From noreply at buildbot.pypy.org Fri Mar 1 01:33:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 01:33:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: our imp.find_module won't raise a SyntaxError like cpython's Message-ID: <20130301003358.2F9551C01A7@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61879:6cc99d28b1ad Date: 2013-02-28 16:33 -0800 http://bitbucket.org/pypy/pypy/changeset/6cc99d28b1ad/ Log: our imp.find_module won't raise a SyntaxError like cpython's diff --git a/lib-python/3.2/test/test_imp.py b/lib-python/3.2/test/test_imp.py --- a/lib-python/3.2/test/test_imp.py +++ b/lib-python/3.2/test/test_imp.py @@ -172,8 +172,15 @@ def test_issue9319(self): path = os.path.dirname(__file__) - self.assertRaises(SyntaxError, - imp.find_module, "badsyntax_pep3120", [path]) + try: + imp.find_module("badsyntax_pep3120", [path]) + except SyntaxError: + pass + else: + # PyPy's find_module won't raise a SyntaxError when checking + # the file's magic encoding comment, the point of the test + # is to ensure no seg fault anyway + self.assertTrue(support.check_impl_detail(cpython=False)) class ReloadTests(unittest.TestCase): From noreply at buildbot.pypy.org Fri Mar 1 02:25:05 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 02:25:05 +0100 (CET) Subject: [pypy-commit] pypy py3k: cpython issue1574217: don't mask non AttributeErrors from __class__ Message-ID: <20130301012505.A67C61C3CE4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61880:0e8ad33bfe4d Date: 2013-02-28 17:22 -0800 http://bitbucket.org/pypy/pypy/changeset/0e8ad33bfe4d/ Log: cpython issue1574217: don't mask non AttributeErrors from __class__ diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -69,8 +69,8 @@ # From now on we know that w_klass_or_tuple is indeed a type. # Try also to compare it with obj.__class__, if this is not # the same as type(obj). + w_pretendtype = abstract_getclass(space, w_obj) try: - w_pretendtype = space.getattr(w_obj, space.wrap('__class__')) if space.is_w(w_pretendtype, space.type(w_obj)): return False # common case: obj.__class__ is type(obj) if allow_override: diff --git a/pypy/module/__builtin__/test/test_abstractinst.py b/pypy/module/__builtin__/test/test_abstractinst.py --- a/pypy/module/__builtin__/test/test_abstractinst.py +++ b/pypy/module/__builtin__/test/test_abstractinst.py @@ -135,6 +135,14 @@ raises(TypeError, isinstance, x, BBase) assert not isinstance(x, BSub2) + class BadClass: + @property + def __class__(self): + raise RuntimeError + raises(RuntimeError, isinstance, BadClass(), bool) + # test another code path + raises(RuntimeError, isinstance, BadClass(), Foo) + def test_abstract_issubclass(self): class MyBaseInst(object): pass From noreply at buildbot.pypy.org Fri Mar 1 02:56:32 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 02:56:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: rework the internal fsencode/decode to use the new 'locale' codec and have Message-ID: <20130301015632.795531C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61881:c4bbf219771f Date: 2013-02-28 17:52 -0800 http://bitbucket.org/pypy/pypy/changeset/c4bbf219771f/ Log: rework the internal fsencode/decode to use the new 'locale' codec and have import use it diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1397,6 +1397,11 @@ """ return w_obj.identifier_w(self) + def fsencode_w(self, w_obj): + if self.isinstance_w(w_obj, self.w_unicode): + w_obj = self.fsencode(w_obj) + return self.bytes0_w(w_obj) + def bool_w(self, w_obj): # Unwraps a bool, also accepting an int for compatibility. # This is here mostly just for gateway.int_unwrapping_space_method(). diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -135,6 +135,9 @@ def visit_str0(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_fsencode(self, el, app_sig): + self.checked_space_method(el, app_sig) + def visit_nonnegint(self, el, app_sig): self.checked_space_method(el, app_sig) @@ -256,6 +259,9 @@ def visit_str0(self, typ): self.run_args.append("space.str0_w(%s)" % (self.scopenext(),)) + def visit_fsencode(self, typ): + self.run_args.append("space.fsencode_w(%s)" % (self.scopenext(),)) + def visit_nonnegint(self, typ): self.run_args.append("space.gateway_nonnegint_w(%s)" % ( self.scopenext(),)) @@ -396,6 +402,9 @@ def visit_str0(self, typ): self.unwrap.append("space.str0_w(%s)" % (self.nextarg(),)) + def visit_fsencode(self, typ): + self.unwrap.append("space.fsencode_w(%s)" % (self.nextarg(),)) + def visit_nonnegint(self, typ): self.unwrap.append("space.gateway_nonnegint_w(%s)" % (self.nextarg(),)) 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 @@ -385,6 +385,17 @@ w_app_g3_idx, space.mul(space.wrap(sys.maxint), space.wrap(-7))) + def test_interp2app_unwrap_spec_fsencode(self): + space = self.space + w = space.wrap + def f(filename): + return space.wrapbytes(filename) + app_f = gateway.interp2app_temp(f, unwrap_spec=['fsencode']) + w_app_f = space.wrap(app_f) + assert space.eq_w( + space.call_function(w_app_f, w(u'\udc80')), + space.wrapbytes('\x80')) + def test_interp2app_unwrap_spec_typechecks(self): space = self.space w = space.wrap diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1,7 +1,15 @@ +import sys from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import specialize from rpython.rlib import runicode from pypy.module._codecs import interp_codecs +_WIN32 = sys.platform == 'win32' +_MACOSX = sys.platform == 'darwin' +if _WIN32: + from rpython.rlib.runicode import str_decode_mbcs, unicode_encode_mbcs +else: + # Workaround translator's confusion + str_decode_mbcs = unicode_encode_mbcs = lambda *args, **kwargs: None @specialize.memo() def decode_error_handler(space): @@ -29,6 +37,60 @@ # ____________________________________________________________ +def PyUnicode_DecodeFSDefault(space, w_string): + state = space.fromcache(interp_codecs.CodecState) + if _WIN32: + bytes = space.bytes_w(w_string) + uni = str_decode_mbcs(bytes, len(bytes), 'strict', + errorhandler=decode_error_handler(space))[0] + elif _MACOSX: + bytes = space.bytes_w(w_string) + uni = runicode.str_decode_utf_8( + bytes, len(bytes), 'surrogateescape', + errorhandler=state.decode_error_handler)[0] + elif state.codec_need_encodings: + # bootstrap check: if the filesystem codec is implemented in + # Python we cannot use it before the codecs are ready. use the + # locale codec instead + from pypy.module._codecs.locale import ( + unicode_decode_locale_surrogateescape) + bytes = space.bytes_w(w_string) + uni = unicode_decode_locale_surrogateescape( + bytes, errorhandler=encode_decode_handler(space)) + else: + from pypy.module.sys.interp_encoding import getfilesystemencoding + return space.call_method(w_string, 'decode', + getfilesystemencoding(space), + space.wrap('surrogateescape')) + return space.wrap(uni) + +def PyUnicode_EncodeFSDefault(space, w_uni): + state = space.fromcache(interp_codecs.CodecState) + if _WIN32: + uni = space.unicode_w(w_uni) + bytes = unicode_encode_mbcs(uni, len(uni), 'strict', + errorhandler=encode_error_handler(space)) + elif _MACOSX: + uni = space.unicode_w(w_uni) + bytes = runicode.unicode_encode_utf_8( + uni, len(uni), 'surrogateescape', + errorhandler=state.encode_error_handler) + elif state.codec_need_encodings: + # bootstrap check: if the filesystem codec is implemented in + # Python we cannot use it before the codecs are ready. use the + # locale codec instead + from pypy.module._codecs.locale import ( + unicode_encode_locale_surrogateescape) + uni = space.unicode_w(w_uni) + bytes = unicode_encode_locale_surrogateescape( + uni, errorhandler=encode_error_handler(space)) + else: + from pypy.module.sys.interp_encoding import getfilesystemencoding + return space.call_method(w_uni, 'encode', + getfilesystemencoding(space), + space.wrap('surrogateescape')) + return space.wrapbytes(bytes) + def PyUnicode_AsEncodedString(space, w_data, w_encoding): return interp_codecs.encode(space, w_data, w_encoding) diff --git a/pypy/module/_posixsubprocess/interp_subprocess.py b/pypy/module/_posixsubprocess/interp_subprocess.py --- a/pypy/module/_posixsubprocess/interp_subprocess.py +++ b/pypy/module/_posixsubprocess/interp_subprocess.py @@ -1,5 +1,5 @@ from rpython.rtyper.lltypesystem import rffi, lltype, llmemory -from pypy.module.posix.interp_posix import fsencode_w, run_fork_hooks +from pypy.module.posix.interp_posix import run_fork_hooks from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.error import ( OperationError, exception_from_errno, wrap_oserror) @@ -115,7 +115,7 @@ l_exec_array = rffi.liststr2charpp(exec_array) if not space.is_none(w_process_args): - argv = [fsencode_w(space, w_item) + argv = [space.fsencode_w(w_item) for w_item in space.listview(w_process_args)] l_argv = rffi.liststr2charpp(argv) @@ -136,7 +136,7 @@ preexec.w_preexec_fn = None if not space.is_none(w_cwd): - cwd = fsencode_w(space, w_cwd) + cwd = space.fsencode_w(w_cwd) l_cwd = rffi.str2charp(cwd) run_fork_hooks('before', space) diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -12,7 +12,6 @@ make_typedescr, get_typedescr) from pypy.module.cpyext.bytesobject import PyBytes_Check, PyBytes_FromObject from pypy.module._codecs.interp_codecs import CodecState -from pypy.module.posix.interp_posix import fsencode, fsdecode from pypy.objspace.std import unicodeobject, unicodetype, stringtype from rpython.rlib import runicode, rstring from rpython.tool.sourcetools import func_renamer @@ -423,7 +422,7 @@ w_output = w_obj else: w_obj = PyUnicode_FromObject(space, w_obj) - w_output = fsencode(space, w_obj) + w_output = space.fsencode(w_obj) if not space.isinstance_w(w_output, space.w_bytes): raise OperationError(space.w_TypeError, space.wrap("encoder failed to return bytes")) @@ -447,7 +446,7 @@ w_output = w_obj else: w_obj = PyBytes_FromObject(space, w_obj) - w_output = fsdecode(space, w_obj) + w_output = space.fsdecode(w_obj) if not space.isinstance_w(w_output, space.w_unicode): raise OperationError(space.w_TypeError, space.wrap("decoder failed to return unicode")) @@ -466,7 +465,7 @@ Use 'strict' error handler on Windows.""" w_bytes = space.wrapbytes(rffi.charpsize2str(s, size)) - return fsdecode(space, w_bytes) + return space.fsdecode(w_bytes) @cpython_api([rffi.CCHARP], PyObject) @@ -481,7 +480,7 @@ Use 'strict' error handler on Windows.""" w_bytes = space.wrapbytes(rffi.charp2str(s)) - return fsdecode(space, w_bytes) + return space.fsdecode(w_bytes) @cpython_api([PyObject], PyObject) @@ -494,7 +493,7 @@ If Py_FileSystemDefaultEncoding is not set, fall back to the locale encoding. """ - return fsencode(space, w_unicode) + return space.fsencode(w_unicode) @cpython_api([CONST_STRING], PyObject) 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 @@ -421,7 +421,7 @@ def __init__(self, space): pass - @unwrap_spec(path='str0') + @unwrap_spec(path='fsencode') def descr_init(self, space, path): if not path: raise OperationError(space.w_ImportError, space.wrap( diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -57,7 +57,7 @@ return streamio.fdopen_as_stream(fd, filemode) def find_module(space, w_name, w_path=None): - name = space.str0_w(w_name) + name = space.fsencode_w(w_name) if space.is_none(w_path): w_path = None @@ -68,7 +68,7 @@ space.w_ImportError, "No module named %s", name) - w_filename = space.wrap(find_info.filename) + w_filename = space.fsdecode(space.wrapbytes(find_info.filename)) stream = find_info.stream if stream is not None: @@ -107,7 +107,7 @@ def load_module(space, w_name, w_file, w_filename, w_info): w_suffix, w_filemode, w_modtype = space.unpackiterable(w_info) - filename = space.str0_w(w_filename) + filename = space.fsencode_w(w_filename) filemode = space.str_w(w_filemode) if space.is_w(w_file, space.w_None): stream = None @@ -124,7 +124,7 @@ space, w_name, find_info, reuse=True) def load_source(space, w_modulename, w_filename, w_file=None): - filename = space.str0_w(w_filename) + filename = space.fsencode_w(w_filename) stream = get_file(space, w_file, filename, 'U') @@ -138,7 +138,7 @@ stream.close() return w_mod - at unwrap_spec(filename='str0', write_paths=bool) + at unwrap_spec(filename='fsencode', write_paths=bool) def _run_compiled_module(space, w_modulename, filename, w_file, w_module, write_paths=True): # the function 'imp._run_compiled_module' is a pypy-only extension @@ -153,14 +153,14 @@ if space.is_none(w_file): stream.close() - at unwrap_spec(filename='str0') + at unwrap_spec(filename='fsencode') def load_compiled(space, w_modulename, filename, w_file=None): w_mod = space.wrap(Module(space, w_modulename)) importing._prepare_module(space, w_mod, filename, None) _run_compiled_module(space, w_modulename, filename, w_file, w_mod) return w_mod - at unwrap_spec(filename=str) + at unwrap_spec(filename='fsencode') def load_dynamic(space, w_modulename, filename, w_file=None): if not space.config.objspace.usemodules.cpyext: raise OperationError(space.w_ImportError, space.wrap( @@ -215,7 +215,7 @@ if space.config.objspace.usemodules.thread: importing.getimportlock(space).reinit_lock() - at unwrap_spec(pathname='str0') + at unwrap_spec(pathname='fsencode') def cache_from_source(space, pathname, w_debug_override=None): """cache_from_source(path, [debug_override]) -> path Given the path to a .py file, return the path to its .pyc/.pyo file. @@ -226,9 +226,10 @@ If debug_override is not None, then it must be a boolean and is taken as the value of __debug__ instead.""" - return space.wrap(importing.make_compiled_pathname(pathname)) + return space.fsdecode(space.wrapbytes( + importing.make_compiled_pathname(pathname))) - at unwrap_spec(pathname='str0') + at unwrap_spec(pathname='fsencode') def source_from_cache(space, pathname): """source_from_cache(path) -> path Given the path to a .pyc./.pyo file, return the path to its .py file. @@ -240,4 +241,4 @@ if sourcename is None: raise operationerrfmt(space.w_ValueError, "Not a PEP 3147 pyc path: %s", pathname) - return space.wrap(sourcename) + return space.fsdecode(space.wrapbytes(sourcename)) diff --git a/pypy/module/imp/test/__init__.py b/pypy/module/imp/test/__init__.py new file mode 100644 diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -1,8 +1,10 @@ +# coding: utf-8 import py from pypy.interpreter.module import Module from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.interpreter.pycode import PyCode +from pypy.module.imp.test.support import BaseImportTest from rpython.tool.udir import udir from rpython.rlib import streamio from pypy.tool.option import make_config @@ -31,7 +33,8 @@ f.close() return p -def setup_directory_structure(space): +def setup_directory_structure(cls): + space = cls.space root = setuppkg("", a = "imamodule = 1\ninpackage = 0", ambig = "imamodule = 1", @@ -90,11 +93,40 @@ 'a=5\nb=6\rc="""hello\r\nworld"""\r', mode='wb') p.join('mod.py').write( 'a=15\nb=16\rc="""foo\r\nbar"""\r', mode='wb') - setuppkg("encoded", + p = setuppkg("encoded", # actually a line 2, setuppkg() sets up a line1 line2 = "# encoding: iso-8859-1\n", bad = "# encoding: uft-8\n") + fsenc = sys.getfilesystemencoding() + # covers utf-8 and Windows ANSI code pages one non-space symbol from + # every page (http://en.wikipedia.org/wiki/Code_page) + known_locales = { + 'utf-8' : b'\xc3\xa4', + 'cp1250' : b'\x8C', + 'cp1251' : b'\xc0', + 'cp1252' : b'\xc0', + 'cp1253' : b'\xc1', + 'cp1254' : b'\xc0', + 'cp1255' : b'\xe0', + 'cp1256' : b'\xe0', + 'cp1257' : b'\xc0', + 'cp1258' : b'\xc0', + } + + if sys.platform == 'darwin': + # Mac OS X uses the Normal Form D decomposition + # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html + special_char = b'a\xcc\x88' + else: + special_char = known_locales.get(fsenc) + + if special_char: + p.join(special_char + '.py').write('pass') + cls.w_special_char = space.wrap(special_char.decode(fsenc)) + else: + cls.w_special_char = space.w_None + # create compiled/x.py and a corresponding pyc file p = setuppkg("compiled", x = "x = 84") if conftest.option.runappdirect: @@ -132,8 +164,9 @@ return str(root) -def _setup(space): - dn = setup_directory_structure(space) +def _setup(cls): + space = cls.space + dn = setup_directory_structure(cls) return space.appexec([space.wrap(dn)], """ (dn): import sys @@ -153,14 +186,15 @@ """) -class AppTestImport: +class AppTestImport(BaseImportTest): spaceconfig = { "usemodules": ['rctime'], } def setup_class(cls): + BaseImportTest.setup_class.im_func(cls) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) - cls.w_saved_modules = _setup(cls.space) + cls.w_saved_modules = _setup(cls) #XXX Compile class def teardown_class(cls): @@ -681,6 +715,30 @@ import encoded raises(SyntaxError, imp.find_module, 'bad', encoded.__path__) + def test_find_module_fsdecode(self): + import sys + name = self.special_char + if not name: + skip("can't run this test with %s as filesystem encoding" + % sys.getfilesystemencoding()) + import imp + import encoded + f, filename, _ = imp.find_module(name, encoded.__path__) + assert f is not None + assert filename[:-3].endswith(name) + + def test_unencodable(self): + if not self.testfn_unencodable: + skip("need an unencodable filename") + import imp + import os + name = self.testfn_unencodable + os.mkdir(name) + try: + raises(ImportError, imp.NullImporter, name) + finally: + os.rmdir(name) + class TestAbi: def test_abi_tag(self): @@ -1316,7 +1374,7 @@ def setup_class(cls): usepycfiles = cls.spaceconfig['objspace.usepycfiles'] cls.w_usepycfiles = cls.space.wrap(usepycfiles) - cls.saved_modules = _setup(cls.space) + cls.saved_modules = _setup(cls) def teardown_class(cls): _teardown(cls.space, cls.saved_modules) diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -10,7 +10,6 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rtyper.tool import rffi_platform from rpython.translator.tool.cbuild import ExternalCompilationInfo -from pypy.module.sys.interp_encoding import getfilesystemencoding import os, sys @@ -36,30 +35,13 @@ raise OperationError(space.w_OverflowError, space.wrap("integer out of range")) -def fsencode_w(space, w_obj): - if space.isinstance_w(w_obj, space.w_unicode): - w_obj = fsencode(space, w_obj) - return space.bytes0_w(w_obj) - -def fsencode(space, w_obj): - w_bytes = space.call_method(w_obj, 'encode', - getfilesystemencoding(space), - space.wrap('surrogateescape')) - return w_bytes - -def fsdecode(space, w_obj): - w_unicode = space.call_method(w_obj, 'decode', - getfilesystemencoding(space), - space.wrap('surrogateescape')) - return w_unicode - class FileEncoder(object): def __init__(self, space, w_obj): self.space = space self.w_obj = w_obj def as_bytes(self): - return fsencode_w(self.space, self.w_obj) + return self.space.fsencode_w(self.w_obj) def as_unicode(self): return self.space.unicode0_w(self.w_obj) @@ -74,7 +56,7 @@ def as_unicode(self): space = self.space - w_unicode = fsdecode(space, self.w_obj) + w_unicode = space.fsdecode(self.w_obj) return space.unicode0_w(w_unicode) @specialize.memo() @@ -443,7 +425,7 @@ else: def getcwd(space): """Return the current working directory as a string.""" - return fsdecode(space, getcwdb(space)) + return space.fsdecode(getcwdb(space)) def chdir(space, w_path): """Change the current working directory to the specified path.""" @@ -557,7 +539,7 @@ result_w = [None] * len_result for i in range(len_result): w_bytes = space.wrapbytes(result[i]) - result_w[i] = fsdecode(space, w_bytes) + result_w[i] = space.fsdecode(w_bytes) else: dirname = space.str0_w(w_dirname) result = rposix.listdir(dirname) @@ -783,13 +765,13 @@ args: iterable of arguments env: dictionary of strings mapping to strings """ - command = fsencode_w(space, w_command) + command = space.fsencode_w(w_command) try: args_w = space.unpackiterable(w_args) if len(args_w) < 1: w_msg = space.wrap("execv() must have at least one argument") raise OperationError(space.w_ValueError, w_msg) - args = [fsencode_w(space, w_arg) for w_arg in args_w] + args = [space.fsencode_w(w_arg) for w_arg in args_w] except OperationError, e: if not e.match(space, space.w_TypeError): raise diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -351,7 +351,7 @@ space = self.space return space.wrap(self.filename) - at unwrap_spec(name='str0') + at unwrap_spec(name='fsencode') def descr_new_zipimporter(space, w_type, name): ok = False parts_ends = [i for i in range(0, len(name)) diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -2,13 +2,14 @@ import time import struct from pypy.module.imp.importing import get_pyc_magic, _w_long +from pypy.module.imp.test.support import BaseImportTest from StringIO import StringIO from rpython.tool.udir import udir from zipfile import ZIP_STORED, ZIP_DEFLATED -class AppTestZipimport: +class AppTestZipimport(BaseImportTest): """ A bit structurized tests stolen and adapted from cpy's regression tests """ @@ -40,6 +41,7 @@ @classmethod def make_class(cls): + BaseImportTest.setup_class.im_func(cls) source = """\ def get_name(): return __name__ @@ -358,6 +360,24 @@ co_filename = code.co_filename assert co_filename == expected + def test_unencodable(self): + if not self.testfn_unencodable: + skip("need an unencodable filename") + import os + import time + import zipimport + from zipfile import ZipFile, ZipInfo + filename = self.testfn_unencodable + ".zip" + z = ZipFile(filename, "w") + zinfo = ZipInfo("uu.py", time.localtime(self.now)) + zinfo.compress_type = self.compression + z.writestr(zinfo, '') + z.close() + try: + zipimport.zipimporter(filename) + finally: + os.remove(filename) + class AppTestZipimportDeflated(AppTestZipimport): compression = ZIP_DEFLATED diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -497,6 +497,14 @@ "'%s' does not support the buffer interface", typename) return space.get_and_call_function(w_impl, w_obj) + def fsencode(space, w_obj): + from pypy.interpreter.unicodehelper import PyUnicode_EncodeFSDefault + return PyUnicode_EncodeFSDefault(space, w_obj) + + def fsdecode(space, w_obj): + from pypy.interpreter.unicodehelper import PyUnicode_DecodeFSDefault + return PyUnicode_DecodeFSDefault(space, w_obj) + # helpers From noreply at buildbot.pypy.org Fri Mar 1 03:04:10 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 03:04:10 +0100 (CET) Subject: [pypy-commit] pypy py3k: fsdecode sys.executable/argv Message-ID: <20130301020410.96D101C07C6@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61882:84683ee69770 Date: 2013-02-28 17:59 -0800 http://bitbucket.org/pypy/pypy/changeset/84683ee69770/ Log: fsdecode sys.executable/argv diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -49,8 +49,9 @@ try: try: space.call_function(w_run_toplevel, w_call_startup_gateway) - w_executable = space.wrap(argv[0]) - w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) + w_executable = space.fsdecode(space.wrapbytes(argv[0])) + w_argv = space.newlist([space.fsdecode(space.wrapbytes(s)) + for s in argv[1:]]) w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) exitcode = space.int_w(w_exitcode) # try to pull it all in From noreply at buildbot.pypy.org Fri Mar 1 06:20:08 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 06:20:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: imp.load_package is undocumented, deprecated in 3.3 and doesn't seem widely Message-ID: <20130301052008.58FC61C01A7@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61883:cff8ed68eb95 Date: 2013-02-28 21:19 -0800 http://bitbucket.org/pypy/pypy/changeset/cff8ed68eb95/ Log: imp.load_package is undocumented, deprecated in 3.3 and doesn't seem widely used anyway diff --git a/lib-python/3.2/test/test_imp.py b/lib-python/3.2/test/test_imp.py --- a/lib-python/3.2/test/test_imp.py +++ b/lib-python/3.2/test/test_imp.py @@ -161,8 +161,9 @@ os.mkdir(test_package_name) with open(init_file_name, 'w') as file: file.write('b = 2\n') - package = imp.load_package(test_package_name, test_package_name) - self.assertEqual(package.b, 2) + if support.check_impl_detail(cpython=True): + package = imp.load_package(test_package_name, test_package_name) + self.assertEqual(package.b, 2) finally: del sys.path[0] for ext in ('.py', '.pyc', '.pyo'): From noreply at buildbot.pypy.org Fri Mar 1 06:38:06 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 06:38:06 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix Message-ID: <20130301053806.6009E1C01A7@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61884:5f0519858fdc Date: 2013-02-28 21:37 -0800 http://bitbucket.org/pypy/pypy/changeset/5f0519858fdc/ Log: fix diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -56,7 +56,7 @@ unicode_decode_locale_surrogateescape) bytes = space.bytes_w(w_string) uni = unicode_decode_locale_surrogateescape( - bytes, errorhandler=encode_decode_handler(space)) + bytes, errorhandler=decode_error_handler(space)) else: from pypy.module.sys.interp_encoding import getfilesystemencoding return space.call_method(w_string, 'decode', From noreply at buildbot.pypy.org Fri Mar 1 09:05:31 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 09:05:31 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix translation Message-ID: <20130301080531.1EA701C3C84@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61885:6f29a9528d54 Date: 2013-03-01 00:04 -0800 http://bitbucket.org/pypy/pypy/changeset/6f29a9528d54/ Log: fix translation diff --git a/pypy/module/_codecs/locale.py b/pypy/module/_codecs/locale.py --- a/pypy/module/_codecs/locale.py +++ b/pypy/module/_codecs/locale.py @@ -113,14 +113,14 @@ def unicode2rawwcharp(u): """unicode -> raw wchar_t*""" - size = _unicode2cwcharp_loop(u, None) if MERGE_SURROGATES else len(u) + size = _unicode2rawwcharp_loop(u, None) if MERGE_SURROGATES else len(u) array = lltype.malloc(RAW_WCHARP.TO, size + 1, flavor='raw') array[size] = rffi.cast(rffi.WCHAR_T, u'\x00') - _unicode2cwcharp_loop(u, array) + _unicode2rawwcharp_loop(u, array) return array unicode2rawwcharp._annenforceargs_ = [unicode] -def _unicode2cwcharp_loop(u, array): +def _unicode2rawwcharp_loop(u, array): write = array is not None ulen = len(u) count = i = 0 @@ -140,7 +140,7 @@ i += 1 count += 1 return count -unicode2rawwcharp._annenforceargs_ = [unicode, None] +_unicode2rawwcharp_loop._annenforceargs_ = [unicode, None] def rawwcharp2unicoden(wcp, maxlen): @@ -150,4 +150,4 @@ b.append(code_to_unichr(wcp[i])) i += 1 return assert_str0(b.build()) -unicode2rawwcharp._annenforceargs_ = [None, int] +rawwcharp2unicoden._annenforceargs_ = [None, int] From noreply at buildbot.pypy.org Fri Mar 1 09:34:54 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 09:34:54 +0100 (CET) Subject: [pypy-commit] pypy py3k: translation fix Message-ID: <20130301083454.14ACA1C01A7@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61886:b6955ddd076c Date: 2013-03-01 00:33 -0800 http://bitbucket.org/pypy/pypy/changeset/b6955ddd076c/ Log: translation fix diff --git a/pypy/module/_codecs/locale.py b/pypy/module/_codecs/locale.py --- a/pypy/module/_codecs/locale.py +++ b/pypy/module/_codecs/locale.py @@ -146,7 +146,7 @@ def rawwcharp2unicoden(wcp, maxlen): b = UnicodeBuilder(maxlen) i = 0 - while i < maxlen and wcp[i] != u'\x00': + while i < maxlen and wcp[i] != 0: b.append(code_to_unichr(wcp[i])) i += 1 return assert_str0(b.build()) From noreply at buildbot.pypy.org Fri Mar 1 15:05:02 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Mar 2013 15:05:02 +0100 (CET) Subject: [pypy-commit] pypy gc-del: A branch in which the __del__() are called after only one major collection Message-ID: <20130301140502.83EC61C11FD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r61887:84efc0ef06d8 Date: 2013-03-01 12:02 +0100 http://bitbucket.org/pypy/pypy/changeset/84efc0ef06d8/ Log: A branch in which the __del__() are called after only one major collection even if they are objects with references to each other. See discussion on python-dev:: http://mail.python.org/pipermail/python- dev/2013-February/124044.html From noreply at buildbot.pypy.org Fri Mar 1 15:05:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Mar 2013 15:05:03 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Kill confusing comment. Adapt the title. Message-ID: <20130301140503.BA3C41C3C84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r61888:bd62f18fc79d Date: 2013-03-01 14:28 +0100 http://bitbucket.org/pypy/pypy/changeset/bd62f18fc79d/ Log: Kill confusing comment. Adapt the title. diff --git a/pypy/doc/discussion/finalizer-order.rst b/pypy/doc/discussion/finalizer-order.rst --- a/pypy/doc/discussion/finalizer-order.rst +++ b/pypy/doc/discussion/finalizer-order.rst @@ -1,8 +1,5 @@ -.. XXX armin, what do we do with this? - - -Ordering finalizers in the SemiSpace GC -======================================= +Ordering finalizers in the SemiSpace/Hybrid/Minimark GC +======================================================= Goal ---- From noreply at buildbot.pypy.org Fri Mar 1 15:05:05 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Mar 2013 15:05:05 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Document a possible memory leak. Message-ID: <20130301140505.0F5E91C11FD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r61889:103e6ebbc9c2 Date: 2013-03-01 15:04 +0100 http://bitbucket.org/pypy/pypy/changeset/103e6ebbc9c2/ Log: Document a possible memory leak. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -226,6 +226,8 @@ # note that we don't call clear_all_weakrefs here because # an array with freed buffer is ok to see - it's just empty with 0 # length + # XXX wrong, because we can then increase its length again, + # XXX which creates a memory leak self.setlen(0) def setlen(self, size, zero=False, overallocate=True): From noreply at buildbot.pypy.org Fri Mar 1 17:29:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Mar 2013 17:29:58 +0100 (CET) Subject: [pypy-commit] pypy default: Test and fix for checkmodule() failing to follow all possible paths. Message-ID: <20130301162958.4BACB1C0084@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61890:e61ccf099ed1 Date: 2013-03-01 17:29 +0100 http://bitbucket.org/pypy/pypy/changeset/e61ccf099ed1/ Log: Test and fix for checkmodule() failing to follow all possible paths. diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -286,8 +286,10 @@ #print self._seen_extras ann.build_types(self._seen_extras[done], [], complete_now=False) + ann.complete_pending_blocks() done += 1 ann.complete() + assert done == len(self._seen_extras) #t.viewcg() t.buildrtyper().specialize() t.checkgraphs() diff --git a/pypy/objspace/fake/test/test_checkmodule.py b/pypy/objspace/fake/test/test_checkmodule.py --- a/pypy/objspace/fake/test/test_checkmodule.py +++ b/pypy/objspace/fake/test/test_checkmodule.py @@ -3,6 +3,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, W_Root, ObjSpace +from rpython.rlib.objectmodel import specialize from rpython.rtyper.test.test_llinterp import interpret def make_checker(): @@ -34,6 +35,22 @@ space.translates() assert check +def test_wrap_interp2app_later(): + see, check = make_checker() + # + @specialize.memo() + def hithere(space): + space.wrap(interp2app(foobar2)) + # + def foobar(space): + hithere(space) + def foobar2(space): + see() + space = FakeObjSpace() + space.wrap(interp2app(foobar)) + space.translates() + assert check + def test_wrap_GetSetProperty(): see, check = make_checker() def foobar(w_obj, space): diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -192,8 +192,7 @@ if not self.annotated[block]: self.pendingblocks[block] = graph - def complete(self): - """Process pending blocks until none is left.""" + def complete_pending_blocks(self): while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() @@ -201,6 +200,10 @@ self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: break # finished + + def complete(self): + """Process pending blocks until none is left.""" + self.complete_pending_blocks() # make sure that the return variables of all graphs is annotated if self.added_blocks is not None: newgraphs = [self.annotated[block] for block in self.added_blocks] From noreply at buildbot.pypy.org Fri Mar 1 17:58:29 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 1 Mar 2013 17:58:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: refactored marking a context as returned from Message-ID: <20130301165829.02E0D1C00E4@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r111:f722db172868 Date: 2013-03-01 17:49 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/f722db172868/ Log: refactored marking a context as returned from diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -90,8 +90,6 @@ w_new_context = self.step(s_active_context) if w_new_context is not None: s_active_context = w_new_context.as_context_get_shadow(self.space) - #method = s_active_context.w_method() - #print method.get_identifier_string() def perform(self, w_receiver, selector, *arguments_w): if isinstance(selector, str): @@ -250,7 +248,6 @@ print "%sSending selector %r to %r with: %r" % ( interp._last_indent, w_selector.as_string(), receiver, [self.peek(argcount-1-i) for i in range(argcount)]) - pass assert argcount >= 0 s_method = receiverclassshadow.lookup(w_selector) # XXX catch MethodNotFound here and send doesNotUnderstand: @@ -285,12 +282,11 @@ def _return(self, object, interp, w_return_to): # for tests, when returning from the top-level context if w_return_to.is_same_object(self.space.w_nil): - raise ReturnFromTopLevel(object) - # widow this context - self.store_pc(-1) - self.store_w_sender(self.space.w_nil) + raise ReturnFromTopLevel(return_value) + # make this context a returned one + self.mark_returned() - w_return_to.as_context_get_shadow(self.space).push(object) + w_return_to.as_context_get_shadow(self.space).push(return_value) return w_return_to def returnReceiver(self, interp, current_bytecode): diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -432,6 +432,13 @@ def stackpointer_offset(self): raise NotImplementedError() + def mark_returned(self): + self.store_pc(-1) + self.store_w_sender(self.space.w_nil) + + def is_returned(self): + return self.pc() == -1 and self.w_sender is self.space.w_nil + # ______________________________________________________________________ # Method that contains the bytecode for this method/block context From noreply at buildbot.pypy.org Fri Mar 1 17:58:30 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 1 Mar 2013 17:58:30 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: refactored the interpreter to use the c stack when building contexts Message-ID: <20130301165830.256961C00E4@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r112:785411941697 Date: 2013-03-01 17:52 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/785411941697/ Log: refactored the interpreter to use the c stack when building contexts there is (at least one) problem with the jit generation. Unfortunately, the error message is too cryptic and websearch does not help diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -26,16 +26,19 @@ _w_last_active_context = None cnt = 0 _last_indent = "" + _loop = True jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], reds=['s_active_context'], get_printable_location=get_printable_location ) - def __init__(self, space, image=None, image_name=""): + def __init__(self, space, image=None, image_name="", max_stack_depth=500): self.space = space self.image = image self.image_name = image_name + self.max_stack_depth = max_stack_depth + self._loop = False def interpret_with_w_frame(self, w_frame): try: @@ -79,6 +82,7 @@ return bytecodeimpl(s_active_context, self, next) def loop(self, w_active_context): + self._loop = True s_active_context = w_active_context.as_context_get_shadow(self.space) while True: pc = s_active_context._pc @@ -87,8 +91,12 @@ self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, s_active_context=s_active_context) - w_new_context = self.step(s_active_context) + try: + w_new_context = self.step(s_active_context) + except StackOverflow, e: + w_new_context = e.w_context if w_new_context is not None: + # we return to the context mentioned -> mark all contexts in between as mark_returned s_active_context = w_new_context.as_context_get_shadow(self.space) def perform(self, w_receiver, selector, *arguments_w): @@ -117,11 +125,49 @@ except ReturnFromTopLevel, e: return e.object + def stack_frame(self, w_new_frame): + if not self._loop: + return w_new_frame # this test is done to not loop in test, + # but rather step just once where wanted + if self.max_stack_depth == 1: + raise StackOverflow(w_new_frame) + #method = s_active_context.w_method() + #print method.get_identifier_string() + interp = StackedInterpreter(self.space, self.image, self.image_name, + self.max_stack_depth - 1) + return interp.loop(w_new_frame) + +class StackedInterpreter(Interpreter): + def __init__(self, space, image, image_name, max_stack_depth): + self.space = space + self.image = image + self.image_name = image_name + self.max_stack_depth = max_stack_depth + + def loop(self, w_active_context): + s_active_context = w_active_context.as_context_get_shadow(self.space) + while True: + pc = s_active_context._pc + method = s_active_context.method() + + self.jit_driver.jit_merge_point( + pc=pc, self=self, method=method, + s_active_context=s_active_context) + w_return_to_context = self.step(s_active_context) + if (w_return_to_context is not None + and w_return_to_context is not w_active_context): + assert w_return_to_context._shadow._w_sender is not w_active_context + w_active_context.as_context_get_shadow(self.space).mark_returned() + return w_return_to_context class ReturnFromTopLevel(Exception): def __init__(self, object): self.object = object +class StackOverflow(Exception): + def __init__(self, w_top_context): + self.w_context = w_top_context + def make_call_primitive_bytecode(primitive, selector, argcount): def callPrimitive(self, interp, current_bytecode): # WARNING: this is used for bytecodes for which it is safe to @@ -277,9 +323,9 @@ w_frame = s_method.create_frame(self.space, receiver, arguments, self.w_self()) self.pop() - return w_frame + return interp.stack_frame(w_frame) - def _return(self, object, interp, w_return_to): + def _return(self, return_value, interp, w_return_to): # for tests, when returning from the top-level context if w_return_to.is_same_object(self.space.w_nil): raise ReturnFromTopLevel(return_value) diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -67,7 +67,7 @@ def wrapped(interp, s_frame, argument_count_m1): w_result = func(interp, s_frame, argument_count_m1) if result_is_new_frame: - return w_result + return interp.stack_frame(w_result) if not no_result: assert w_result is not None s_frame.push(w_result) @@ -110,7 +110,7 @@ # needs to be updated s_frame.pop_n(len_unwrap_spec) # only if no exception occurs! if result_is_new_frame: - return w_result + return interp.stack_frame(w_result) elif not no_result: assert w_result is not None s_frame.push(w_result) diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -50,7 +50,7 @@ # we can't find PCSystem, because Smalltalkdict is nil... import time t0 = time.time() - sends = perform(w(20), 'benchFib') + sends = perform(w(5), 'benchFib') t1 = time.time() t = t1 - t0 print str(tools.space.unwrap_int(sends)/t) + " sends per second" \ No newline at end of file diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -6,6 +6,9 @@ space = objspace.ObjSpace() interp = interpreter.Interpreter(space) +def step_in_interp(ctxt): # due to missing resets in between tests + interp._loop = False + return interp.step(ctxt) # expose the bytecode's values as global constants. # Bytecodes that have a whole range are exposed as global functions: @@ -122,12 +125,12 @@ def test_unknownBytecode(): w_frame, s_frame = new_frame(unknownBytecode) - py.test.raises(interpreter.MissingBytecode, interp.step, s_frame) + py.test.raises(interpreter.MissingBytecode, step_in_interp, s_frame) # push bytecodes def test_pushReceiverBytecode(): w_frame, s_frame = new_frame(pushReceiverBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.top().is_same_object( s_frame.w_receiver()) @@ -140,9 +143,9 @@ w_demo.store(space, 2, "baz") w_frame, s_frame = new_frame(bytecode, receiver = w_demo) s_frame = w_frame.as_context_get_shadow(space) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == ["egg", "bar", "baz"] def test_pushTemporaryVariableBytecode(bytecode=(pushTemporaryVariableBytecode(0) + @@ -151,9 +154,9 @@ w_frame, s_frame = new_frame(bytecode) s_frame = w_frame.as_context_get_shadow(space) s_frame.settemp(2, "temp") - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == ["foo", "bar", "temp"] def test_pushLiteralConstantBytecode(bytecode=pushLiteralConstantBytecode(0) + @@ -161,9 +164,9 @@ pushLiteralConstantBytecode(2)): w_frame, s_frame = new_frame(bytecode) s_frame.w_method().setliterals(fakeliterals(space, "a", "b", "c")) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == [fakesymbol("a"), fakesymbol("b"), fakesymbol("c")] @@ -174,7 +177,7 @@ w_association.store(space, 1, "myvalue") w_frame, s_frame = new_frame(bytecode) s_frame.w_method().setliterals( fakeliterals(space, w_association)) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == ["myvalue"] def test_storeAndPopReceiverVariableBytecode(bytecode=storeAndPopReceiverVariableBytecode, @@ -184,8 +187,8 @@ w_object = shadow.new() w_frame, s_frame = new_frame(pushConstantTrueBytecode + bytecode(index)) s_frame.store_w_receiver(w_object) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) if popped: assert s_frame.stack() == [] else: @@ -201,8 +204,8 @@ for index in range(8): w_frame, s_frame = new_frame(pushConstantTrueBytecode + bytecode(index)) #s_frame.temps = [None] * 8 - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == [] for test_index in range(8): print w_frame._vars @@ -213,141 +216,141 @@ def test_pushConstantTrueBytecode(): w_frame, s_frame = new_frame(pushConstantTrueBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_true) assert s_frame.stack() == [] def test_pushConstantFalseBytecode(): w_frame, s_frame = new_frame(pushConstantFalseBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_false) assert s_frame.stack() == [] def test_pushConstantNilBytecode(): w_frame, s_frame = new_frame(pushConstantNilBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_nil) assert s_frame.stack() == [] def test_pushConstantMinusOneBytecode(): w_frame, s_frame = new_frame(pushConstantMinusOneBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_minus_one) assert s_frame.stack() == [] def test_pushConstantZeroBytecode(): w_frame, s_frame = new_frame(pushConstantZeroBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_zero) assert s_frame.stack() == [] def test_pushConstantOneBytecode(): w_frame, s_frame = new_frame(pushConstantOneBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_one) assert s_frame.stack() == [] def test_pushConstantTwoBytecode(): w_frame, s_frame = new_frame(pushConstantTwoBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop().is_same_object(space.w_two) assert s_frame.stack() == [] def test_pushActiveContextBytecode(): w_frame, s_frame = new_frame(pushActiveContextBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pop() == w_frame assert s_frame.stack() == [] def test_duplicateTopBytecode(): w_frame, s_frame = new_frame(pushConstantZeroBytecode + duplicateTopBytecode) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == [space.w_zero, space.w_zero] def test_bytecodePrimBitAnd(): w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitAnd) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == 0 assert s_frame.stack() == [] def test_bytecodePrimBitOr(): w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitOr) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == 3 assert s_frame.stack() == [] def test_bytecodePrimBitShift(): w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitShift) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == 4 assert s_frame.stack() == [] def test_bytecodePrimClass(): w_frame, s_frame = new_frame(pushConstantOneBytecode + bytecodePrimClass) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop() == space.w_SmallInteger assert s_frame.stack() == [] def test_bytecodePrimSubtract(): w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimSubtract) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == -1 assert s_frame.stack() == [] def test_bytecodePrimMultiply(): w_frame, s_frame = new_frame(pushConstantMinusOneBytecode + pushConstantTwoBytecode + bytecodePrimMultiply) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == -2 assert s_frame.stack() == [] def test_bytecodePrimDivide(): w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDivide) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == -2 assert s_frame.stack() == [] def test_bytecodePrimDiv(): w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDiv) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == -2 assert s_frame.stack() == [] def test_bytecodePrimMod(): w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimMod) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop().value == 0 assert s_frame.stack() == [] def test_bytecodePrimEquivalent(): w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimEquivalent) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop() == space.w_false assert s_frame.stack() == [] w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantOneBytecode + bytecodePrimEquivalent) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert s_frame.pop() == space.w_true assert s_frame.stack() == [] @@ -359,7 +362,7 @@ s_frame.push(w_fakeclass) run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW, 0, "new"]], - interp.step, + step_in_interp, s_frame) w_fakeinst = s_frame.pop() assert s_frame.stack() == [] @@ -375,7 +378,7 @@ s_frame.push(space.w_two) run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]], - interp.step, + step_in_interp, s_frame) w_fakeinst = s_frame.pop() assert s_frame.stack() == [] @@ -389,7 +392,7 @@ s_frame.push(w_fakeinst) run_with_faked_primitive_methods( [[w_fakeclass, primitives.SIZE, 0, "size"]], - interp.step, + step_in_interp, s_frame) assert s_frame.pop().value == 5 assert s_frame.stack() == [] @@ -413,15 +416,15 @@ w_frame, s_frame = new_frame(bytecodes) s_frame.w_method().setliterals(literals) s_frame.push(w_object) - w_active_context = interp.step(s_frame) + w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) assert s_active_context.w_sender() == w_frame assert s_active_context.stack() == [] assert w_active_context.as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) assert s_frame.stack() == [] - interp.step(s_active_context) - w_active_context = interp.step(s_active_context) + step_in_interp(s_active_context) + w_active_context = step_in_interp(s_active_context) s_active_context = w_active_context.as_context_get_shadow(space) assert w_active_context == w_frame assert s_active_context.stack() == [result] @@ -457,7 +460,7 @@ s_frame.w_method().setliterals(fakeliterals(space, "foo", "-")) s_frame.push(space.wrap_int(50)) s_frame.push(space.wrap_int(8)) - w_new_frame = interp.step(s_frame) + w_new_frame = step_in_interp(s_frame) assert w_new_frame is None assert len(s_frame.stack()) == 1 w_result = s_frame.pop() @@ -472,9 +475,9 @@ w_frame, s_frame = new_frame(pushConstantZeroBytecode + pushConstantOneBytecode + bytecodePrimMakePoint) - interp.step(s_frame) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) w_point = s_frame.top() from spyvm.wrapper import PointWrapper point = PointWrapper(interp.space, w_point) @@ -485,55 +488,55 @@ w_frame, s_frame = new_frame(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15)) s_frame.push(space.w_false) pc = s_frame.pc() + 2 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc s_frame.push(space.w_true) pc = s_frame.pc() + 2 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 15 def test_longJumpIfFalse(): w_frame, s_frame = new_frame(pushConstantTrueBytecode + longJumpIfFalse(0) + chr(15) + pushConstantFalseBytecode + longJumpIfFalse(0) + chr(15)) - interp.step(s_frame) + step_in_interp(s_frame) pc = s_frame.pc() + 2 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc - interp.step(s_frame) + step_in_interp(s_frame) pc = s_frame.pc() + 2 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 15 def test_longUnconditionalJump(): w_frame, s_frame = new_frame(longUnconditionalJump(4) + chr(15)) pc = s_frame.pc() + 2 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 15 def test_shortUnconditionalJump(): w_frame, s_frame = new_frame(chr(145)) pc = s_frame.pc() + 1 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 2 def test_shortConditionalJump(): w_frame, s_frame = new_frame(pushConstantTrueBytecode + shortConditionalJump(3) + pushConstantFalseBytecode + shortConditionalJump(3)) - interp.step(s_frame) + step_in_interp(s_frame) pc = s_frame.pc() + 1 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc - interp.step(s_frame) + step_in_interp(s_frame) pc = s_frame.pc() + 1 - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 4 def test_popStackBytecode(): w_frame, s_frame = new_frame(pushConstantTrueBytecode + popStackBytecode) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == [space.w_true] - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == [] def test_extendedPushBytecode(): @@ -557,8 +560,8 @@ w_association.store(space, 1, "myvalue") w_frame, s_frame = new_frame(pushConstantOneBytecode + bytecode) s_frame.w_method().setliterals(fakeliterals(space, w_association)) - interp.step(s_frame) - interp.step(s_frame) + step_in_interp(s_frame) + step_in_interp(s_frame) assert w_association.fetch(space, 1).is_same_object(space.w_one) def test_extendedStoreAndPopBytecode(): @@ -587,7 +590,7 @@ w_object = shadow.new() s_frame.push(w_object) s_frame.push(space.w_one) - w_active_context = interp.step(s_frame) + w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) assert w_active_context.as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] assert s_active_context.w_receiver() is w_object @@ -604,7 +607,7 @@ for i in range(6): s_frame.push(space.w_one) s_frame.push(space.w_two) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.stack() == [space.w_true, space.w_false, space.w_true, space.w_false, space.w_false, space.w_true] @@ -638,13 +641,13 @@ w_frame, s_frame = new_frame(bytecodes) s_frame.w_method().setliterals(literals) s_frame.push(w_object) - w_active_context = interp.step(s_frame) + w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) for w_specificclass in [w_super, w_supersuper]: w_caller_context = w_active_context s_caller_context = s_active_context - interp.step(s_active_context) - w_active_context = interp.step(s_active_context) + step_in_interp(s_active_context) + w_active_context = step_in_interp(s_active_context) s_active_context = w_active_context.as_context_get_shadow(space) assert s_active_context.w_sender() == w_caller_context assert s_active_context.stack() == [] @@ -755,12 +758,13 @@ # # [ :a :b | a - b ] valueWithArguments: #(3 2) def test(): - assert interpret_bc( + val = interpret_bc( [ 137, 119, 200, 164, 6, 105, 104, 16, 17, 177, 125, 33, 224, 124 ], fakeliterals(space, "valueWithArguments:", - [3, 2])).value == 1 + [3, 2])) + assert val.value == 1 run_with_faked_primitive_methods( [[space.w_BlockContext, primitives.VALUE_WITH_ARGS, 1, "valueWithArguments:"]], @@ -856,7 +860,7 @@ s_frame.push(fakeliterals(space, "egg")) s_frame.push(fakeliterals(space, "bar")) s_frame.push(fakeliterals(space, "baz")) - interp.step(s_frame) + step_in_interp(s_frame) array = s_frame.pop() assert array.at0(space, 0) == fakeliterals(space, "egg") assert array.at0(space, 1) == fakeliterals(space, "bar") @@ -864,7 +868,7 @@ def test_bc_pushNewArray(bytecode=pushNewArrayBytecode): w_frame, s_frame = new_frame(bytecode + chr(0x07)) - interp.step(s_frame) + step_in_interp(s_frame) array = s_frame.pop() assert array.size() == 7 assert array.at0(space, 0) == space.w_nil @@ -872,7 +876,7 @@ def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode): w_frame, s_frame = new_frame(bytecode + chr(0) + chr(0)) s_frame.settemp(0, space.w_Array.as_class_get_shadow(interp.space).new(2)) - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.top() == space.w_nil def setupTempArrayAndContext(bytecode): @@ -883,7 +887,7 @@ temp_array = space.w_Array.as_class_get_shadow(interp.space).new(3) temp_array.atput0(space, 2, fakeliterals(space, "pub")) s_frame.settemp(1, temp_array) - interp.step(s_frame) + step_in_interp(s_frame) return s_frame, temp_array def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode): @@ -905,7 +909,7 @@ w_frame, s_frame = new_frame(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) pc = s_frame.pc() # create/find a method with an appropriate blockClosure - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 4 + i closure = wrapper.BlockClosureWrapper(space, s_frame.top()) assert closure.startpc() == pc + 4 @@ -916,7 +920,7 @@ s_frame.push("english") s_frame.push("bar") pc = s_frame.pc() - interp.step(s_frame) + step_in_interp(s_frame) assert s_frame.pc() == pc + 4 closure = wrapper.BlockClosureWrapper(space, s_frame.top()) assert closure.startpc() == pc + 4 @@ -949,3 +953,40 @@ [[space.w_BlockClosure, primitives.CLOSURE_VALUE_VALUE, 2, "value:value:"]], test) + +def test_stacking_interpreter(): + # | testBlock | + # testBlock := [ :aNumber | + # aNumber = 0 + # ifTrue: [ 0 ] + # ifFalse: [ (testBlock value: aNumber - 1) + aNumber ]]. + # ^ testBlock value: 11 + import operator + interp = interpreter.Interpreter(space, max_stack_depth=2) + #create a method with the correct bytecodes and a literal + bytes = reduce(operator.add, map(chr, [0x8a, 0x01, 0x68, 0x10, 0x8f, 0x11, + 0x00, 0x11, 0x10, 0x75, 0xb6, 0x9a, 0x75, 0xa4, 0x09, 0x8c, 0x00, 0x01, + 0x10, 0x76, 0xb1, 0xca, 0x10, 0xb0, 0x7d, 0x8e, 0x00, 0x00, 0x8c, 0x00, + 0x00, 0x20, 0xca, 0x7c])) + w_method = model.W_CompiledMethod(len(bytes)) + w_method.islarge = 1 + w_method.bytes = bytes + w_method.argsize=0 + w_method.tempsize=1 + w_method.setliterals([space.wrap_int(11)]) + + #create a frame for that method + w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []) + try: + interp.loop(w_frame) + except interpreter.ReturnFromTopLevel, e: + assert space.unwrap_int(e.object) == 66 + except interpreter.StackOverflow, e: + assert False + try: + interp = interpreter.StackedInterpreter(space, None, "", 10) + interp.loop(w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), [])) + except interpreter.StackOverflow, e: + assert e.w_context.getclass(space) is space.w_MethodContext + except interpreter.ReturnFromTopLevel, e: + assert False \ No newline at end of file From noreply at buildbot.pypy.org Fri Mar 1 17:58:31 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 1 Mar 2013 17:58:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: removed unused method #step in Interpreter Message-ID: <20130301165831.47FC91C00E4@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r113:859f20a13015 Date: 2013-03-01 17:57 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/859f20a13015/ Log: removed unused method #step in Interpreter removed 'if False:' branch in ContextPartShadow._sendSelector diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -53,34 +53,6 @@ return conftest.option.bc_trace return conftest.option.prim_trace - def step(self, s_active_context): - """NOT_RPYTHON: only for testing""" - next = s_active_context.getbytecode() - bytecodeimpl = BYTECODE_TABLE[next] - - if self.should_trace(): - if self._w_last_active_context != self.w_active_context(): - cnt = 0 - p = self.w_active_context() - # AK make method - while not p.is_same_object(self.space.w_nil): - cnt += 1 - # Do not update the context - # for this action. - p = p.as_context_get_shadow(self.space).w_sender() - self._last_indent = " " * cnt - self._w_last_active_context = self.w_active_context() - - print "%sStack=%s" % ( - self._last_indent, - repr(s_active_context.stack()),) - print "%sBytecode at %d (%d:%s):" % ( - self._last_indent, - s_active_context.pc(), - next, bytecodeimpl.__name__,) - - return bytecodeimpl(s_active_context, self, next) - def loop(self, w_active_context): self._loop = True s_active_context = w_active_context.as_context_get_shadow(self.space) @@ -303,22 +275,14 @@ code = s_method.primitive if interp.should_trace(): print "%sActually calling primitive %d" % (interp._last_indent, code,) - if False: #objectmodel.we_are_translated(): - for i, func in primitives.unrolling_prim_table: - if i == code: - try: - return func(interp, self, argcount) - except primitives.PrimitiveFailedError: - break - else: - func = primitives.prim_table[code] - try: - # note: argcount does not include rcvr - return func(interp, self, argcount) - except primitives.PrimitiveFailedError: - if interp.should_trace(True): - print "PRIMITIVE FAILED: %d %s" % (s_method.primitive, w_selector.as_string(),) - pass # ignore this error and fall back to the Smalltalk version + func = primitives.prim_table[code] + try: + # note: argcount does not include rcvr + return func(interp, self, argcount) + except primitives.PrimitiveFailedError: + if interp.should_trace(True): + print "PRIMITIVE FAILED: %d %s" % (s_method.primitive, w_selector.as_string(),) + pass # ignore this error and fall back to the Smalltalk version arguments = self.pop_and_return_n(argcount) w_frame = s_method.create_frame(self.space, receiver, arguments, self.w_self()) From noreply at buildbot.pypy.org Fri Mar 1 17:59:00 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Mar 2013 17:59:00 +0100 (CET) Subject: [pypy-commit] pypy py3k: 64bit translation fix Message-ID: <20130301165900.641A41C00E4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61891:b4a002fda4cc Date: 2013-03-01 08:58 -0800 http://bitbucket.org/pypy/pypy/changeset/b4a002fda4cc/ Log: 64bit translation fix diff --git a/pypy/module/_codecs/locale.py b/pypy/module/_codecs/locale.py --- a/pypy/module/_codecs/locale.py +++ b/pypy/module/_codecs/locale.py @@ -34,6 +34,7 @@ # An actual wchar_t*, rffi.CWCHARP is an array of UniChar (possibly on a # narrow build) RAW_WCHARP = lltype.Ptr(lltype.Array(rffi.WCHAR_T, hints={'nolength': True})) +WCHAR_NUL = rffi.cast(rffi.WCHAR_T, u'\x00') pypy_char2wchar = llexternal('pypy_char2wchar', [rffi.CCHARP, rffi.SIZE_TP], RAW_WCHARP) pypy_char2wchar_free = llexternal('pypy_char2wchar_free', [RAW_WCHARP], @@ -115,7 +116,7 @@ """unicode -> raw wchar_t*""" size = _unicode2rawwcharp_loop(u, None) if MERGE_SURROGATES else len(u) array = lltype.malloc(RAW_WCHARP.TO, size + 1, flavor='raw') - array[size] = rffi.cast(rffi.WCHAR_T, u'\x00') + array[size] = WCHAR_NUL _unicode2rawwcharp_loop(u, array) return array unicode2rawwcharp._annenforceargs_ = [unicode] @@ -146,7 +147,7 @@ def rawwcharp2unicoden(wcp, maxlen): b = UnicodeBuilder(maxlen) i = 0 - while i < maxlen and wcp[i] != 0: + while i < maxlen and wcp[i] != WCHAR_NUL: b.append(code_to_unichr(wcp[i])) i += 1 return assert_str0(b.build()) From noreply at buildbot.pypy.org Fri Mar 1 18:07:41 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 1 Mar 2013 18:07:41 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Fix rpython/translator/c/test/test_newgc.py. Message-ID: <20130301170741.A0E8D1C00E4@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61892:0ad97e3b96ef Date: 2013-02-27 17:04 +0100 http://bitbucket.org/pypy/pypy/changeset/0ad97e3b96ef/ Log: Fix rpython/translator/c/test/test_newgc.py. diff --git a/rpython/translator/c/test/test_newgc.py b/rpython/translator/c/test/test_newgc.py --- a/rpython/translator/c/test/test_newgc.py +++ b/rpython/translator/c/test/test_newgc.py @@ -43,9 +43,9 @@ t = Translation(main, gc=cls.gcpolicy, taggedpointers=cls.taggedpointers, - gcremovetypeptr=cls.removetypeptr) - t.disable(['backendopt']) - t.set_backend_extra_options(c_debug_defines=True) + gcremovetypeptr=cls.removetypeptr, + **{'backendopt.none': True}) + t.set_backend_extra_options({'c_debug_defines': True}) t.rtype() if option.view: t.viewcg() diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -108,6 +108,7 @@ self.create_exe() else: self.driver.c_entryp = cbuilder.get_entry_point() + return self.driver.c_entryp def create_exe(self): """ Copy the compiled executable into translator/goal From noreply at buildbot.pypy.org Fri Mar 1 18:07:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 1 Mar 2013 18:07:42 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Fix rpython/translator/c/test/test_rtagged.py. Message-ID: <20130301170742.EAF941C087E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61893:2b254eb61df4 Date: 2013-02-27 17:05 +0100 http://bitbucket.org/pypy/pypy/changeset/2b254eb61df4/ Log: Fix rpython/translator/c/test/test_rtagged.py. diff --git a/rpython/translator/c/test/test_rtagged.py b/rpython/translator/c/test/test_rtagged.py --- a/rpython/translator/c/test/test_rtagged.py +++ b/rpython/translator/c/test/test_rtagged.py @@ -69,7 +69,7 @@ def test_tagged_boehm(): t = Translation(entry_point, gc='boehm', taggedpointers=True) try: - exename = str(t.compile_c()) + exename = str(t.compile()) finally: if option.view: t.view() From noreply at buildbot.pypy.org Fri Mar 1 18:07:44 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 1 Mar 2013 18:07:44 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Fix rpython/translator/c/test/test_standalone.py. Message-ID: <20130301170744.3B3481C00E4@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61894:2bfaaa21b44b Date: 2013-02-27 17:11 +0100 http://bitbucket.org/pypy/pypy/changeset/2bfaaa21b44b/ Log: Fix rpython/translator/c/test/test_standalone.py. diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -219,7 +219,7 @@ funcgen.patch_graph(copy_graph=False) return db - def generate_source(self, db=None, debug_defines=True, exe_name=None): + def generate_source(self, db=None, debug_defines=False, exe_name=None): assert self.c_source_filename is None if db is None: From noreply at buildbot.pypy.org Fri Mar 1 18:07:45 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 1 Mar 2013 18:07:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: Implement release() and context manager protocol on memoryview. Message-ID: <20130301170745.77D111C00E4@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61895:11b581d8503f Date: 2013-03-01 12:54 +0100 http://bitbucket.org/pypy/pypy/changeset/11b581d8503f/ Log: Implement release() and context manager protocol on memoryview. diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py --- a/pypy/module/__builtin__/interp_memoryview.py +++ b/pypy/module/__builtin__/interp_memoryview.py @@ -20,6 +20,8 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): other = space.interpclass_w(w_other) + if self.buf is None: + return space.wrap(getattr(operator, name)(self, other)) if isinstance(other, W_MemoryView): # xxx not the most efficient implementation str1 = self.as_str() @@ -66,12 +68,15 @@ not in CPython; but CPython supports passing memoryview() to most built-in functions that accept buffers, with the notable exception of the buffer() built-in.""" + self._check_released(space) return space.wrap(self.buf) def descr_tobytes(self, space): + self._check_released(space) return space.wrapbytes(self.as_str()) def descr_tolist(self, space): + self._check_released(space) buf = self.buf result = [] for i in range(buf.getlength()): @@ -79,6 +84,7 @@ return space.newlist(result) def descr_getitem(self, space, w_index): + self._check_released(space) start, stop, step = space.decode_index(w_index, self.getlength()) if step == 0: # index only return space.wrapbytes(self.buf.getitem(start)) @@ -92,6 +98,7 @@ @unwrap_spec(newstring='bufferstr') def descr_setitem(self, space, w_index, newstring): + self._check_released(space) buf = self.buf if isinstance(buf, buffer.RWBuffer): buf.descr_setitem(space, w_index, newstring) @@ -100,26 +107,53 @@ space.wrap("cannot modify read-only memory")) def descr_len(self, space): + self._check_released(space) return self.buf.descr_len(space) def w_get_format(self, space): + self._check_released(space) return space.wrap("B") def w_get_itemsize(self, space): + self._check_released(space) return space.wrap(1) def w_get_ndim(self, space): + self._check_released(space) return space.wrap(1) def w_is_readonly(self, space): + self._check_released(space) return space.wrap(not isinstance(self.buf, buffer.RWBuffer)) def w_get_shape(self, space): + self._check_released(space) return space.newtuple([space.wrap(self.getlength())]) def w_get_strides(self, space): + self._check_released(space) return space.newtuple([space.wrap(1)]) def w_get_suboffsets(self, space): + self._check_released(space) # I've never seen anyone filling this field return space.w_None def descr_repr(self, space): - return self.getrepr(space, 'memory') + if self.buf is None: + return self.getrepr(space, 'released memory') + else: + return self.getrepr(space, 'memory') + + def descr_release(self, space): + self.buf = None + + def _check_released(self, space): + if self.buf is None: + raise OperationError(space.w_ValueError, space.wrap( + "operation forbidden on released memoryview object")) + + def descr_enter(self, space): + self._check_released(space) + return self + + def descr_exit(self, space, __args__): + self.buf = None + return space.w_None def descr_new(space, w_subtype, w_object): @@ -139,8 +173,11 @@ __ne__ = interp2app(W_MemoryView.descr_ne), __setitem__ = interp2app(W_MemoryView.descr_setitem), __repr__ = interp2app(W_MemoryView.descr_repr), + __enter__ = interp2app(W_MemoryView.descr_enter), + __exit__ = interp2app(W_MemoryView.descr_exit), tobytes = interp2app(W_MemoryView.descr_tobytes), tolist = interp2app(W_MemoryView.descr_tolist), + release = interp2app(W_MemoryView.descr_release), format = GetSetProperty(W_MemoryView.w_get_format), itemsize = GetSetProperty(W_MemoryView.w_get_itemsize), ndim = GetSetProperty(W_MemoryView.w_get_ndim), diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -80,3 +80,31 @@ def test_suboffsets(self): v = memoryview(b"a"*100) assert v.suboffsets == None + + def test_release(self): + v = memoryview(b"a"*100) + v.release() + raises(ValueError, len, v) + raises(ValueError, v.tolist) + raises(ValueError, v.tobytes) + raises(ValueError, "v[0]") + raises(ValueError, "v[0] = b'a'") + raises(ValueError, "v.format") + raises(ValueError, "v.itemsize") + raises(ValueError, "v.ndim") + raises(ValueError, "v.readonly") + raises(ValueError, "v.shape") + raises(ValueError, "v.strides") + raises(ValueError, "v.suboffsets") + raises(ValueError, "with v as cm: pass") + raises(ValueError, "memoryview(v)") + assert v == v + assert v != memoryview(b"a"*100) + assert v != b"a"*100 + assert "released memory" in repr(v) + + def test_context_manager(self): + v = memoryview(b"a"*100) + with v as cm: + assert cm is v + assert "released memory" in repr(v) From noreply at buildbot.pypy.org Fri Mar 1 18:07:46 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 1 Mar 2013 18:07:46 +0100 (CET) Subject: [pypy-commit] pypy py3k: PyPy raises TypeError instead of ValueError here. Message-ID: <20130301170746.A43C01C00E4@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61896:9f1bcd8fadc8 Date: 2013-03-01 13:46 +0100 http://bitbucket.org/pypy/pypy/changeset/9f1bcd8fadc8/ Log: PyPy raises TypeError instead of ValueError here. diff --git a/lib-python/3.2/test/test_memoryview.py b/lib-python/3.2/test/test_memoryview.py --- a/lib-python/3.2/test/test_memoryview.py +++ b/lib-python/3.2/test/test_memoryview.py @@ -109,8 +109,8 @@ self.assertRaises(TypeError, setitem, (0,), b"a") self.assertRaises(TypeError, setitem, "a", b"a") # Trying to resize the memory object - self.assertRaises(ValueError, setitem, 0, b"") - self.assertRaises(ValueError, setitem, 0, b"ab") + self.assertRaises((ValueError, TypeError), setitem, 0, b"") + self.assertRaises((ValueError, TypeError), setitem, 0, b"ab") self.assertRaises(ValueError, setitem, slice(1,1), b"a") self.assertRaises(ValueError, setitem, slice(0,2), b"a") From noreply at buildbot.pypy.org Fri Mar 1 18:07:48 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 1 Mar 2013 18:07:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge Message-ID: <20130301170748.4A7AC1C00E4@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61897:86f0a4a1237f Date: 2013-03-01 18:07 +0100 http://bitbucket.org/pypy/pypy/changeset/86f0a4a1237f/ Log: hg merge diff --git a/lib-python/3.2/test/test_imp.py b/lib-python/3.2/test/test_imp.py --- a/lib-python/3.2/test/test_imp.py +++ b/lib-python/3.2/test/test_imp.py @@ -161,8 +161,9 @@ os.mkdir(test_package_name) with open(init_file_name, 'w') as file: file.write('b = 2\n') - package = imp.load_package(test_package_name, test_package_name) - self.assertEqual(package.b, 2) + if support.check_impl_detail(cpython=True): + package = imp.load_package(test_package_name, test_package_name) + self.assertEqual(package.b, 2) finally: del sys.path[0] for ext in ('.py', '.pyc', '.pyo'): diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -49,8 +49,9 @@ try: try: space.call_function(w_run_toplevel, w_call_startup_gateway) - w_executable = space.wrap(argv[0]) - w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) + w_executable = space.fsdecode(space.wrapbytes(argv[0])) + w_argv = space.newlist([space.fsdecode(space.wrapbytes(s)) + for s in argv[1:]]) w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) exitcode = space.int_w(w_exitcode) # try to pull it all in diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1397,6 +1397,11 @@ """ return w_obj.identifier_w(self) + def fsencode_w(self, w_obj): + if self.isinstance_w(w_obj, self.w_unicode): + w_obj = self.fsencode(w_obj) + return self.bytes0_w(w_obj) + def bool_w(self, w_obj): # Unwraps a bool, also accepting an int for compatibility. # This is here mostly just for gateway.int_unwrapping_space_method(). diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -135,6 +135,9 @@ def visit_str0(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_fsencode(self, el, app_sig): + self.checked_space_method(el, app_sig) + def visit_nonnegint(self, el, app_sig): self.checked_space_method(el, app_sig) @@ -256,6 +259,9 @@ def visit_str0(self, typ): self.run_args.append("space.str0_w(%s)" % (self.scopenext(),)) + def visit_fsencode(self, typ): + self.run_args.append("space.fsencode_w(%s)" % (self.scopenext(),)) + def visit_nonnegint(self, typ): self.run_args.append("space.gateway_nonnegint_w(%s)" % ( self.scopenext(),)) @@ -396,6 +402,9 @@ def visit_str0(self, typ): self.unwrap.append("space.str0_w(%s)" % (self.nextarg(),)) + def visit_fsencode(self, typ): + self.unwrap.append("space.fsencode_w(%s)" % (self.nextarg(),)) + def visit_nonnegint(self, typ): self.unwrap.append("space.gateway_nonnegint_w(%s)" % (self.nextarg(),)) 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 @@ -385,6 +385,17 @@ w_app_g3_idx, space.mul(space.wrap(sys.maxint), space.wrap(-7))) + def test_interp2app_unwrap_spec_fsencode(self): + space = self.space + w = space.wrap + def f(filename): + return space.wrapbytes(filename) + app_f = gateway.interp2app_temp(f, unwrap_spec=['fsencode']) + w_app_f = space.wrap(app_f) + assert space.eq_w( + space.call_function(w_app_f, w(u'\udc80')), + space.wrapbytes('\x80')) + def test_interp2app_unwrap_spec_typechecks(self): space = self.space w = space.wrap diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1,7 +1,15 @@ +import sys from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import specialize from rpython.rlib import runicode from pypy.module._codecs import interp_codecs +_WIN32 = sys.platform == 'win32' +_MACOSX = sys.platform == 'darwin' +if _WIN32: + from rpython.rlib.runicode import str_decode_mbcs, unicode_encode_mbcs +else: + # Workaround translator's confusion + str_decode_mbcs = unicode_encode_mbcs = lambda *args, **kwargs: None @specialize.memo() def decode_error_handler(space): @@ -29,6 +37,60 @@ # ____________________________________________________________ +def PyUnicode_DecodeFSDefault(space, w_string): + state = space.fromcache(interp_codecs.CodecState) + if _WIN32: + bytes = space.bytes_w(w_string) + uni = str_decode_mbcs(bytes, len(bytes), 'strict', + errorhandler=decode_error_handler(space))[0] + elif _MACOSX: + bytes = space.bytes_w(w_string) + uni = runicode.str_decode_utf_8( + bytes, len(bytes), 'surrogateescape', + errorhandler=state.decode_error_handler)[0] + elif state.codec_need_encodings: + # bootstrap check: if the filesystem codec is implemented in + # Python we cannot use it before the codecs are ready. use the + # locale codec instead + from pypy.module._codecs.locale import ( + unicode_decode_locale_surrogateescape) + bytes = space.bytes_w(w_string) + uni = unicode_decode_locale_surrogateescape( + bytes, errorhandler=decode_error_handler(space)) + else: + from pypy.module.sys.interp_encoding import getfilesystemencoding + return space.call_method(w_string, 'decode', + getfilesystemencoding(space), + space.wrap('surrogateescape')) + return space.wrap(uni) + +def PyUnicode_EncodeFSDefault(space, w_uni): + state = space.fromcache(interp_codecs.CodecState) + if _WIN32: + uni = space.unicode_w(w_uni) + bytes = unicode_encode_mbcs(uni, len(uni), 'strict', + errorhandler=encode_error_handler(space)) + elif _MACOSX: + uni = space.unicode_w(w_uni) + bytes = runicode.unicode_encode_utf_8( + uni, len(uni), 'surrogateescape', + errorhandler=state.encode_error_handler) + elif state.codec_need_encodings: + # bootstrap check: if the filesystem codec is implemented in + # Python we cannot use it before the codecs are ready. use the + # locale codec instead + from pypy.module._codecs.locale import ( + unicode_encode_locale_surrogateescape) + uni = space.unicode_w(w_uni) + bytes = unicode_encode_locale_surrogateescape( + uni, errorhandler=encode_error_handler(space)) + else: + from pypy.module.sys.interp_encoding import getfilesystemencoding + return space.call_method(w_uni, 'encode', + getfilesystemencoding(space), + space.wrap('surrogateescape')) + return space.wrapbytes(bytes) + def PyUnicode_AsEncodedString(space, w_data, w_encoding): return interp_codecs.encode(space, w_data, w_encoding) diff --git a/pypy/module/_codecs/locale.py b/pypy/module/_codecs/locale.py --- a/pypy/module/_codecs/locale.py +++ b/pypy/module/_codecs/locale.py @@ -34,6 +34,7 @@ # An actual wchar_t*, rffi.CWCHARP is an array of UniChar (possibly on a # narrow build) RAW_WCHARP = lltype.Ptr(lltype.Array(rffi.WCHAR_T, hints={'nolength': True})) +WCHAR_NUL = rffi.cast(rffi.WCHAR_T, u'\x00') pypy_char2wchar = llexternal('pypy_char2wchar', [rffi.CCHARP, rffi.SIZE_TP], RAW_WCHARP) pypy_char2wchar_free = llexternal('pypy_char2wchar_free', [RAW_WCHARP], @@ -113,14 +114,14 @@ def unicode2rawwcharp(u): """unicode -> raw wchar_t*""" - size = _unicode2cwcharp_loop(u, None) if MERGE_SURROGATES else len(u) + size = _unicode2rawwcharp_loop(u, None) if MERGE_SURROGATES else len(u) array = lltype.malloc(RAW_WCHARP.TO, size + 1, flavor='raw') - array[size] = rffi.cast(rffi.WCHAR_T, u'\x00') - _unicode2cwcharp_loop(u, array) + array[size] = WCHAR_NUL + _unicode2rawwcharp_loop(u, array) return array unicode2rawwcharp._annenforceargs_ = [unicode] -def _unicode2cwcharp_loop(u, array): +def _unicode2rawwcharp_loop(u, array): write = array is not None ulen = len(u) count = i = 0 @@ -140,14 +141,14 @@ i += 1 count += 1 return count -unicode2rawwcharp._annenforceargs_ = [unicode, None] +_unicode2rawwcharp_loop._annenforceargs_ = [unicode, None] def rawwcharp2unicoden(wcp, maxlen): b = UnicodeBuilder(maxlen) i = 0 - while i < maxlen and wcp[i] != u'\x00': + while i < maxlen and wcp[i] != WCHAR_NUL: b.append(code_to_unichr(wcp[i])) i += 1 return assert_str0(b.build()) -unicode2rawwcharp._annenforceargs_ = [None, int] +rawwcharp2unicoden._annenforceargs_ = [None, int] diff --git a/pypy/module/_posixsubprocess/interp_subprocess.py b/pypy/module/_posixsubprocess/interp_subprocess.py --- a/pypy/module/_posixsubprocess/interp_subprocess.py +++ b/pypy/module/_posixsubprocess/interp_subprocess.py @@ -1,5 +1,5 @@ from rpython.rtyper.lltypesystem import rffi, lltype, llmemory -from pypy.module.posix.interp_posix import fsencode_w, run_fork_hooks +from pypy.module.posix.interp_posix import run_fork_hooks from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.error import ( OperationError, exception_from_errno, wrap_oserror) @@ -115,7 +115,7 @@ l_exec_array = rffi.liststr2charpp(exec_array) if not space.is_none(w_process_args): - argv = [fsencode_w(space, w_item) + argv = [space.fsencode_w(w_item) for w_item in space.listview(w_process_args)] l_argv = rffi.liststr2charpp(argv) @@ -136,7 +136,7 @@ preexec.w_preexec_fn = None if not space.is_none(w_cwd): - cwd = fsencode_w(space, w_cwd) + cwd = space.fsencode_w(w_cwd) l_cwd = rffi.str2charp(cwd) run_fork_hooks('before', space) diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -12,7 +12,6 @@ make_typedescr, get_typedescr) from pypy.module.cpyext.bytesobject import PyBytes_Check, PyBytes_FromObject from pypy.module._codecs.interp_codecs import CodecState -from pypy.module.posix.interp_posix import fsencode, fsdecode from pypy.objspace.std import unicodeobject, unicodetype, stringtype from rpython.rlib import runicode, rstring from rpython.tool.sourcetools import func_renamer @@ -423,7 +422,7 @@ w_output = w_obj else: w_obj = PyUnicode_FromObject(space, w_obj) - w_output = fsencode(space, w_obj) + w_output = space.fsencode(w_obj) if not space.isinstance_w(w_output, space.w_bytes): raise OperationError(space.w_TypeError, space.wrap("encoder failed to return bytes")) @@ -447,7 +446,7 @@ w_output = w_obj else: w_obj = PyBytes_FromObject(space, w_obj) - w_output = fsdecode(space, w_obj) + w_output = space.fsdecode(w_obj) if not space.isinstance_w(w_output, space.w_unicode): raise OperationError(space.w_TypeError, space.wrap("decoder failed to return unicode")) @@ -466,7 +465,7 @@ Use 'strict' error handler on Windows.""" w_bytes = space.wrapbytes(rffi.charpsize2str(s, size)) - return fsdecode(space, w_bytes) + return space.fsdecode(w_bytes) @cpython_api([rffi.CCHARP], PyObject) @@ -481,7 +480,7 @@ Use 'strict' error handler on Windows.""" w_bytes = space.wrapbytes(rffi.charp2str(s)) - return fsdecode(space, w_bytes) + return space.fsdecode(w_bytes) @cpython_api([PyObject], PyObject) @@ -494,7 +493,7 @@ If Py_FileSystemDefaultEncoding is not set, fall back to the locale encoding. """ - return fsencode(space, w_unicode) + return space.fsencode(w_unicode) @cpython_api([CONST_STRING], PyObject) 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 @@ -421,7 +421,7 @@ def __init__(self, space): pass - @unwrap_spec(path='str0') + @unwrap_spec(path='fsencode') def descr_init(self, space, path): if not path: raise OperationError(space.w_ImportError, space.wrap( diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -57,7 +57,7 @@ return streamio.fdopen_as_stream(fd, filemode) def find_module(space, w_name, w_path=None): - name = space.str0_w(w_name) + name = space.fsencode_w(w_name) if space.is_none(w_path): w_path = None @@ -68,7 +68,7 @@ space.w_ImportError, "No module named %s", name) - w_filename = space.wrap(find_info.filename) + w_filename = space.fsdecode(space.wrapbytes(find_info.filename)) stream = find_info.stream if stream is not None: @@ -107,7 +107,7 @@ def load_module(space, w_name, w_file, w_filename, w_info): w_suffix, w_filemode, w_modtype = space.unpackiterable(w_info) - filename = space.str0_w(w_filename) + filename = space.fsencode_w(w_filename) filemode = space.str_w(w_filemode) if space.is_w(w_file, space.w_None): stream = None @@ -124,7 +124,7 @@ space, w_name, find_info, reuse=True) def load_source(space, w_modulename, w_filename, w_file=None): - filename = space.str0_w(w_filename) + filename = space.fsencode_w(w_filename) stream = get_file(space, w_file, filename, 'U') @@ -138,7 +138,7 @@ stream.close() return w_mod - at unwrap_spec(filename='str0', write_paths=bool) + at unwrap_spec(filename='fsencode', write_paths=bool) def _run_compiled_module(space, w_modulename, filename, w_file, w_module, write_paths=True): # the function 'imp._run_compiled_module' is a pypy-only extension @@ -153,14 +153,14 @@ if space.is_none(w_file): stream.close() - at unwrap_spec(filename='str0') + at unwrap_spec(filename='fsencode') def load_compiled(space, w_modulename, filename, w_file=None): w_mod = space.wrap(Module(space, w_modulename)) importing._prepare_module(space, w_mod, filename, None) _run_compiled_module(space, w_modulename, filename, w_file, w_mod) return w_mod - at unwrap_spec(filename=str) + at unwrap_spec(filename='fsencode') def load_dynamic(space, w_modulename, filename, w_file=None): if not space.config.objspace.usemodules.cpyext: raise OperationError(space.w_ImportError, space.wrap( @@ -215,7 +215,7 @@ if space.config.objspace.usemodules.thread: importing.getimportlock(space).reinit_lock() - at unwrap_spec(pathname='str0') + at unwrap_spec(pathname='fsencode') def cache_from_source(space, pathname, w_debug_override=None): """cache_from_source(path, [debug_override]) -> path Given the path to a .py file, return the path to its .pyc/.pyo file. @@ -226,9 +226,10 @@ If debug_override is not None, then it must be a boolean and is taken as the value of __debug__ instead.""" - return space.wrap(importing.make_compiled_pathname(pathname)) + return space.fsdecode(space.wrapbytes( + importing.make_compiled_pathname(pathname))) - at unwrap_spec(pathname='str0') + at unwrap_spec(pathname='fsencode') def source_from_cache(space, pathname): """source_from_cache(path) -> path Given the path to a .pyc./.pyo file, return the path to its .py file. @@ -240,4 +241,4 @@ if sourcename is None: raise operationerrfmt(space.w_ValueError, "Not a PEP 3147 pyc path: %s", pathname) - return space.wrap(sourcename) + return space.fsdecode(space.wrapbytes(sourcename)) diff --git a/pypy/module/imp/test/__init__.py b/pypy/module/imp/test/__init__.py new file mode 100644 diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -1,8 +1,10 @@ +# coding: utf-8 import py from pypy.interpreter.module import Module from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.interpreter.pycode import PyCode +from pypy.module.imp.test.support import BaseImportTest from rpython.tool.udir import udir from rpython.rlib import streamio from pypy.tool.option import make_config @@ -31,7 +33,8 @@ f.close() return p -def setup_directory_structure(space): +def setup_directory_structure(cls): + space = cls.space root = setuppkg("", a = "imamodule = 1\ninpackage = 0", ambig = "imamodule = 1", @@ -90,11 +93,40 @@ 'a=5\nb=6\rc="""hello\r\nworld"""\r', mode='wb') p.join('mod.py').write( 'a=15\nb=16\rc="""foo\r\nbar"""\r', mode='wb') - setuppkg("encoded", + p = setuppkg("encoded", # actually a line 2, setuppkg() sets up a line1 line2 = "# encoding: iso-8859-1\n", bad = "# encoding: uft-8\n") + fsenc = sys.getfilesystemencoding() + # covers utf-8 and Windows ANSI code pages one non-space symbol from + # every page (http://en.wikipedia.org/wiki/Code_page) + known_locales = { + 'utf-8' : b'\xc3\xa4', + 'cp1250' : b'\x8C', + 'cp1251' : b'\xc0', + 'cp1252' : b'\xc0', + 'cp1253' : b'\xc1', + 'cp1254' : b'\xc0', + 'cp1255' : b'\xe0', + 'cp1256' : b'\xe0', + 'cp1257' : b'\xc0', + 'cp1258' : b'\xc0', + } + + if sys.platform == 'darwin': + # Mac OS X uses the Normal Form D decomposition + # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html + special_char = b'a\xcc\x88' + else: + special_char = known_locales.get(fsenc) + + if special_char: + p.join(special_char + '.py').write('pass') + cls.w_special_char = space.wrap(special_char.decode(fsenc)) + else: + cls.w_special_char = space.w_None + # create compiled/x.py and a corresponding pyc file p = setuppkg("compiled", x = "x = 84") if conftest.option.runappdirect: @@ -132,8 +164,9 @@ return str(root) -def _setup(space): - dn = setup_directory_structure(space) +def _setup(cls): + space = cls.space + dn = setup_directory_structure(cls) return space.appexec([space.wrap(dn)], """ (dn): import sys @@ -153,14 +186,15 @@ """) -class AppTestImport: +class AppTestImport(BaseImportTest): spaceconfig = { "usemodules": ['rctime'], } def setup_class(cls): + BaseImportTest.setup_class.im_func(cls) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) - cls.w_saved_modules = _setup(cls.space) + cls.w_saved_modules = _setup(cls) #XXX Compile class def teardown_class(cls): @@ -681,6 +715,30 @@ import encoded raises(SyntaxError, imp.find_module, 'bad', encoded.__path__) + def test_find_module_fsdecode(self): + import sys + name = self.special_char + if not name: + skip("can't run this test with %s as filesystem encoding" + % sys.getfilesystemencoding()) + import imp + import encoded + f, filename, _ = imp.find_module(name, encoded.__path__) + assert f is not None + assert filename[:-3].endswith(name) + + def test_unencodable(self): + if not self.testfn_unencodable: + skip("need an unencodable filename") + import imp + import os + name = self.testfn_unencodable + os.mkdir(name) + try: + raises(ImportError, imp.NullImporter, name) + finally: + os.rmdir(name) + class TestAbi: def test_abi_tag(self): @@ -1316,7 +1374,7 @@ def setup_class(cls): usepycfiles = cls.spaceconfig['objspace.usepycfiles'] cls.w_usepycfiles = cls.space.wrap(usepycfiles) - cls.saved_modules = _setup(cls.space) + cls.saved_modules = _setup(cls) def teardown_class(cls): _teardown(cls.space, cls.saved_modules) diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -10,7 +10,6 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rtyper.tool import rffi_platform from rpython.translator.tool.cbuild import ExternalCompilationInfo -from pypy.module.sys.interp_encoding import getfilesystemencoding import os, sys @@ -36,30 +35,13 @@ raise OperationError(space.w_OverflowError, space.wrap("integer out of range")) -def fsencode_w(space, w_obj): - if space.isinstance_w(w_obj, space.w_unicode): - w_obj = fsencode(space, w_obj) - return space.bytes0_w(w_obj) - -def fsencode(space, w_obj): - w_bytes = space.call_method(w_obj, 'encode', - getfilesystemencoding(space), - space.wrap('surrogateescape')) - return w_bytes - -def fsdecode(space, w_obj): - w_unicode = space.call_method(w_obj, 'decode', - getfilesystemencoding(space), - space.wrap('surrogateescape')) - return w_unicode - class FileEncoder(object): def __init__(self, space, w_obj): self.space = space self.w_obj = w_obj def as_bytes(self): - return fsencode_w(self.space, self.w_obj) + return self.space.fsencode_w(self.w_obj) def as_unicode(self): return self.space.unicode0_w(self.w_obj) @@ -74,7 +56,7 @@ def as_unicode(self): space = self.space - w_unicode = fsdecode(space, self.w_obj) + w_unicode = space.fsdecode(self.w_obj) return space.unicode0_w(w_unicode) @specialize.memo() @@ -443,7 +425,7 @@ else: def getcwd(space): """Return the current working directory as a string.""" - return fsdecode(space, getcwdb(space)) + return space.fsdecode(getcwdb(space)) def chdir(space, w_path): """Change the current working directory to the specified path.""" @@ -557,7 +539,7 @@ result_w = [None] * len_result for i in range(len_result): w_bytes = space.wrapbytes(result[i]) - result_w[i] = fsdecode(space, w_bytes) + result_w[i] = space.fsdecode(w_bytes) else: dirname = space.str0_w(w_dirname) result = rposix.listdir(dirname) @@ -783,13 +765,13 @@ args: iterable of arguments env: dictionary of strings mapping to strings """ - command = fsencode_w(space, w_command) + command = space.fsencode_w(w_command) try: args_w = space.unpackiterable(w_args) if len(args_w) < 1: w_msg = space.wrap("execv() must have at least one argument") raise OperationError(space.w_ValueError, w_msg) - args = [fsencode_w(space, w_arg) for w_arg in args_w] + args = [space.fsencode_w(w_arg) for w_arg in args_w] except OperationError, e: if not e.match(space, space.w_TypeError): raise diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -351,7 +351,7 @@ space = self.space return space.wrap(self.filename) - at unwrap_spec(name='str0') + at unwrap_spec(name='fsencode') def descr_new_zipimporter(space, w_type, name): ok = False parts_ends = [i for i in range(0, len(name)) diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -2,13 +2,14 @@ import time import struct from pypy.module.imp.importing import get_pyc_magic, _w_long +from pypy.module.imp.test.support import BaseImportTest from StringIO import StringIO from rpython.tool.udir import udir from zipfile import ZIP_STORED, ZIP_DEFLATED -class AppTestZipimport: +class AppTestZipimport(BaseImportTest): """ A bit structurized tests stolen and adapted from cpy's regression tests """ @@ -40,6 +41,7 @@ @classmethod def make_class(cls): + BaseImportTest.setup_class.im_func(cls) source = """\ def get_name(): return __name__ @@ -358,6 +360,24 @@ co_filename = code.co_filename assert co_filename == expected + def test_unencodable(self): + if not self.testfn_unencodable: + skip("need an unencodable filename") + import os + import time + import zipimport + from zipfile import ZipFile, ZipInfo + filename = self.testfn_unencodable + ".zip" + z = ZipFile(filename, "w") + zinfo = ZipInfo("uu.py", time.localtime(self.now)) + zinfo.compress_type = self.compression + z.writestr(zinfo, '') + z.close() + try: + zipimport.zipimporter(filename) + finally: + os.remove(filename) + class AppTestZipimportDeflated(AppTestZipimport): compression = ZIP_DEFLATED diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -497,6 +497,14 @@ "'%s' does not support the buffer interface", typename) return space.get_and_call_function(w_impl, w_obj) + def fsencode(space, w_obj): + from pypy.interpreter.unicodehelper import PyUnicode_EncodeFSDefault + return PyUnicode_EncodeFSDefault(space, w_obj) + + def fsdecode(space, w_obj): + from pypy.interpreter.unicodehelper import PyUnicode_DecodeFSDefault + return PyUnicode_DecodeFSDefault(space, w_obj) + # helpers From noreply at buildbot.pypy.org Sun Mar 3 16:05:54 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 3 Mar 2013 16:05:54 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix _io tests run with -A Message-ID: <20130303150554.30BBE1C034F@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61949:8785335d6ee8 Date: 2013-03-03 11:36 +0100 http://bitbucket.org/pypy/pypy/changeset/8785335d6ee8/ Log: Fix _io tests run with -A diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -240,12 +240,10 @@ def setup_class(cls): tmpfile = udir.join('tmpfile') cls.w_tmpfile = cls.space.wrap(str(tmpfile)) - if cls.runappdirect: - cls.w_readfile = tmpfile.read - else: - def readfile(space): - return space.wrapbytes(tmpfile.read()) - cls.w_readfile = cls.space.wrap(interp2app(readfile)) + + def w_readfile(self): + with open(self.tmpfile, 'rb') as f: + return f.read() def test_write(self): import _io From noreply at buildbot.pypy.org Sun Mar 3 16:05:55 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 3 Mar 2013 16:05:55 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix _socket tests with -A Message-ID: <20130303150555.B48661C03A7@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61950:55f827e1eae3 Date: 2013-03-03 12:04 +0100 http://bitbucket.org/pypy/pypy/changeset/55f827e1eae3/ Log: Fix _socket tests with -A diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -588,8 +588,9 @@ def setup_method(self, method): w_HOST = space.wrap(self.HOST) - self.w_serv = space.appexec([w_socket, w_HOST], - '''(_socket, HOST): + self.w_serv = space.appexec([w_HOST], + '''(HOST): + import _socket serv = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM) serv.bind((HOST, 0)) serv.listen(1) From noreply at buildbot.pypy.org Sun Mar 3 16:05:57 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 3 Mar 2013 16:05:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix most failures in module/zipimport Message-ID: <20130303150557.09DA91C395E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61951:7bb4c432036c Date: 2013-03-03 12:24 +0100 http://bitbucket.org/pypy/pypy/changeset/7bb4c432036c/ Log: Fix most failures in module/zipimport diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -9,11 +9,11 @@ TESTFN = '@test' -created_paths = dict.fromkeys(['_top_level', - os.path.join('_pkg', '__init__'), - os.path.join('_pkg', 'submodule'), - os.path.join('_pkg', '_subpkg', '__init__'), - os.path.join('_pkg', '_subpkg', 'submodule') +created_paths = dict.fromkeys([u'_top_level', + os.path.join(u'_pkg', '__init__'), + os.path.join(u'_pkg', 'submodule'), + os.path.join(u'_pkg', '_subpkg', '__init__'), + os.path.join(u'_pkg', '_subpkg', 'submodule') ]) From noreply at buildbot.pypy.org Sun Mar 3 16:05:58 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 3 Mar 2013 16:05:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20130303150558.7F14D1C3960@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61952:0bbb8eab0776 Date: 2013-03-03 15:57 +0100 http://bitbucket.org/pypy/pypy/changeset/0bbb8eab0776/ Log: hg merge default diff --git a/_pytest/pdb.py b/_pytest/pdb.py --- a/_pytest/pdb.py +++ b/_pytest/pdb.py @@ -72,10 +72,10 @@ tw.sep(">", "entering PDB") # A doctest.UnexpectedException is not useful for post_mortem. # Use the underlying exception instead: - if isinstance(call.excinfo.value, py.std.doctest.UnexpectedException): - tb = call.excinfo.value.exc_info[2] - else: - tb = call.excinfo._excinfo[2] + #if isinstance(call.excinfo.value, py.std.doctest.UnexpectedException): + # tb = call.excinfo.value.exc_info[2] + #else: + tb = call.excinfo._excinfo[2] post_mortem(tb) rep._pdbshown = True return rep diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -7,9 +7,9 @@ import re, os, math import pygame from pygame.locals import * +from strunicode import forceunicode -RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') @@ -52,12 +52,6 @@ else: return default -def forceunicode(name): - return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) - -def forcestr(name): - return name if isinstance(name, str) else name.encode(RAW_ENCODING) - class GraphLayout: fixedfont = False diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -1,6 +1,7 @@ import os, sys, re import subprocess import msgstruct +from strunicode import forcestr this_dir = os.path.dirname(os.path.abspath(__file__)) GRAPHSERVER = os.path.join(this_dir, 'graphserver.py') @@ -33,7 +34,6 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: - from drawgraph import forcestr f = open(save_tmp_file, 'w') f.write(forcestr(page.source)) f.close() @@ -76,7 +76,6 @@ def page_messages(page, graph_id): import graphparse - from drawgraph import forcestr return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,8 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr +from drawgraph import EventQueue, wait_for_events +from strunicode import forceunicode, forcestr METAKEYS = dict([ diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -45,7 +45,7 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): import codecs - from drawgraph import RAW_ENCODING + from strunicode import RAW_ENCODING f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/msgstruct.py b/dotviewer/msgstruct.py --- a/dotviewer/msgstruct.py +++ b/dotviewer/msgstruct.py @@ -24,9 +24,15 @@ long_max = 2147483647 +def _encodeme(x): + if type(x) is unicode: + x = x.encode('utf-8') + return x + def message(tp, *values): #print >> sys.stderr, tp, values typecodes = [''] + values = map(_encodeme, values) for v in values: if type(v) is str: typecodes.append('%ds' % len(v)) diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -88,7 +88,7 @@ PyPy has pluggable garbage collection policy. This means that various garbage collectors can be written for specialized purposes, or even various -experiments can be done for the general purpose. Examples +experiments can be done for the general purpose. Examples: * An incremental garbage collector that has specified maximal pause times, crucial for games @@ -97,6 +97,9 @@ * A concurrent garbage collector (a lot of work) +* A collector that keeps object flags in separate memory pages, to avoid + un-sharing all pages between several fork()ed processes + STM (Software Transactional Memory) ----------------------------------- diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -589,7 +589,7 @@ # banner (unless "-q" was specified) and run # $PYTHONSTARTUP. if not quiet: - print_banner() + print_banner(not no_site) python_startup = readenv and os.getenv('PYTHONSTARTUP') if python_startup: try: @@ -679,10 +679,11 @@ return status -def print_banner(): +def print_banner(copyright): print('Python %s on %s' % (sys.version, sys.platform)) - print('Type "help", "copyright", "credits" or ' - '"license" for more information.') + if copyright: + print('Type "help", "copyright", "credits" or ' + '"license" for more information.') STDLIB_WARNING = """\ debug: WARNING: Library path not found, using compiled-in sys.path. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1687,6 +1687,8 @@ 'UnicodeTranslateError', 'ValueError', 'ZeroDivisionError', + 'RuntimeWarning', + 'PendingDeprecationWarning', ] if sys.platform.startswith("win"): diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -757,6 +757,10 @@ expect_prompt=True, expect_banner=False) assert '42\n' in data + def test_option_S_copyright(self): + data = self.run('-S -i', expect_prompt=True, expect_banner=True) + assert 'copyright' not in data + def test_non_interactive_stdout_fully_buffered(self): path = getscript(r""" import sys, time diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -92,15 +92,20 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): + if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a " + "primitive cdata")) cdata2 = other._cdata + elif (misc.is_zero(space, w_other) and + not isinstance(self.ctype, W_CTypePrimitive)): + cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -156,6 +156,10 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): + if misc.is_zero(space, w_ob): + NULL = lltype.nullptr(rffi.CCHARP.TO) + rffi.cast(rffi.CCHARPP, cdata)[0] = NULL + return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -258,7 +262,12 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if space.is_w(w_init, space.w_None): + if misc.is_zero(space, w_init): + # Convert 0 to NULL. Note that passing 0 is not ambigous, + # despite the potential confusion: as a 'T*' argument, 0 means + # NULL, but as a 'T[]' argument it would mean "array of size 0" + # --- except that we specifically refuse to interpret numbers + # as the array size when passing arguments. rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) return 3 elif (space.isinstance_w(w_init, space.w_list) or diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -209,6 +209,11 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" +def is_zero(space, w_ob): + return ((space.isinstance_w(w_ob, space.w_int) or + space.isinstance_w(w_ob, space.w_long)) + and not space.is_true(w_ob)) + # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -388,6 +388,19 @@ assert (x == ["hello"]) is False assert (x != ["hello"]) is True +def test_cmp_pointer_with_0(): + p = new_pointer_type(new_primitive_type("int")) + x = cast(p, 0) + assert (x == 0) is True + assert (x != 0) is False + assert (0 == x) is True + assert (0 != x) is False + y = cast(p, 42) + assert (y == 0) is False + assert (y != 0) is True + assert (0 == y) is False + assert (0 != y) is True + def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) @@ -766,6 +779,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) + assert s.p4 == 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -778,8 +792,13 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p + s.p4 = 0 + assert s.p4 == 0 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) + assert s.p4 == 0 + # + s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -998,8 +1017,12 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(None) + res = f(0) # NULL assert res == -42 + res = f(long(0)) # NULL + assert res == -42 + py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): # declaring the function as int(unsigned char*) diff --git a/pypy/module/_minimal_curses/fficurses.py b/pypy/module/_minimal_curses/fficurses.py --- a/pypy/module/_minimal_curses/fficurses.py +++ b/pypy/module/_minimal_curses/fficurses.py @@ -35,7 +35,7 @@ c_tigetstr = rffi.llexternal('tigetstr', [rffi.CCHARP], rffi.CCHARP, compilation_info=eci) c_tparm = rffi.llexternal('tparm', [rffi.CCHARP, INT, INT, INT, INT, INT, - INT, INT, INT, INT, INT], rffi.CCHARP, + INT, INT, INT, INT], rffi.CCHARP, compilation_info=eci) ERR = rffi.CConstant('ERR', lltype.Signed) @@ -97,13 +97,13 @@ def tparm_llimpl(s, args): check_setup_invoked() - l = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - for i in range(min(len(args), 10)): + l = [0, 0, 0, 0, 0, 0, 0, 0, 0] + for i in range(min(len(args), 9)): l[i] = args[i] ll_s = rffi.str2charp(s) # XXX nasty trick stolen from CPython ll_res = c_tparm(ll_s, l[0], l[1], l[2], l[3], l[4], l[5], l[6], - l[7], l[8], l[9]) + l[7], l[8]) rffi.free_charp(ll_s) res = rffi.charp2str(ll_res) return res diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -416,210 +416,17 @@ def erf(space, w_x): """The error function""" - return math1(space, _erf, w_x) + return math1(space, rfloat.erf, w_x) def erfc(space, w_x): """The complementary error function""" - return math1(space, _erfc, w_x) + return math1(space, rfloat.erfc, w_x) def gamma(space, w_x): """Compute the gamma function for x.""" - return math1(space, _gamma, w_x) + return math1(space, rfloat.gamma, w_x) def lgamma(space, w_x): """Compute the natural logarithm of the gamma function for x.""" - return math1(space, _lgamma, w_x) + return math1(space, rfloat.lgamma, w_x) -# Implementation of the error function, the complimentary error function, the -# gamma function, and the natural log of the gamma function. These exist in -# libm, but I hear those implementations are horrible. - -ERF_SERIES_CUTOFF = 1.5 -ERF_SERIES_TERMS = 25 -ERFC_CONTFRAC_CUTOFF = 30. -ERFC_CONTFRAC_TERMS = 50 -_sqrtpi = 1.772453850905516027298167483341145182798 - -def _erf_series(x): - x2 = x * x - acc = 0. - fk = ERF_SERIES_TERMS + .5 - for i in range(ERF_SERIES_TERMS): - acc = 2.0 + x2 * acc / fk - fk -= 1. - return acc * x * math.exp(-x2) / _sqrtpi - -def _erfc_contfrac(x): - if x >= ERFC_CONTFRAC_CUTOFF: - return 0. - x2 = x * x - a = 0. - da = .5 - p = 1. - p_last = 0. - q = da + x2 - q_last = 1. - for i in range(ERFC_CONTFRAC_TERMS): - a += da - da += 2. - b = da + x2 - p_last, p = p, b * p - a * p_last - q_last, q = q, b * q - a * q_last - return p / q * x * math.exp(-x2) / _sqrtpi - -def _erf(x): - if rfloat.isnan(x): - return x - absx = abs(x) - if absx < ERF_SERIES_CUTOFF: - return _erf_series(x) - else: - cf = _erfc_contfrac(absx) - return 1. - cf if x > 0. else cf - 1. - -def _erfc(x): - if rfloat.isnan(x): - return x - absx = abs(x) - if absx < ERF_SERIES_CUTOFF: - return 1. - _erf_series(x) - else: - cf = _erfc_contfrac(absx) - return cf if x > 0. else 2. - cf - -def _sinpi(x): - y = math.fmod(abs(x), 2.) - n = int(rfloat.round_away(2. * y)) - if n == 0: - r = math.sin(math.pi * y) - elif n == 1: - r = math.cos(math.pi * (y - .5)) - elif n == 2: - r = math.sin(math.pi * (1. - y)) - elif n == 3: - r = -math.cos(math.pi * (y - 1.5)) - elif n == 4: - r = math.sin(math.pi * (y - 2.)) - else: - raise AssertionError("should not reach") - return rfloat.copysign(1., x) * r - -_lanczos_g = 6.024680040776729583740234375 -_lanczos_g_minus_half = 5.524680040776729583740234375 -_lanczos_num_coeffs = [ - 23531376880.410759688572007674451636754734846804940, - 42919803642.649098768957899047001988850926355848959, - 35711959237.355668049440185451547166705960488635843, - 17921034426.037209699919755754458931112671403265390, - 6039542586.3520280050642916443072979210699388420708, - 1439720407.3117216736632230727949123939715485786772, - 248874557.86205415651146038641322942321632125127801, - 31426415.585400194380614231628318205362874684987640, - 2876370.6289353724412254090516208496135991145378768, - 186056.26539522349504029498971604569928220784236328, - 8071.6720023658162106380029022722506138218516325024, - 210.82427775157934587250973392071336271166969580291, - 2.5066282746310002701649081771338373386264310793408 -] -_lanczos_den_coeffs = [ - 0.0, 39916800.0, 120543840.0, 150917976.0, 105258076.0, 45995730.0, - 13339535.0, 2637558.0, 357423.0, 32670.0, 1925.0, 66.0, 1.0] -LANCZOS_N = len(_lanczos_den_coeffs) -_lanczos_n_iter = unroll.unrolling_iterable(range(LANCZOS_N)) -_lanczos_n_iter_back = unroll.unrolling_iterable(range(LANCZOS_N - 1, -1, -1)) -_gamma_integrals = [ - 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, - 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0, - 1307674368000.0, 20922789888000.0, 355687428096000.0, - 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0, - 51090942171709440000.0, 1124000727777607680000.0] - -def _lanczos_sum(x): - num = 0. - den = 0. - assert x > 0. - if x < 5.: - for i in _lanczos_n_iter_back: - num = num * x + _lanczos_num_coeffs[i] - den = den * x + _lanczos_den_coeffs[i] - else: - for i in _lanczos_n_iter: - num = num / x + _lanczos_num_coeffs[i] - den = den / x + _lanczos_den_coeffs[i] - return num / den - -def _gamma(x): - if rfloat.isnan(x) or (rfloat.isinf(x) and x > 0.): - return x - if rfloat.isinf(x): - raise ValueError("math domain error") - if x == 0.: - raise ValueError("math domain error") - if x == math.floor(x): - if x < 0.: - raise ValueError("math domain error") - if x < len(_gamma_integrals): - return _gamma_integrals[int(x) - 1] - absx = abs(x) - if absx < 1e-20: - r = 1. / x - if rfloat.isinf(r): - raise OverflowError("math range error") - return r - if absx > 200.: - if x < 0.: - return 0. / -_sinpi(x) - else: - raise OverflowError("math range error") - y = absx + _lanczos_g_minus_half - if absx > _lanczos_g_minus_half: - q = y - absx - z = q - _lanczos_g_minus_half - else: - q = y - _lanczos_g_minus_half - z = q - absx - z = z * _lanczos_g / y - if x < 0.: - r = -math.pi / _sinpi(absx) / absx * math.exp(y) / _lanczos_sum(absx) - r -= z * r - if absx < 140.: - r /= math.pow(y, absx - .5) - else: - sqrtpow = math.pow(y, absx / 2. - .25) - r /= sqrtpow - r /= sqrtpow - else: - r = _lanczos_sum(absx) / math.exp(y) - r += z * r - if absx < 140.: - r *= math.pow(y, absx - .5) - else: - sqrtpow = math.pow(y, absx / 2. - .25) - r *= sqrtpow - r *= sqrtpow - if rfloat.isinf(r): - raise OverflowError("math range error") - return r - -def _lgamma(x): - if rfloat.isnan(x): - return x - if rfloat.isinf(x): - return rfloat.INFINITY - if x == math.floor(x) and x <= 2.: - if x <= 0.: - raise ValueError("math range error") - return 0. - absx = abs(x) - if absx < 1e-20: - return -math.log(absx) - if x > 0.: - r = (math.log(_lanczos_sum(x)) - _lanczos_g + (x - .5) * - (math.log(x + _lanczos_g - .5) - 1)) - else: - r = (math.log(math.pi) - math.log(abs(_sinpi(absx))) - math.log(absx) - - (math.log(_lanczos_sum(absx)) - _lanczos_g + - (absx - .5) * (math.log(absx + _lanczos_g - .5) - 1))) - if rfloat.isinf(r): - raise OverflowError("math domain error") - return r diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -170,139 +170,6 @@ raises(ValueError, math.atanh, 1.) assert math.isnan(math.atanh(float("nan"))) - def test_mtestfile(self): - import math - import zipfile - import os - import struct - def _parse_mtestfile(fname): - """Parse a file with test values - - -- starts a comment - blank lines, or lines containing only a comment, are ignored - other lines are expected to have the form - id fn arg -> expected [flag]* - - """ - with open(fname) as fp: - for line in fp: - # strip comments, and skip blank lines - if '--' in line: - line = line[:line.index('--')] - if not line.strip(): - continue - - lhs, rhs = line.split('->') - id, fn, arg = lhs.split() - rhs_pieces = rhs.split() - exp = rhs_pieces[0] - flags = rhs_pieces[1:] - - yield (id, fn, float(arg), float(exp), flags) - def to_ulps(x): - """Convert a non-NaN float x to an integer, in such a way that - adjacent floats are converted to adjacent integers. Then - abs(ulps(x) - ulps(y)) gives the difference in ulps between two - floats. - - The results from this function will only make sense on platforms - where C doubles are represented in IEEE 754 binary64 format. - - """ - n = struct.unpack('= ERFC_CONTFRAC_CUTOFF: + return 0. + x2 = x * x + a = 0. + da = .5 + p = 1. + p_last = 0. + q = da + x2 + q_last = 1. + for i in range(ERFC_CONTFRAC_TERMS): + a += da + da += 2. + b = da + x2 + p_last, p = p, b * p - a * p_last + q_last, q = q, b * q - a * q_last + return p / q * x * math.exp(-x2) / _sqrtpi + +def erf(x): + """The error function at x.""" + if isnan(x): + return x + absx = abs(x) + if absx < ERF_SERIES_CUTOFF: + return _erf_series(x) + else: + cf = _erfc_contfrac(absx) + return 1. - cf if x > 0. else cf - 1. + +def erfc(x): + """The complementary error function at x.""" + if isnan(x): + return x + absx = abs(x) + if absx < ERF_SERIES_CUTOFF: + return 1. - _erf_series(x) + else: + cf = _erfc_contfrac(absx) + return cf if x > 0. else 2. - cf + +def _sinpi(x): + y = math.fmod(abs(x), 2.) + n = int(round_away(2. * y)) + if n == 0: + r = math.sin(math.pi * y) + elif n == 1: + r = math.cos(math.pi * (y - .5)) + elif n == 2: + r = math.sin(math.pi * (1. - y)) + elif n == 3: + r = -math.cos(math.pi * (y - 1.5)) + elif n == 4: + r = math.sin(math.pi * (y - 2.)) + else: + raise AssertionError("should not reach") + return copysign(1., x) * r + +_lanczos_g = 6.024680040776729583740234375 +_lanczos_g_minus_half = 5.524680040776729583740234375 +_lanczos_num_coeffs = [ + 23531376880.410759688572007674451636754734846804940, + 42919803642.649098768957899047001988850926355848959, + 35711959237.355668049440185451547166705960488635843, + 17921034426.037209699919755754458931112671403265390, + 6039542586.3520280050642916443072979210699388420708, + 1439720407.3117216736632230727949123939715485786772, + 248874557.86205415651146038641322942321632125127801, + 31426415.585400194380614231628318205362874684987640, + 2876370.6289353724412254090516208496135991145378768, + 186056.26539522349504029498971604569928220784236328, + 8071.6720023658162106380029022722506138218516325024, + 210.82427775157934587250973392071336271166969580291, + 2.5066282746310002701649081771338373386264310793408 +] +_lanczos_den_coeffs = [ + 0.0, 39916800.0, 120543840.0, 150917976.0, 105258076.0, 45995730.0, + 13339535.0, 2637558.0, 357423.0, 32670.0, 1925.0, 66.0, 1.0] +LANCZOS_N = len(_lanczos_den_coeffs) +_lanczos_n_iter = unroll.unrolling_iterable(range(LANCZOS_N)) +_lanczos_n_iter_back = unroll.unrolling_iterable(range(LANCZOS_N - 1, -1, -1)) +_gamma_integrals = [ + 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, + 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0, + 1307674368000.0, 20922789888000.0, 355687428096000.0, + 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0, + 51090942171709440000.0, 1124000727777607680000.0] + +def _lanczos_sum(x): + num = 0. + den = 0. + assert x > 0. + if x < 5.: + for i in _lanczos_n_iter_back: + num = num * x + _lanczos_num_coeffs[i] + den = den * x + _lanczos_den_coeffs[i] + else: + for i in _lanczos_n_iter: + num = num / x + _lanczos_num_coeffs[i] + den = den / x + _lanczos_den_coeffs[i] + return num / den + +def gamma(x): + """Compute the gamma function for x.""" + if isnan(x) or (isinf(x) and x > 0.): + return x + if isinf(x): + raise ValueError("math domain error") + if x == 0.: + raise ValueError("math domain error") + if x == math.floor(x): + if x < 0.: + raise ValueError("math domain error") + if x < len(_gamma_integrals): + return _gamma_integrals[int(x) - 1] + absx = abs(x) + if absx < 1e-20: + r = 1. / x + if isinf(r): + raise OverflowError("math range error") + return r + if absx > 200.: + if x < 0.: + return 0. / -_sinpi(x) + else: + raise OverflowError("math range error") + y = absx + _lanczos_g_minus_half + if absx > _lanczos_g_minus_half: + q = y - absx + z = q - _lanczos_g_minus_half + else: + q = y - _lanczos_g_minus_half + z = q - absx + z = z * _lanczos_g / y + if x < 0.: + r = -math.pi / _sinpi(absx) / absx * math.exp(y) / _lanczos_sum(absx) + r -= z * r + if absx < 140.: + r /= math.pow(y, absx - .5) + else: + sqrtpow = math.pow(y, absx / 2. - .25) + r /= sqrtpow + r /= sqrtpow + else: + r = _lanczos_sum(absx) / math.exp(y) + r += z * r + if absx < 140.: + r *= math.pow(y, absx - .5) + else: + sqrtpow = math.pow(y, absx / 2. - .25) + r *= sqrtpow + r *= sqrtpow + if isinf(r): + raise OverflowError("math range error") + return r + +def lgamma(x): + """Compute the natural logarithm of the gamma function for x.""" + if isnan(x): + return x + if isinf(x): + return INFINITY + if x == math.floor(x) and x <= 2.: + if x <= 0.: + raise ValueError("math range error") + return 0. + absx = abs(x) + if absx < 1e-20: + return -math.log(absx) + if x > 0.: + r = (math.log(_lanczos_sum(x)) - _lanczos_g + (x - .5) * + (math.log(x + _lanczos_g - .5) - 1)) + else: + r = (math.log(math.pi) - math.log(abs(_sinpi(absx))) - math.log(absx) - + (math.log(_lanczos_sum(absx)) - _lanczos_g + + (absx - .5) * (math.log(absx + _lanczos_g - .5) - 1))) + if isinf(r): + raise OverflowError("math domain error") + return r + + +def to_ulps(x): + """Convert a non-NaN float x to an integer, in such a way that + adjacent floats are converted to adjacent integers. Then + abs(ulps(x) - ulps(y)) gives the difference in ulps between two + floats. + + The results from this function will only make sense on platforms + where C doubles are represented in IEEE 754 binary64 format. + + """ + n = struct.unpack(' expected [flag]* + + """ + with open(fname) as fp: + for line in fp: + # strip comments, and skip blank lines + if '--' in line: + line = line[:line.index('--')] + if not line.strip(): + continue + + lhs, rhs = line.split('->') + id, fn, arg = lhs.split() + rhs_pieces = rhs.split() + exp = rhs_pieces[0] + flags = rhs_pieces[1:] + + yield (id, fn, float(arg), float(exp), flags) + + ALLOWED_ERROR = 20 # permitted error, in ulps + fail_fmt = "{}:{}({!r}): expected {!r}, got {!r}" + + failures = [] + math_testcases = os.path.join(os.path.dirname(__file__), + "math_testcases.txt") + for id, fn, arg, expected, flags in _parse_mtestfile(math_testcases): + func = getattr(rfloat, fn) + + if 'invalid' in flags or 'divide-by-zero' in flags: + expected = 'ValueError' + elif 'overflow' in flags: + expected = 'OverflowError' + + try: + got = func(arg) + except ValueError: + got = 'ValueError' + except OverflowError: + got = 'OverflowError' + + accuracy_failure = None + if isinstance(got, float) and isinstance(expected, float): + if isnan(expected) and isnan(got): + continue + if not isnan(expected) and not isnan(got): + if fn == 'lgamma': + # we use a weaker accuracy test for lgamma; + # lgamma only achieves an absolute error of + # a few multiples of the machine accuracy, in + # general. + accuracy_failure = acc_check(expected, got, + rel_err = 5e-15, + abs_err = 5e-15) + elif fn == 'erfc': + # erfc has less-than-ideal accuracy for large + # arguments (x ~ 25 or so), mainly due to the + # error involved in computing exp(-x*x). + # + # XXX Would be better to weaken this test only + # for large x, instead of for all x. + accuracy_failure = ulps_check(expected, got, 2000) + + else: + accuracy_failure = ulps_check(expected, got, 20) + if accuracy_failure is None: + continue + + if isinstance(got, str) and isinstance(expected, str): + if got == expected: + continue + + fail_msg = fail_fmt.format(id, fn, arg, expected, got) + if accuracy_failure is not None: + fail_msg += ' ({})'.format(accuracy_failure) + failures.append(fail_msg) + assert not failures + + +def test_gamma_overflow_translated(): + from rpython.translator.c.test.test_genc import compile + def wrapper(arg): + try: + return gamma(arg) + except OverflowError: + return -42 + + f = compile(wrapper, [float]) + assert f(10.0) == 362880.0 + assert f(1720.0) == -42 + assert f(172.0) == -42 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 @@ -302,6 +302,7 @@ b.chars[i] = str.chars[i] return b + @jit.look_inside_iff(lambda s: jit.isvirtual(s)) @jit.elidable def ll_strhash(s): # unlike CPython, there is no reason to avoid to return -1 diff --git a/rpython/translator/backendopt/merge_if_blocks.py b/rpython/translator/backendopt/merge_if_blocks.py --- a/rpython/translator/backendopt/merge_if_blocks.py +++ b/rpython/translator/backendopt/merge_if_blocks.py @@ -9,8 +9,10 @@ if len(block.operations) > 1 and not first: return False op = block.operations[-1] - if (op.opname not in ('int_eq', 'uint_eq', 'llong_eq', 'ullong_eq', - 'char_eq', 'unichar_eq') + if (op.opname not in ('int_eq', 'uint_eq', 'char_eq', 'unichar_eq') + # note: 'llong_eq', 'ullong_eq' have been removed, as it's not + # strictly C-compliant to do a switch() on a long long. It also + # crashes the JIT, and it's very very rare anyway. or op.result != block.exitswitch): return False if isinstance(op.args[0], Variable) and isinstance(op.args[1], Variable): diff --git a/rpython/translator/backendopt/test/test_merge_if_blocks.py b/rpython/translator/backendopt/test/test_merge_if_blocks.py --- a/rpython/translator/backendopt/test/test_merge_if_blocks.py +++ b/rpython/translator/backendopt/test/test_merge_if_blocks.py @@ -38,9 +38,10 @@ return 4 do_test_merge(merge_int, range(4)) do_test_merge(merge_int, [r_uint(i) for i in range(4)]) - if r_longlong is not r_int: - do_test_merge(merge_int, [r_longlong(i) for i in range(4)]) - do_test_merge(merge_int, [r_ulonglong(i) for i in range(4)]) + # this has been disabled: + #if r_longlong is not r_int: + # do_test_merge(merge_int, [r_longlong(i) for i in range(4)]) + #do_test_merge(merge_int, [r_ulonglong(i) for i in range(4)]) def merge_chr(n): c = chr(n + 1) diff --git a/rpython/translator/jvm/test/test_int.py b/rpython/translator/jvm/test/test_int.py --- a/rpython/translator/jvm/test/test_int.py +++ b/rpython/translator/jvm/test/test_int.py @@ -16,5 +16,8 @@ def test_rarithmetic(self): pass # does this make more sense in jvm + + def test_str_of_uint(self): + py.test.skip("we don't care") div_mod_iteration_count = 20 diff --git a/rpython/translator/platform/netbsd.py b/rpython/translator/platform/netbsd.py --- a/rpython/translator/platform/netbsd.py +++ b/rpython/translator/platform/netbsd.py @@ -18,7 +18,9 @@ class Netbsd(posix.BasePosix): name = "netbsd" - link_flags = ['-pthread'] + get_env_vector('LDFLAGS', '') + link_flags = ['-pthread', + '-Wl,-R' + get_env("LOCALBASE", "/usr/pkg") + '/lib' + ] + get_env_vector('LDFLAGS', '') cflags = ['-O3', '-pthread', '-fomit-frame-pointer' ] + get_env_vector('CFLAGS', '') standalone_only = [] diff --git a/rpython/translator/sandbox/test/test_sandlib.py b/rpython/translator/sandbox/test/test_sandlib.py --- a/rpython/translator/sandbox/test/test_sandlib.py +++ b/rpython/translator/sandbox/test/test_sandlib.py @@ -106,7 +106,7 @@ pass def entry_point(argv): - fd = os.open("tcp://pypy.org:80", os.O_RDONLY, 0777) + fd = os.open("tcp://python.org:80", os.O_RDONLY, 0777) os.write(fd, 'GET /\n') print os.read(fd, 30) return 0 diff --git a/rpython/translator/tool/graphpage.py b/rpython/translator/tool/graphpage.py --- a/rpython/translator/tool/graphpage.py +++ b/rpython/translator/tool/graphpage.py @@ -425,6 +425,8 @@ if block not in seen: pending.append(block) seen[block] = True + elif isinstance(y, dict): + pending.append(y) # go back from the dict to the real obj graph = IncompleteGraph(pending) SingleGraphPage(graph).display() else: From noreply at buildbot.pypy.org Sun Mar 3 18:05:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 3 Mar 2013 18:05:06 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Change "stuff" with the goal of fixing a bug in W_Continulet. Message-ID: <20130303170506.613651C034F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61953:da3bcd418b5c Date: 2013-03-03 17:14 +0100 http://bitbucket.org/pypy/pypy/changeset/da3bcd418b5c/ Log: Change "stuff" with the goal of fixing a bug in W_Continulet. The problem is that __del__ can call stacklet_destroy() too early. * removed __del__ from W_Continulet, and instead add it as a lower level destructor on the 'sthread' object * kill destroy() from various levels, because it is not needed any more * we can't pass any more the thread_handle to stacklet.c, so kill it and store it in the stacklet_handle. Fix a problem related to freeing the thread_handle before the remaining stacklet_handle's. * bad luck: this means the sthread objects need both a custom tracer and a destructor. Fix everything to accomodate that. * this lets us kill the unused second argument from the low-level destructor functions diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -19,11 +19,6 @@ # - normal: self.sthread != None, not is_empty_handle(self.h) # - finished: self.sthread != None, is_empty_handle(self.h) - def __del__(self): - sthread = self.sthread - if sthread is not None and not sthread.is_empty_handle(self.h): - sthread.destroy(self.h) - def check_sthread(self): ec = self.space.getexecutioncontext() if ec.stacklet_thread is not self.sthread: diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -341,7 +341,7 @@ break obj = self.run_finalizers.popleft() finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj, llmemory.NULL) + finalizer(obj) finally: self.finalizer_lock_count -= 1 diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1890,7 +1890,7 @@ if not self.is_forwarded(obj): finalizer = self.getlightfinalizer(self.get_type_id(obj)) ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + finalizer(obj) else: obj = self.get_forwarding_address(obj) self.old_objects_with_light_finalizers.append(obj) @@ -1911,7 +1911,7 @@ # dying finalizer = self.getlightfinalizer(self.get_type_id(obj)) ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + finalizer(obj) self.old_objects_with_light_finalizers.delete() self.old_objects_with_light_finalizers = new_objects diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py --- a/rpython/memory/gc/semispace.py +++ b/rpython/memory/gc/semispace.py @@ -494,7 +494,7 @@ new_objects.append(self.get_forwarding_address(obj)) else: finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj, llmemory.NULL) + finalizer(obj) self.objects_with_light_finalizers.delete() self.objects_with_light_finalizers = new_objects diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -645,11 +645,9 @@ c_type_id = rmodel.inputconst(TYPE_ID, type_id) info = self.layoutbuilder.get_info(type_id) c_size = rmodel.inputconst(lltype.Signed, info.fixedsize) - kind_and_fptr = self.special_funcptr_for_type(TYPE) - has_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "finalizer") - has_light_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "light_finalizer") + fptrs = self.special_funcptr_for_type(TYPE) + has_finalizer = "finalizer" in fptrs + has_light_finalizer = "light_finalizer" in fptrs if has_light_finalizer: has_finalizer = True c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer) @@ -798,11 +796,6 @@ [self.root_walker.gc_shadowstackref_context_ptr, op.args[0]], resultvar=op.result) - def gct_gc_shadowstackref_destroy(self, hop): - op = hop.spaceop - hop.genop("direct_call", - [self.root_walker.gc_shadowstackref_destroy_ptr, op.args[0]]) - def gct_gc_save_current_state_away(self, hop): op = hop.spaceop hop.genop("direct_call", @@ -1213,8 +1206,8 @@ None) def has_light_finalizer(self, TYPE): - special = self.special_funcptr_for_type(TYPE) - return special is not None and special[0] == 'light_finalizer' + fptrs = self.special_funcptr_for_type(TYPE) + return "light_finalizer" in fptrs def has_custom_trace(self, TYPE): rtti = get_rtti(TYPE) @@ -1228,13 +1221,20 @@ destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] typename = TYPE.__name__ - def ll_finalizer(addr, ignored): + def ll_finalizer(addr): v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) - return llmemory.NULL fptr = self.transformer.annotate_finalizer(ll_finalizer, - [llmemory.Address, llmemory.Address], llmemory.Address) - g = destrptr._obj.graph + [llmemory.Address], lltype.Void) + try: + g = destrptr._obj.graph + except AttributeError: + # hack hack hack + self.transformer.annotate_finalizer( + destrptr._obj._callable, [DESTR_ARG], lltype.Void) + g = self.transformer._last_annotated_graph + destrptr._obj.__dict__['graph'] = g + # light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) return fptr, light diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -226,10 +226,6 @@ ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) return ssref.context - def gc_shadowstackref_destroy(gcref): - ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) - shadow_stack_pool.destroy(ssref) - def gc_save_current_state_away(gcref, ncontext): ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) shadow_stack_pool.save_current_state_away(ssref, ncontext) @@ -252,9 +248,6 @@ self.gc_shadowstackref_context_ptr = getfn(gc_shadowstackref_context, [s_gcref], s_addr, inline=True) - self.gc_shadowstackref_destroy_ptr = getfn(gc_shadowstackref_destroy, - [s_gcref], annmodel.s_None, - inline=True) self.gc_save_current_state_away_ptr = getfn(gc_save_current_state_away, [s_gcref, s_addr], annmodel.s_None, @@ -340,10 +333,6 @@ self.gcdata.root_stack_top = self.unused_full_stack self.unused_full_stack = llmemory.NULL - def destroy(self, shadowstackref): - llmemory.raw_free(shadowstackref.base) - self._cleanup(shadowstackref) - def _cleanup(self, shadowstackref): shadowstackref.base = llmemory.NULL shadowstackref.top = llmemory.NULL @@ -402,7 +391,20 @@ CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) - lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr) + + def shadowstack_destructor(shadowstackref): + from rpython.rlib import _rffi_stacklet as _c + h = shadowstackref.context + h = llmemory.cast_adr_to_ptr(h, _c.handle) + llmemory.raw_free(shadowstackref.base) + if h: + _c.destroy(h) + + DESTRFUNC = lltype.FuncType([SHADOWSTACKREFPTR], lltype.Void) + destrptr = llhelper(lltype.Ptr(DESTRFUNC), shadowstack_destructor) + + lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr, + destrptr=destrptr) gctransformer._SHADOWSTACKREF = SHADOWSTACKREF return SHADOWSTACKREF diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py --- a/rpython/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -267,6 +267,7 @@ if inline: self.graphs_to_inline[graph] = True FUNCTYPE = lltype.FuncType(ll_args, ll_result) + self._last_annotated_graph = graph return self.mixlevelannotator.graph2delayed(graph, FUNCTYPE=FUNCTYPE) def inittime_helper(self, ll_helper, ll_args, ll_result, inline=True): diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -17,20 +17,22 @@ OFFSETS_TO_GC_PTR = lltype.Array(lltype.Signed) - # When used as a finalizer, the following functions only take one - # address and ignore the second, and return NULL. When used as a - # custom tracer (CT), it enumerates the addresses that contain GCREFs. + # A custom tracer (CT), enumerates the addresses that contain GCREFs. # It is called with the object as first argument, and the previous # returned address (or NULL the first time) as the second argument. - FINALIZER_OR_CT_FUNC = lltype.FuncType([llmemory.Address, - llmemory.Address], - llmemory.Address) - FINALIZER_OR_CT = lltype.Ptr(FINALIZER_OR_CT_FUNC) + FINALIZER_FUNC = lltype.FuncType([llmemory.Address], lltype.Void) + CUSTOMTRACER_FUNC = lltype.FuncType([llmemory.Address, llmemory.Address], + llmemory.Address) + FINALIZER = lltype.Ptr(FINALIZER_FUNC) + CUSTOMTRACER = lltype.Ptr(CUSTOMTRACER_FUNC) + EXTRA = lltype.Struct("type_info_extra", + ('finalizer', FINALIZER), + ('customtracer', CUSTOMTRACER)) # structure describing the layout of a typeid TYPE_INFO = lltype.Struct("type_info", ("infobits", lltype.Signed), # combination of the T_xxx consts - ("finalizer_or_customtrace", FINALIZER_OR_CT), + ("extra", lltype.Ptr(EXTRA)), ("fixedsize", lltype.Signed), ("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)), hints={'immutable': True}, @@ -80,16 +82,16 @@ def q_finalizer(self, typeid): typeinfo = self.get(typeid) if typeinfo.infobits & T_HAS_FINALIZER: - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.finalizer else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.FINALIZER_FUNC) def q_light_finalizer(self, typeid): typeinfo = self.get(typeid) if typeinfo.infobits & T_HAS_LIGHTWEIGHT_FINALIZER: - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.finalizer else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.FINALIZER_FUNC) def q_offsets_to_gc_pointers(self, typeid): return self.get(typeid).ofstoptrs @@ -131,7 +133,7 @@ ll_assert(self.q_has_custom_trace(typeid), "T_HAS_CUSTOM_TRACE missing") typeinfo = self.get(typeid) - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.customtracer def q_fast_path_tracing(self, typeid): # return True if none of the flags T_HAS_GCPTR_IN_VARSIZE, @@ -196,18 +198,20 @@ infobits = index info.ofstoptrs = builder.offsets2table(offsets, TYPE) # - kind_and_fptr = builder.special_funcptr_for_type(TYPE) - if kind_and_fptr is not None: - kind, fptr = kind_and_fptr - info.finalizer_or_customtrace = fptr - if kind == "finalizer": + fptrs = builder.special_funcptr_for_type(TYPE) + if fptrs: + extra = lltype.malloc(GCData.EXTRA, zero=True, immortal=True, + flavor='raw') + if "finalizer" in fptrs: + extra.finalizer = fptrs["finalizer"] infobits |= T_HAS_FINALIZER - elif kind == 'light_finalizer': + if "light_finalizer" in fptrs: + extra.finalizer = fptrs["light_finalizer"] infobits |= T_HAS_FINALIZER | T_HAS_LIGHTWEIGHT_FINALIZER - elif kind == "custom_trace": + if "custom_trace" in fptrs: + extra.customtracer = fptrs["custom_trace"] infobits |= T_HAS_CUSTOM_TRACE - else: - assert 0, kind + info.extra = extra # if not TYPE._is_varsize(): info.fixedsize = llarena.round_up_for_allocation( @@ -379,19 +383,16 @@ return self._special_funcptrs[TYPE] fptr1, is_lightweight = self.make_finalizer_funcptr_for_type(TYPE) fptr2 = self.make_custom_trace_funcptr_for_type(TYPE) - assert not (fptr1 and fptr2), ( - "type %r needs both a finalizer and a custom tracer" % (TYPE,)) + result = {} if fptr1: if is_lightweight: - kind_and_fptr = "light_finalizer", fptr1 + result["light_finalizer"] = fptr1 else: - kind_and_fptr = "finalizer", fptr1 - elif fptr2: - kind_and_fptr = "custom_trace", fptr2 - else: - kind_and_fptr = None - self._special_funcptrs[TYPE] = kind_and_fptr - return kind_and_fptr + result["finalizer"] = fptr1 + if fptr2: + result["custom_trace"] = fptr2 + self._special_funcptrs[TYPE] = result + return result def make_finalizer_funcptr_for_type(self, TYPE): # must be overridden for proper finalizer support diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -216,16 +216,14 @@ t = self.llinterp.typer.annotator.translator light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) - def ll_finalizer(addr, dummy): - assert dummy == llmemory.NULL + def ll_finalizer(addr): try: v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) self.llinterp.eval_graph(destrgraph, [v], recursive=True) except llinterp.LLException: raise RuntimeError( "a finalizer raised an exception, shouldn't happen") - return llmemory.NULL - return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light + return llhelper(gctypelayout.GCData.FINALIZER, ll_finalizer), light def make_custom_trace_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti diff --git a/rpython/rlib/_rffi_stacklet.py b/rpython/rlib/_rffi_stacklet.py --- a/rpython/rlib/_rffi_stacklet.py +++ b/rpython/rlib/_rffi_stacklet.py @@ -56,9 +56,9 @@ new = llexternal('stacklet_new', [thread_handle, run_fn, llmemory.Address], handle, random_effects_on_gcobjs=True) -switch = llexternal('stacklet_switch', [thread_handle, handle], handle, +switch = llexternal('stacklet_switch', [handle], handle, random_effects_on_gcobjs=True) -destroy = llexternal('stacklet_destroy', [thread_handle, handle], lltype.Void) +destroy = llexternal('stacklet_destroy', [handle], lltype.Void) _translate_pointer = llexternal("_stacklet_translate_pointer", [llmemory.Address, llmemory.Address], diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -134,6 +134,11 @@ stackletrootwalker = get_stackletrootwalker() return stackletrootwalker.next(obj, prev) +def suspstack_destructor(suspstack): + h = suspstack.handle + if h: + _c.destroy(h) + SUSPSTACK = lltype.GcStruct('SuspStack', ('handle', _c.handle), @@ -143,7 +148,12 @@ CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) -lltype.attachRuntimeTypeInfo(SUSPSTACK, customtraceptr=customtraceptr) + +DESTRFUNC = lltype.FuncType([lltype.Ptr(SUSPSTACK)], lltype.Void) +destrptr = llhelper(lltype.Ptr(DESTRFUNC), suspstack_destructor) + +lltype.attachRuntimeTypeInfo(SUSPSTACK, customtraceptr=customtraceptr, + destrptr=destrptr) ASM_FRAMEDATA_HEAD_PTR = lltype.Ptr(lltype.ForwardReference()) ASM_FRAMEDATA_HEAD_PTR.TO.become(lltype.Struct('ASM_FRAMEDATA_HEAD', @@ -169,7 +179,7 @@ # stacklet with stacklet_new(). If this call fails, then we # are just returning NULL. _stack_just_closed() - return _c.new(gcrootfinder.thrd, llhelper(_c.run_fn, _new_runfn), + return _c.new(gcrootfinder.newthrd, llhelper(_c.run_fn, _new_runfn), llmemory.NULL) def _stack_just_closed(): @@ -216,7 +226,7 @@ # # gcrootfinder.suspstack.anchor is left with the anchor of the # previous place (i.e. before the call to switch()). - h2 = _c.switch(gcrootfinder.thrd, h) + h2 = _c.switch(h) # if not h2: # MemoryError: restore gcrootfinder.suspstack.anchor = oldanchor @@ -228,7 +238,7 @@ suspstack = NULL_SUSPSTACK def new(self, thrd, callback, arg): - self.thrd = thrd._thrd + self.newthrd = thrd._thrd self.runfn = callback self.arg = arg # make a fresh new clean SUSPSTACK @@ -240,8 +250,7 @@ alternateanchor) return self.get_result_suspstack(h) - def switch(self, thrd, suspstack): - self.thrd = thrd._thrd + def switch(self, suspstack): self.suspstack = suspstack h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _switch_callback), alternateanchor) @@ -267,11 +276,6 @@ # This is a return that gave us a real handle. Store it. return self.attach_handle_on_suspstack(h) - def destroy(self, thrd, suspstack): - h = suspstack.handle - suspstack.handle = _c.null_handle - _c.destroy(thrd._thrd, h) - def is_empty_handle(self, suspstack): return not suspstack diff --git a/rpython/rlib/_stacklet_shadowstack.py b/rpython/rlib/_stacklet_shadowstack.py --- a/rpython/rlib/_stacklet_shadowstack.py +++ b/rpython/rlib/_stacklet_shadowstack.py @@ -79,25 +79,18 @@ return get_result_suspstack(h) new._dont_inline_ = True - def switch(thrd, suspstack): + def switch(suspstack): # suspstack has a handle to target, i.e. where to switch to ll_assert(suspstack != gcrootfinder.oldsuspstack, "stacklet: invalid use") gcrootfinder.newsuspstack = suspstack - thread_handle = thrd._thrd h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) h = llmemory.cast_adr_to_ptr(h, _c.handle) prepare_old_suspstack() - h = _c.switch(thread_handle, h) + h = _c.switch(h) return get_result_suspstack(h) switch._dont_inline_ = True - def destroy(thrd, suspstack): - h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) - h = llmemory.cast_adr_to_ptr(h, _c.handle) - llop.gc_shadowstackref_destroy(lltype.Void, suspstack) - _c.destroy(thrd._thrd, h) - def is_empty_handle(suspstack): return not suspstack diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py --- a/rpython/rlib/rstacklet.py +++ b/rpython/rlib/rstacklet.py @@ -34,17 +34,11 @@ def switch(self, stacklet): if DEBUG: debug.remove(stacklet) - h = self._gcrootfinder.switch(self, stacklet) + h = self._gcrootfinder.switch(stacklet) if DEBUG: debug.add(h) return h - @jit.dont_look_inside - def destroy(self, stacklet): - if DEBUG: - debug.remove(stacklet) - self._gcrootfinder.destroy(self, stacklet) - def is_empty_handle(self, stacklet): # note that "being an empty handle" and being equal to # "get_null_handle()" may be the same, or not; don't rely on it diff --git a/rpython/rlib/test/test_rstacklet.py b/rpython/rlib/test/test_rstacklet.py --- a/rpython/rlib/test/test_rstacklet.py +++ b/rpython/rlib/test/test_rstacklet.py @@ -6,7 +6,7 @@ except CompilationError, e: py.test.skip("cannot import rstacklet: %s" % e) -from rpython.rlib import rrandom +from rpython.rlib import rrandom, rgc from rpython.rlib.rarithmetic import intmask from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.c.test.test_standalone import StandaloneTests @@ -72,7 +72,9 @@ self.status = 0 h = self.sthread.new(switchbackonce_callback, rffi.cast(llmemory.Address, 321)) - self.sthread.destroy(h) + # 'h' ignored + if (i % 5000) == 2500: + rgc.collect() def any_alive(self): for task in self.tasks: diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -890,8 +890,6 @@ raise NotImplementedError("gc_shadowstackref_new") def op_gc_shadowstackref_context(self): raise NotImplementedError("gc_shadowstackref_context") - def op_gc_shadowstackref_destroy(self): - raise NotImplementedError("gc_shadowstackref_destroy") def op_gc_save_current_state_away(self): raise NotImplementedError("gc_save_current_state_away") def op_gc_forget_current_state(self): diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -518,7 +518,6 @@ # for stacklet+shadowstack support 'gc_shadowstackref_new': LLOp(canmallocgc=True), 'gc_shadowstackref_context': LLOp(), - 'gc_shadowstackref_destroy': LLOp(), 'gc_save_current_state_away': LLOp(), 'gc_forget_current_state': LLOp(), 'gc_restore_state_from': LLOp(), diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py --- a/rpython/translator/c/gc.py +++ b/rpython/translator/c/gc.py @@ -313,19 +313,19 @@ def struct_setup(self, structdefnode, rtti): if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): - destrptr = rtti._obj.destructor_funcptr + gctransf = self.db.gctransformer + TYPE = structdefnode.STRUCT + fptrs = gctransf.special_funcptr_for_type(TYPE) # make sure this is seen by the database early, i.e. before # finish_helpers() on the gctransformer - self.db.get(destrptr) + #destrptr = rtti._obj.destructor_funcptr + #self.db.get(destrptr) # the following, on the other hand, will only discover ll_finalizer # helpers. The get() sees and records a delayed pointer. It is # still important to see it so that it can be followed as soon as # the mixlevelannotator resolves it. - gctransf = self.db.gctransformer - TYPE = structdefnode.STRUCT - kind_and_fptr = gctransf.special_funcptr_for_type(TYPE) - if kind_and_fptr: - self.db.get(kind_and_fptr[1]) + for fptr in fptrs.values(): + self.db.get(fptr) def array_setup(self, arraydefnode): pass diff --git a/rpython/translator/c/src/stacklet/stacklet.c b/rpython/translator/c/src/stacklet/stacklet.c --- a/rpython/translator/c/src/stacklet/stacklet.c +++ b/rpython/translator/c/src/stacklet/stacklet.c @@ -52,6 +52,8 @@ * main stack. */ struct stacklet_s *stack_prev; + + stacklet_thread_handle stack_thrd; /* the thread where the stacklet is */ }; void *(*_stacklet_switchstack)(void*(*)(void*, void*), @@ -132,6 +134,7 @@ stacklet->stack_stop = thrd->g_current_stack_stop; stacklet->stack_saved = 0; stacklet->stack_prev = thrd->g_stack_chain_head; + stacklet->stack_thrd = thrd; thrd->g_stack_chain_head = stacklet; return 0; } @@ -293,10 +296,10 @@ return thrd->g_source; } -stacklet_handle stacklet_switch(stacklet_thread_handle thrd, - stacklet_handle target) +stacklet_handle stacklet_switch(stacklet_handle target) { long stackmarker; + stacklet_thread_handle thrd = target->stack_thrd; if (thrd->g_current_stack_stop <= (char *)&stackmarker) thrd->g_current_stack_stop = ((char *)&stackmarker) + 1; @@ -305,15 +308,23 @@ return thrd->g_source; } -void stacklet_destroy(stacklet_thread_handle thrd, stacklet_handle target) +void stacklet_destroy(stacklet_handle target) { - /* remove 'target' from the chained list 'unsaved_stack', if it is there */ - struct stacklet_s **pp = &thrd->g_stack_chain_head; - for (; *pp != NULL; pp = &(*pp)->stack_prev) - if (*pp == target) { - *pp = target->stack_prev; - break; - } + if (target->stack_prev != NULL) { + /* 'target' appears to be in the chained list 'unsaved_stack', + so remove it from there. Note that if 'thrd' was already + deleted, it means that we left the thread and all stacklets + still in the thread should be fully copied away from the + stack --- so should have stack_prev == NULL. In this case + we don't even read 'stack_thrd', already deallocated. */ + stacklet_thread_handle thrd = target->stack_thrd; + struct stacklet_s **pp = &thrd->g_stack_chain_head; + for (; *pp != NULL; pp = &(*pp)->stack_prev) + if (*pp == target) { + *pp = target->stack_prev; + break; + } + } free(target); } diff --git a/rpython/translator/c/src/stacklet/stacklet.h b/rpython/translator/c/src/stacklet/stacklet.h --- a/rpython/translator/c/src/stacklet/stacklet.h +++ b/rpython/translator/c/src/stacklet/stacklet.h @@ -44,13 +44,12 @@ * Don't call this with an already-used target, with EMPTY_STACKLET_HANDLE, * or with a stack handle from another thread (in multithreaded apps). */ -stacklet_handle stacklet_switch(stacklet_thread_handle thrd, - stacklet_handle target); +stacklet_handle stacklet_switch(stacklet_handle target); /* Delete a stack handle without resuming it at all. * (This works even if the stack handle is of a different thread) */ -void stacklet_destroy(stacklet_thread_handle thrd, stacklet_handle target); +void stacklet_destroy(stacklet_handle target); /* stacklet_handle _stacklet_switch_to_copy(stacklet_handle) --- later */ From noreply at buildbot.pypy.org Sun Mar 3 18:05:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 3 Mar 2013 18:05:07 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Move the hacks around until it seems to work Message-ID: <20130303170507.86B131C034F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61954:dc7053edd681 Date: 2013-03-03 18:03 +0100 http://bitbucket.org/pypy/pypy/changeset/dc7053edd681/ Log: Move the hacks around until it seems to work 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 @@ -139,6 +139,7 @@ if self._with_jit: jit2gc = gctransformer.translator._jit2gc self.frame_tid = jit2gc['frame_tid'] + self.gctransformer = gctransformer def need_stacklet_support(self, gctransformer, getfn): # stacklet support: BIG HACK for rlib.rstacklet diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -1228,14 +1228,9 @@ [llmemory.Address], lltype.Void) try: g = destrptr._obj.graph - except AttributeError: - # hack hack hack - self.transformer.annotate_finalizer( - destrptr._obj._callable, [DESTR_ARG], lltype.Void) - g = self.transformer._last_annotated_graph - destrptr._obj.__dict__['graph'] = g - # - light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) + light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) + except lltype.DelayedPointer: + light = False # XXX bah, too bad return fptr, light def make_custom_trace_funcptr_for_type(self, TYPE): diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -1,6 +1,7 @@ from rpython.annotator import model as annmodel from rpython.rlib.debug import ll_assert from rpython.rlib.nonconst import NonConstant +from rpython.rlib import rgc from rpython.rtyper import rmodel from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, llmemory @@ -400,8 +401,8 @@ if h: _c.destroy(h) - DESTRFUNC = lltype.FuncType([SHADOWSTACKREFPTR], lltype.Void) - destrptr = llhelper(lltype.Ptr(DESTRFUNC), shadowstack_destructor) + destrptr = gctransformer.annotate_helper(shadowstack_destructor, + [SHADOWSTACKREFPTR], lltype.Void) lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr, destrptr=destrptr) diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py --- a/rpython/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -267,7 +267,6 @@ if inline: self.graphs_to_inline[graph] = True FUNCTYPE = lltype.FuncType(ll_args, ll_result) - self._last_annotated_graph = graph return self.mixlevelannotator.graph2delayed(graph, FUNCTYPE=FUNCTYPE) def inittime_helper(self, ll_helper, ll_args, ll_result, inline=True): @@ -282,6 +281,10 @@ def finish_helpers(self, backendopt=True): if self.translator is not None: self.mixlevelannotator.finish_annotate() + if hasattr(self, '_hack_call_later'): + f = self._hack_call_later + del self._hack_call_later + f(self) self.finished_helpers = True if self.translator is not None: self.mixlevelannotator.finish_rtype() diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -1,8 +1,8 @@ -from rpython.rlib import _rffi_stacklet as _c from rpython.rlib.debug import ll_assert from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.annlowlevel import llhelper +from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator +from rpython.annotator import model as annmodel _asmstackrootwalker = None # BIG HACK: monkey-patched by asmgcroot.py @@ -126,9 +126,20 @@ return _c._translate_pointer(self.context, addr) _stackletrootwalker = StackletRootWalker() + _asmstackrootwalker.gctransformer._hack_call_later = complete_destrptr return _stackletrootwalker get_stackletrootwalker._annspecialcase_ = 'specialize:memo' +def complete_destrptr(gctransformer): + translator = gctransformer.translator + mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) + args_s = [annmodel.lltype_to_annotation(lltype.Ptr(SUSPSTACK))] + s_result = annmodel.s_None + destrptr = mixlevelannotator.delayedfunction(suspstack_destructor, + args_s, s_result) + mixlevelannotator.finish() + lltype.attachRuntimeTypeInfo(SUSPSTACK, destrptr=destrptr) + def customtrace(obj, prev): stackletrootwalker = get_stackletrootwalker() @@ -148,12 +159,7 @@ CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) - -DESTRFUNC = lltype.FuncType([lltype.Ptr(SUSPSTACK)], lltype.Void) -destrptr = llhelper(lltype.Ptr(DESTRFUNC), suspstack_destructor) - -lltype.attachRuntimeTypeInfo(SUSPSTACK, customtraceptr=customtraceptr, - destrptr=destrptr) +lltype.attachRuntimeTypeInfo(SUSPSTACK, customtraceptr=customtraceptr) ASM_FRAMEDATA_HEAD_PTR = lltype.Ptr(lltype.ForwardReference()) ASM_FRAMEDATA_HEAD_PTR.TO.become(lltype.Struct('ASM_FRAMEDATA_HEAD', diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py --- a/rpython/translator/c/gc.py +++ b/rpython/translator/c/gc.py @@ -318,8 +318,8 @@ fptrs = gctransf.special_funcptr_for_type(TYPE) # make sure this is seen by the database early, i.e. before # finish_helpers() on the gctransformer - #destrptr = rtti._obj.destructor_funcptr - #self.db.get(destrptr) + destrptr = rtti._obj.destructor_funcptr + self.db.get(destrptr) # the following, on the other hand, will only discover ll_finalizer # helpers. The get() sees and records a delayed pointer. It is # still important to see it so that it can be followed as soon as From noreply at buildbot.pypy.org Sun Mar 3 18:18:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 3 Mar 2013 18:18:20 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Uh? No clue how it used to work Message-ID: <20130303171820.DEC4E1C034F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61955:9b1ae41499b6 Date: 2013-03-03 18:19 +0100 http://bitbucket.org/pypy/pypy/changeset/9b1ae41499b6/ Log: Uh? No clue how it used to work diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -3,6 +3,7 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator from rpython.annotator import model as annmodel +from rpython.rlib import _rffi_stacklet as _c _asmstackrootwalker = None # BIG HACK: monkey-patched by asmgcroot.py From noreply at buildbot.pypy.org Sun Mar 3 19:12:29 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 3 Mar 2013 19:12:29 +0100 (CET) Subject: [pypy-commit] pypy default: this file was missing from cea544e88241 Message-ID: <20130303181229.9C5EA1C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61956:e4110edee543 Date: 2013-03-03 13:11 -0500 http://bitbucket.org/pypy/pypy/changeset/e4110edee543/ Log: this file was missing from cea544e88241 diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py new file mode 100644 --- /dev/null +++ b/dotviewer/strunicode.py @@ -0,0 +1,9 @@ +RAW_ENCODING = "utf-8" + + +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) From noreply at buildbot.pypy.org Sun Mar 3 19:19:10 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 3 Mar 2013 19:19:10 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: Set default format and itemsize to the same value as before. Message-ID: <20130303181910.0821D1C010A@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r61957:48a23a9cfefd Date: 2013-03-03 19:15 +0100 http://bitbucket.org/pypy/pypy/changeset/48a23a9cfefd/ Log: Set default format and itemsize to the same value as before. diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -27,6 +27,8 @@ """Abstract base class for memory views.""" __slots__ = ('format', 'itemsize') + format = 'B' + itemsize = 1 def getlength(self): raise NotImplementedError From noreply at buildbot.pypy.org Sun Mar 3 19:56:48 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 3 Mar 2013 19:56:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: forgot this Message-ID: <20130303185648.A0DFD1C010A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61958:cbe4ed53ce77 Date: 2013-03-03 10:56 -0800 http://bitbucket.org/pypy/pypy/changeset/cbe4ed53ce77/ Log: forgot this diff --git a/pypy/module/imp/test/support.py b/pypy/module/imp/test/support.py new file mode 100644 --- /dev/null +++ b/pypy/module/imp/test/support.py @@ -0,0 +1,21 @@ +import sys + +class BaseImportTest: + + def setup_class(cls): + space = cls.space + testfn = u'test_tmp' + testfn_unencodable = None + + if sys.platform == 'nt': + testfn_unencodable = testfn + u"-\u5171\u0141\u2661\u0363\uDC80" + elif sys.platform != 'darwin': + fsenc = sys.getfilesystemencoding() + try: + '\xff'.decode(fsenc) + except UnicodeDecodeError: + w_unenc = space.call_method(space.wrapbytes('-\xff'), 'decode', + space.wrap(fsenc), + space.wrap('surrogateescape')) + testfn_unencodable = testfn + space.unicode_w(w_unenc) + cls.w_testfn_unencodable = space.wrap(testfn_unencodable) From noreply at buildbot.pypy.org Sun Mar 3 19:58:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 3 Mar 2013 19:58:28 +0100 (CET) Subject: [pypy-commit] pypy default: add numpypy.vdot Message-ID: <20130303185828.936861C010A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61959:3778a9fd5fe9 Date: 2013-03-03 13:57 -0500 http://bitbucket.org/pypy/pypy/changeset/3778a9fd5fe9/ Log: add numpypy.vdot diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -2,7 +2,7 @@ 'newaxis', 'ufunc', 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'outer', 'identity', 'little_endian', + 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', ] @@ -523,6 +523,60 @@ b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] +def vdot(a, b): + """ + Return the dot product of two vectors. + + The vdot(`a`, `b`) function handles complex numbers differently than + dot(`a`, `b`). If the first argument is complex the complex conjugate + of the first argument is used for the calculation of the dot product. + + Note that `vdot` handles multidimensional arrays differently than `dot`: + it does *not* perform a matrix product, but flattens input arguments + to 1-D vectors first. Consequently, it should only be used for vectors. + + Parameters + ---------- + a : array_like + If `a` is complex the complex conjugate is taken before calculation + of the dot product. + b : array_like + Second argument to the dot product. + + Returns + ------- + output : ndarray + Dot product of `a` and `b`. Can be an int, float, or + complex depending on the types of `a` and `b`. + + See Also + -------- + dot : Return the dot product without using the complex conjugate of the + first argument. + + Examples + -------- + >>> a = np.array([1+2j,3+4j]) + >>> b = np.array([5+6j,7+8j]) + >>> np.vdot(a, b) + (70-8j) + >>> np.vdot(b, a) + (70+8j) + + Note that higher-dimensional arrays are flattened! + + >>> a = np.array([[1, 4], [5, 6]]) + >>> b = np.array([[4, 1], [2, 2]]) + >>> np.vdot(a, b) + 30 + >>> np.vdot(b, a) + 30 + >>> 1*4 + 4*1 + 5*2 + 6*2 + 30 + + """ + return dot(asarray(a).ravel().conj(), asarray(b).ravel()) + def identity(n, dtype=None): """ Return the identity array. diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -189,6 +189,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_vdot(self): + import numpypy as np + a = np.array([1+2j,3+4j]) + b = np.array([5+6j,7+8j]) + c = np.vdot(a, b) + assert c == (70-8j) + c = np.vdot(b, a) + assert c == (70+8j) + + a = np.array([[1, 4], [5, 6]]) + b = np.array([[4, 1], [2, 2]]) + c = np.vdot(a, b) + assert c == 30 + c = np.vdot(b, a) + assert c == 30 + def test_identity(self): from numpypy import array, int32, float64, dtype, identity a = identity(0) From noreply at buildbot.pypy.org Sun Mar 3 20:02:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 3 Mar 2013 20:02:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix. Message-ID: <20130303190234.E03471C0F4B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61965:152ee9d80952 Date: 2013-03-03 20:02 +0100 http://bitbucket.org/pypy/pypy/changeset/152ee9d80952/ Log: Fix. 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 @@ -145,6 +145,7 @@ # stacklet support: BIG HACK for rlib.rstacklet from rpython.rlib import _stacklet_asmgcc _stacklet_asmgcc._asmstackrootwalker = self # as a global! argh + _stacklet_asmgcc.complete_destrptr(gctransformer) def need_thread_support(self, gctransformer, getfn): # Threads supported "out of the box" by the rest of the code. diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py --- a/rpython/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -281,10 +281,6 @@ def finish_helpers(self, backendopt=True): if self.translator is not None: self.mixlevelannotator.finish_annotate() - if hasattr(self, '_hack_call_later'): - f = self._hack_call_later - del self._hack_call_later - f(self) self.finished_helpers = True if self.translator is not None: self.mixlevelannotator.finish_rtype() diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -127,7 +127,6 @@ return _c._translate_pointer(self.context, addr) _stackletrootwalker = StackletRootWalker() - _asmstackrootwalker.gctransformer._hack_call_later = complete_destrptr return _stackletrootwalker get_stackletrootwalker._annspecialcase_ = 'specialize:memo' From noreply at buildbot.pypy.org Sun Mar 3 20:08:13 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 3 Mar 2013 20:08:13 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: Change app_main to find the stdlib which is now in lib-python/2. Message-ID: <20130303190813.8A4B41C010A@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: vendor-rename Changeset: r61966:2997a202a900 Date: 2013-03-03 20:05 +0100 http://bitbucket.org/pypy/pypy/changeset/2997a202a900/ Log: Change app_main to find the stdlib which is now in lib-python/2. diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -711,7 +711,7 @@ from os.path import abspath, join, dirname as dn thisfile = abspath(__file__) root = dn(dn(dn(thisfile))) - return [join(root, 'lib-python', '2.7'), + return [join(root, 'lib-python', '2'), join(root, 'lib_pypy')] def pypy_resolvedirof(s): From noreply at buildbot.pypy.org Sun Mar 3 20:08:14 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 3 Mar 2013 20:08:14 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: Adapt pypy/tool/lib_pypy.py, too. Message-ID: <20130303190814.D6B931C010A@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: vendor-rename Changeset: r61967:80b2bbd1eebf Date: 2013-03-03 20:07 +0100 http://bitbucket.org/pypy/pypy/changeset/80b2bbd1eebf/ Log: Adapt pypy/tool/lib_pypy.py, too. diff --git a/pypy/tool/lib_pypy.py b/pypy/tool/lib_pypy.py --- a/pypy/tool/lib_pypy.py +++ b/pypy/tool/lib_pypy.py @@ -5,7 +5,7 @@ LIB_ROOT = py.path.local(pypy.__path__[0]).dirpath() LIB_PYPY = LIB_ROOT.join('lib_pypy') -LIB_PYTHON = LIB_ROOT.join('lib-python', '%d.%d' % CPYTHON_VERSION[:2]) +LIB_PYTHON = LIB_ROOT.join('lib-python', '%d.%d' % CPYTHON_VERSION[0]) def import_from_lib_pypy(modname): From noreply at buildbot.pypy.org Sun Mar 3 20:11:33 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 3 Mar 2013 20:11:33 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: Change pypy/module/sys/initpath.py to find the stdlib which is now in lib-python/2. Message-ID: <20130303191133.B4D261C034F@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: vendor-rename Changeset: r61968:2752a68d972a Date: 2013-03-03 20:11 +0100 http://bitbucket.org/pypy/pypy/changeset/2752a68d972a/ Log: Change pypy/module/sys/initpath.py to find the stdlib which is now in lib-python/2. diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -91,8 +91,7 @@ ``lib_pypy``. If they cannot be found, it raises OSError. """ from pypy.module.sys.version import CPYTHON_VERSION - dirname = '%d.%d' % (CPYTHON_VERSION[0], - CPYTHON_VERSION[1]) + dirname = '%d.%d' % CPYTHON_VERSION[0] lib_python = os.path.join(prefix, 'lib-python') python_std_lib = os.path.join(lib_python, dirname) _checkdir(python_std_lib) From noreply at buildbot.pypy.org Sun Mar 3 20:12:39 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 3 Mar 2013 20:12:39 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: Oops. Message-ID: <20130303191239.1E1B71C034F@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: vendor-rename Changeset: r61969:33aeb97728f9 Date: 2013-03-03 20:12 +0100 http://bitbucket.org/pypy/pypy/changeset/33aeb97728f9/ Log: Oops. diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -91,7 +91,7 @@ ``lib_pypy``. If they cannot be found, it raises OSError. """ from pypy.module.sys.version import CPYTHON_VERSION - dirname = '%d.%d' % CPYTHON_VERSION[0] + dirname = '%d' % CPYTHON_VERSION[0] lib_python = os.path.join(prefix, 'lib-python') python_std_lib = os.path.join(lib_python, dirname) _checkdir(python_std_lib) diff --git a/pypy/tool/lib_pypy.py b/pypy/tool/lib_pypy.py --- a/pypy/tool/lib_pypy.py +++ b/pypy/tool/lib_pypy.py @@ -5,7 +5,7 @@ LIB_ROOT = py.path.local(pypy.__path__[0]).dirpath() LIB_PYPY = LIB_ROOT.join('lib_pypy') -LIB_PYTHON = LIB_ROOT.join('lib-python', '%d.%d' % CPYTHON_VERSION[0]) +LIB_PYTHON = LIB_ROOT.join('lib-python', '%d' % CPYTHON_VERSION[0]) def import_from_lib_pypy(modname): From noreply at buildbot.pypy.org Sun Mar 3 21:03:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 3 Mar 2013 21:03:45 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: more fixes for lib-python version rename Message-ID: <20130303200345.A49F81C3960@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: vendor-rename Changeset: r61970:7e7a539355b6 Date: 2013-03-03 15:03 -0500 http://bitbucket.org/pypy/pypy/changeset/7e7a539355b6/ Log: more fixes for lib-python version rename diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -889,7 +889,7 @@ # setup code for test_setup_bootstrap_path # ---------------------------------------- from pypy.module.sys.version import CPYTHON_VERSION, PYPY_VERSION - cpy_ver = '%d.%d' % CPYTHON_VERSION[:2] + cpy_ver = '%d' % CPYTHON_VERSION[0] goal_dir = os.path.dirname(app_main) # build a directory hierarchy like which contains both bin/pypy-c and diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -5,7 +5,7 @@ from pypy.module.sys.version import PYPY_VERSION, CPYTHON_VERSION def build_hierarchy(prefix): - dirname = '%d.%d' % CPYTHON_VERSION[:2] + dirname = '%d' % CPYTHON_VERSION[0] a = prefix.join('lib_pypy').ensure(dir=1) b = prefix.join('lib-python', dirname).ensure(dir=1) return a, b diff --git a/pypy/sandbox/test/test_pypy_interact.py b/pypy/sandbox/test/test_pypy_interact.py --- a/pypy/sandbox/test/test_pypy_interact.py +++ b/pypy/sandbox/test/test_pypy_interact.py @@ -5,7 +5,7 @@ from pypy.module.sys.version import CPYTHON_VERSION from pypy.tool.lib_pypy import LIB_PYTHON -VERSION = '%d.%d' % CPYTHON_VERSION[:2] +VERSION = '%d' % CPYTHON_VERSION[0] SITE_PY_CONTENT = LIB_PYTHON.join('site.py').read() ERROR_TEXT = os.strerror(errno.ENOENT) diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -22,7 +22,7 @@ USE_ZIPFILE_MODULE = sys.platform == 'win32' -STDLIB_VER = "2.7" +STDLIB_VER = "2" def ignore_patterns(*patterns): """Function that can be used as copytree() ignore parameter. diff --git a/pypy/tool/release/test/test_package.py b/pypy/tool/release/test/test_package.py --- a/pypy/tool/release/test/test_package.py +++ b/pypy/tool/release/test/test_package.py @@ -26,7 +26,7 @@ builddir = package.package(py.path.local(pypydir).dirpath(), test, rename_pypy_c) prefix = builddir.join(test) - cpyver = '%d.%d' % CPYTHON_VERSION[:2] + cpyver = '%d' % CPYTHON_VERSION[0] assert prefix.join('lib-python', cpyver, 'test').check() assert prefix.join(exe_name_in_archive).check() assert prefix.join('lib_pypy', 'syslog.py').check() diff --git a/pypy/tool/test/test_package.py b/pypy/tool/test/test_package.py --- a/pypy/tool/test/test_package.py +++ b/pypy/tool/test/test_package.py @@ -2,5 +2,4 @@ from pypy.module.sys import version def test_version(): - assert package.STDLIB_VER == '%d.%d' % (version.CPYTHON_VERSION[0], - version.CPYTHON_VERSION[1]) + assert package.STDLIB_VER == '%d' % version.CPYTHON_VERSION[0] From noreply at buildbot.pypy.org Sun Mar 3 22:09:25 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 3 Mar 2013 22:09:25 +0100 (CET) Subject: [pypy-commit] pypy default: Rollback 55c169444232 it breaks things Message-ID: <20130303210925.46DF31C0F4B@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61971:75139770e725 Date: 2013-03-03 13:06 -0800 http://bitbucket.org/pypy/pypy/changeset/75139770e725/ Log: Rollback 55c169444232 it breaks things 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 @@ -302,7 +302,6 @@ b.chars[i] = str.chars[i] return b - @jit.look_inside_iff(lambda s: jit.isvirtual(s)) @jit.elidable def ll_strhash(s): # unlike CPython, there is no reason to avoid to return -1 From noreply at buildbot.pypy.org Sun Mar 3 22:09:26 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 3 Mar 2013 22:09:26 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130303210926.995D61C0F4B@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61972:9c33b593ae1c Date: 2013-03-03 13:09 -0800 http://bitbucket.org/pypy/pypy/changeset/9c33b593ae1c/ Log: merged upstream diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -2,7 +2,7 @@ 'newaxis', 'ufunc', 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'outer', 'identity', 'little_endian', + 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', ] @@ -523,6 +523,60 @@ b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] +def vdot(a, b): + """ + Return the dot product of two vectors. + + The vdot(`a`, `b`) function handles complex numbers differently than + dot(`a`, `b`). If the first argument is complex the complex conjugate + of the first argument is used for the calculation of the dot product. + + Note that `vdot` handles multidimensional arrays differently than `dot`: + it does *not* perform a matrix product, but flattens input arguments + to 1-D vectors first. Consequently, it should only be used for vectors. + + Parameters + ---------- + a : array_like + If `a` is complex the complex conjugate is taken before calculation + of the dot product. + b : array_like + Second argument to the dot product. + + Returns + ------- + output : ndarray + Dot product of `a` and `b`. Can be an int, float, or + complex depending on the types of `a` and `b`. + + See Also + -------- + dot : Return the dot product without using the complex conjugate of the + first argument. + + Examples + -------- + >>> a = np.array([1+2j,3+4j]) + >>> b = np.array([5+6j,7+8j]) + >>> np.vdot(a, b) + (70-8j) + >>> np.vdot(b, a) + (70+8j) + + Note that higher-dimensional arrays are flattened! + + >>> a = np.array([[1, 4], [5, 6]]) + >>> b = np.array([[4, 1], [2, 2]]) + >>> np.vdot(a, b) + 30 + >>> np.vdot(b, a) + 30 + >>> 1*4 + 4*1 + 5*2 + 6*2 + 30 + + """ + return dot(asarray(a).ravel().conj(), asarray(b).ravel()) + def identity(n, dtype=None): """ Return the identity array. diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -189,6 +189,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_vdot(self): + import numpypy as np + a = np.array([1+2j,3+4j]) + b = np.array([5+6j,7+8j]) + c = np.vdot(a, b) + assert c == (70-8j) + c = np.vdot(b, a) + assert c == (70+8j) + + a = np.array([[1, 4], [5, 6]]) + b = np.array([[4, 1], [2, 2]]) + c = np.vdot(a, b) + assert c == 30 + c = np.vdot(b, a) + assert c == 30 + def test_identity(self): from numpypy import array, int32, float64, dtype, identity a = identity(0) From noreply at buildbot.pypy.org Sun Mar 3 23:20:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 3 Mar 2013 23:20:31 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: merge default Message-ID: <20130303222031.862BC1C03A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: vendor-rename Changeset: r61973:fc3d8d284aac Date: 2013-03-03 17:19 -0500 http://bitbucket.org/pypy/pypy/changeset/fc3d8d284aac/ Log: merge default diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py new file mode 100644 --- /dev/null +++ b/dotviewer/strunicode.py @@ -0,0 +1,9 @@ +RAW_ENCODING = "utf-8" + + +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -2,7 +2,7 @@ 'newaxis', 'ufunc', 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'outer', 'identity', 'little_endian', + 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', ] @@ -523,6 +523,60 @@ b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] +def vdot(a, b): + """ + Return the dot product of two vectors. + + The vdot(`a`, `b`) function handles complex numbers differently than + dot(`a`, `b`). If the first argument is complex the complex conjugate + of the first argument is used for the calculation of the dot product. + + Note that `vdot` handles multidimensional arrays differently than `dot`: + it does *not* perform a matrix product, but flattens input arguments + to 1-D vectors first. Consequently, it should only be used for vectors. + + Parameters + ---------- + a : array_like + If `a` is complex the complex conjugate is taken before calculation + of the dot product. + b : array_like + Second argument to the dot product. + + Returns + ------- + output : ndarray + Dot product of `a` and `b`. Can be an int, float, or + complex depending on the types of `a` and `b`. + + See Also + -------- + dot : Return the dot product without using the complex conjugate of the + first argument. + + Examples + -------- + >>> a = np.array([1+2j,3+4j]) + >>> b = np.array([5+6j,7+8j]) + >>> np.vdot(a, b) + (70-8j) + >>> np.vdot(b, a) + (70+8j) + + Note that higher-dimensional arrays are flattened! + + >>> a = np.array([[1, 4], [5, 6]]) + >>> b = np.array([[4, 1], [2, 2]]) + >>> np.vdot(a, b) + 30 + >>> np.vdot(b, a) + 30 + >>> 1*4 + 4*1 + 5*2 + 6*2 + 30 + + """ + return dot(asarray(a).ravel().conj(), asarray(b).ravel()) + def identity(n, dtype=None): """ Return the identity array. diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -189,6 +189,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_vdot(self): + import numpypy as np + a = np.array([1+2j,3+4j]) + b = np.array([5+6j,7+8j]) + c = np.vdot(a, b) + assert c == (70-8j) + c = np.vdot(b, a) + assert c == (70+8j) + + a = np.array([[1, 4], [5, 6]]) + b = np.array([[4, 1], [2, 2]]) + c = np.vdot(a, b) + assert c == 30 + c = np.vdot(b, a) + assert c == 30 + def test_identity(self): from numpypy import array, int32, float64, dtype, identity a = identity(0) 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 @@ -302,7 +302,6 @@ b.chars[i] = str.chars[i] return b - @jit.look_inside_iff(lambda s: jit.isvirtual(s)) @jit.elidable def ll_strhash(s): # unlike CPython, there is no reason to avoid to return -1 From noreply at buildbot.pypy.org Mon Mar 4 01:08:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 01:08:27 +0100 (CET) Subject: [pypy-commit] pypy vendor-rename: close merged branch Message-ID: <20130304000827.0F88E1C0F4B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: vendor-rename Changeset: r61974:723986fc919f Date: 2013-03-03 19:05 -0500 http://bitbucket.org/pypy/pypy/changeset/723986fc919f/ Log: close merged branch From noreply at buildbot.pypy.org Mon Mar 4 01:47:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 01:47:33 +0100 (CET) Subject: [pypy-commit] pypy default: port a few small no-op cleanups from py3k Message-ID: <20130304004733.24F0F1C010A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61979:7656fc10050b Date: 2013-03-03 19:38 -0500 http://bitbucket.org/pypy/pypy/changeset/7656fc10050b/ Log: port a few small no-op cleanups from py3k diff --git a/pypy/__init__.py b/pypy/__init__.py --- a/pypy/__init__.py +++ b/pypy/__init__.py @@ -6,7 +6,7 @@ # When all tests work, this branch will be merged # and the branch stage 2 is started, where we remove this patch. import sys -if hasattr(sys, "maxsize"): +if hasattr(sys, "maxint") and hasattr(sys, "maxsize"): if sys.maxint != sys.maxsize: sys.maxint = sys.maxsize import warnings diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -23,7 +23,7 @@ py.code.Source.deindent = braindead_deindent def pytest_report_header(): - return "pytest-%s from %s" %(pytest.__version__, pytest.__file__) + return "pytest-%s from %s" % (pytest.__version__, pytest.__file__) def pytest_addhooks(pluginmanager): from rpython.conftest import LeakFinder diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -120,8 +120,7 @@ except AttributeError: print >> sys.stderr, 'no translation information found' else: - optitems = options.items() - optitems.sort() + optitems = sorted(options.items()) current = [] for key, value in optitems: group = key.split('.') @@ -151,8 +150,7 @@ except ImportError: print >> sys.stderr, "No jit support in %s" % (sys.executable,) return - items = pypyjit.defaults.items() - items.sort() + items = sorted(pypyjit.defaults.items()) print 'Advanced JIT options: a comma-separated list of OPTION=VALUE:' for key, value in items: print diff --git a/pytest.py b/pytest.py --- a/pytest.py +++ b/pytest.py @@ -23,7 +23,7 @@ # When all tests work, this branch will be merged # and the branch stage 2 is started, where we remove this patch. import sys -if hasattr(sys, "maxsize"): +if hasattr(sys, "maxint") and hasattr(sys, "maxsize"): if sys.maxint != sys.maxsize: sys.maxint = sys.maxsize import warnings From noreply at buildbot.pypy.org Mon Mar 4 01:47:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 01:47:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130304004734.779B61C010A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r61980:a5aeb453db1c Date: 2013-03-03 19:46 -0500 http://bitbucket.org/pypy/pypy/changeset/a5aeb453db1c/ Log: merge default diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -117,8 +117,7 @@ except AttributeError: print('no translation information found', file=sys.stderr) else: - optitems = list(options.items()) - optitems.sort() + optitems = sorted(options.items()) current = [] for key, value in optitems: group = key.split('.') From noreply at buildbot.pypy.org Mon Mar 4 02:09:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 02:09:33 +0100 (CET) Subject: [pypy-commit] pypy default: more no-op changes to reduce diff with py3k Message-ID: <20130304010933.04AB91C0F4B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61981:59da76c514bb Date: 2013-03-03 20:03 -0500 http://bitbucket.org/pypy/pypy/changeset/59da76c514bb/ Log: more no-op changes to reduce diff with py3k diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py --- a/lib_pypy/_ctypes/function.py +++ b/lib_pypy/_ctypes/function.py @@ -160,11 +160,11 @@ callable(restype)): raise TypeError("restype must be a type, a callable, or None") self._restype_ = restype - + def _delrestype(self): self._ptr = None del self._restype_ - + restype = property(_getrestype, _setrestype, _delrestype) def _geterrcheck(self): @@ -224,7 +224,7 @@ self._check_argtypes_for_fastpath() return - + # A callback into python if callable(argument) and not argsl: self.callable = argument @@ -277,7 +277,7 @@ for argtype, arg in zip(argtypes, args)] return to_call(*args) return f - + def __call__(self, *args, **kwargs): argtypes = self._argtypes_ if self.callable is not None: @@ -577,7 +577,7 @@ @staticmethod def _is_primitive(argtype): return argtype.__bases__[0] is _SimpleCData - + def _wrap_result(self, restype, result): """ Convert from low-level repr of the result to the high-level python diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py --- a/lib_pypy/_ctypes/primitive.py +++ b/lib_pypy/_ctypes/primitive.py @@ -186,8 +186,8 @@ elif value is None: value = 0 self._buffer[0] = value - result.value = property(_getvalue, _setvalue) - + result.value = property(_getvalue, _setvalue) + elif tp == 'u': def _setvalue(self, val): if isinstance(val, str): @@ -271,7 +271,7 @@ def _as_ffi_pointer_(self, ffitype): return as_ffi_pointer(self, ffitype) result._as_ffi_pointer_ = _as_ffi_pointer_ - + return result from_address = cdata_from_address @@ -279,7 +279,7 @@ def from_param(self, value): if isinstance(value, self): return value - + from_param_f = FROM_PARAM_BY_TYPE.get(self._type_) if from_param_f: res = from_param_f(self, value) @@ -298,7 +298,7 @@ if self.__bases__[0] is _SimpleCData: return output.value return output - + def _sizeofinstances(self): return _rawffi.sizeof(self._type_) diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -964,8 +964,8 @@ raise self.con._get_exception(ret) self.con._remember_statement(self) if _check_remaining_sql(next_char.value): - raise Warning("One and only one statement required: %r" % ( - next_char.value,)) + raise Warning("One and only one statement required: %r" % + (next_char.value,)) # sql_char should remain alive until here self._build_row_cast_map() @@ -1036,7 +1036,8 @@ elif type(param) is buffer: sqlite.sqlite3_bind_blob(self.statement, idx, str(param), len(param), SQLITE_TRANSIENT) else: - raise InterfaceError("parameter type %s is not supported" % str(type(param))) + raise InterfaceError("parameter type %s is not supported" % + str(type(param))) def set_params(self, params): ret = sqlite.sqlite3_reset(self.statement) From noreply at buildbot.pypy.org Mon Mar 4 02:09:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 02:09:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130304010934.3A6691C0F4B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r61982:d0d289b7040b Date: 2013-03-03 20:08 -0500 http://bitbucket.org/pypy/pypy/changeset/d0d289b7040b/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1028,7 +1028,7 @@ param = bytes(param) sqlite.sqlite3_bind_blob(self.statement, idx, param, len(param), SQLITE_TRANSIENT) else: - raise InterfaceError("parameter type %s is not supported" % + raise InterfaceError("parameter type %s is not supported" % type(param)) def set_params(self, params): From noreply at buildbot.pypy.org Mon Mar 4 02:54:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 02:54:57 +0100 (CET) Subject: [pypy-commit] pypy default: prevent test_rsocket from relying on SO_REUSEADDR (behavior differs across platforms) Message-ID: <20130304015457.C78421C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61983:f7c7029269d3 Date: 2013-03-03 20:54 -0500 http://bitbucket.org/pypy/pypy/changeset/f7c7029269d3/ Log: prevent test_rsocket from relying on SO_REUSEADDR (behavior differs across platforms) diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -367,7 +367,6 @@ if sys.platform == "win32": skip("dup does not work on Windows") s = RSocket(AF_INET, SOCK_STREAM) - s.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) s.bind(INETAddress('localhost', 50007)) s2 = s.dup() assert s.fd != s2.fd @@ -377,10 +376,10 @@ # rsocket.dup() duplicates fd, it also works on Windows # (but only on socket handles!) s = RSocket(AF_INET, SOCK_STREAM) - s.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) s.bind(INETAddress('localhost', 50007)) - fd2 = dup(s.fd) - assert s.fd != fd2 + s2 = RSocket(fd=dup(s.fd)) + assert s.fd != s2.fd + assert s.getsockname().eq(s2.getsockname()) def test_inet_aton(): assert inet_aton('1.2.3.4') == '\x01\x02\x03\x04' @@ -444,7 +443,6 @@ def setup_method(self, method): self.serv = RSocket(AF_INET, SOCK_STREAM) - self.serv.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) self.serv.bind(INETAddress(self.HOST, self.PORT)) self.serv.listen(1) From noreply at buildbot.pypy.org Mon Mar 4 03:15:42 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 03:15:42 +0100 (CET) Subject: [pypy-commit] pypy default: bsd does seem to raise EINPROGRESS Message-ID: <20130304021542.0FED61C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61984:9de22a29a217 Date: 2013-03-03 18:15 -0800 http://bitbucket.org/pypy/pypy/changeset/9de22a29a217/ Log: bsd does seem to raise EINPROGRESS diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py --- a/pypy/module/select/test/test_kqueue.py +++ b/pypy/module/select/test/test_kqueue.py @@ -100,10 +100,9 @@ try: client.connect(("127.0.0.1", server_socket.getsockname()[1])) except socket.error, e: - if 'bsd' in sys.platform: - assert e.args[0] == errno.ENOENT - else: - assert e.args[0] == errno.EINPROGRESS + assert e.args[0] == errno.EINPROGRESS + else: + assert False, "EINPROGRESS not raised" server, addr = server_socket.accept() if sys.platform.startswith("darwin"): From noreply at buildbot.pypy.org Mon Mar 4 03:32:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 03:32:10 +0100 (CET) Subject: [pypy-commit] pypy default: this test is really the same as the previous, merge Message-ID: <20130304023210.A703D1C395E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61985:2cb26f938ad8 Date: 2013-03-03 21:30 -0500 http://bitbucket.org/pypy/pypy/changeset/2cb26f938ad8/ Log: this test is really the same as the previous, merge diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py --- a/pypy/module/select/test/test_select.py +++ b/pypy/module/select/test/test_select.py @@ -193,29 +193,12 @@ readend, writeend = self.getpair() readend.close() try: - iwtd, owtd, ewtd = select.select([], [writeend], []) - assert owtd == [writeend] - assert iwtd == ewtd == [] + iwtd, owtd, ewtd = select.select([writeend], [writeend], [writeend]) + assert iwtd == owtd == [writeend] + assert ewtd == [] finally: writeend.close() - def test_select_bug(self): - import select, os - if not hasattr(os, 'fork'): - skip("no fork() on this platform") - read, write = os.pipe() - pid = os.fork() - if pid == 0: - os._exit(0) - else: - os.close(read) - os.waitpid(pid, 0) - res = select.select([write], [write], [write]) - assert len(res[0]) == 1 - assert len(res[1]) == 1 - assert len(res[2]) == 0 - assert res[0][0] == res[1][0] - def test_poll(self): import select if not hasattr(select, 'poll'): From noreply at buildbot.pypy.org Mon Mar 4 04:23:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 04:23:55 +0100 (CET) Subject: [pypy-commit] pypy default: try to fix ctypes_tests on win32 Message-ID: <20130304032355.7B6861C03A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61986:4f5bb04f69ac Date: 2013-03-03 22:23 -0500 http://bitbucket.org/pypy/pypy/changeset/4f5bb04f69ac/ Log: try to fix ctypes_tests on win32 diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py b/pypy/module/test_lib_pypy/ctypes_tests/support.py --- a/pypy/module/test_lib_pypy/ctypes_tests/support.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/support.py @@ -44,6 +44,7 @@ del_funcptr_refs_maybe(mod, 'dll2') del_funcptr_refs_maybe(mod, 'lib') del_funcptr_refs_maybe(mod, 'testdll') + del_funcptr_refs_maybe(mod, 'windll') del_funcptr_refs_maybe(mod, 'ctdll') del_funcptr_refs_maybe(cls, '_dll') # From noreply at buildbot.pypy.org Mon Mar 4 04:34:17 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 04:34:17 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_os_wait for win32 Message-ID: <20130304033417.77F7B1C03A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61987:a421042f59d5 Date: 2013-03-03 22:33 -0500 http://bitbucket.org/pypy/pypy/changeset/a421042f59d5/ Log: fix test_os_wait for win32 diff --git a/pypy/module/test_lib_pypy/test_os_wait.py b/pypy/module/test_lib_pypy/test_os_wait.py --- a/pypy/module/test_lib_pypy/test_os_wait.py +++ b/pypy/module/test_lib_pypy/test_os_wait.py @@ -5,9 +5,8 @@ import os -from lib_pypy._pypy_wait import wait3, wait4 - if hasattr(os, 'wait3'): + from lib_pypy._pypy_wait import wait3 def test_os_wait3(): exit_status = 0x33 @@ -26,6 +25,7 @@ assert isinstance(rusage.ru_maxrss, int) if hasattr(os, 'wait4'): + from lib_pypy._pypy_wait import wait4 def test_os_wait4(): exit_status = 0x33 From noreply at buildbot.pypy.org Mon Mar 4 04:34:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 04:34:18 +0100 (CET) Subject: [pypy-commit] pypy default: (yamt) more dotviewer fixes Message-ID: <20130304033418.EDA831C03A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61988:6d5c4347b06e Date: 2013-03-03 22:34 -0500 http://bitbucket.org/pypy/pypy/changeset/6d5c4347b06e/ Log: (yamt) more dotviewer fixes diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py --- a/dotviewer/test/test_interactive_unicode.py +++ b/dotviewer/test/test_interactive_unicode.py @@ -4,7 +4,7 @@ import py import sys, os, signal, thread, time, codecs from dotviewer.conftest import option -from dotviewer.drawgraph import RAW_ENCODING +from dotviewer.strunicode import RAW_ENCODING SOURCE1 = u"""digraph G{ λ -> b diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py --- a/dotviewer/test/test_unicode_util.py +++ b/dotviewer/test/test_unicode_util.py @@ -3,7 +3,7 @@ # import py import codecs -from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode +from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode SOURCE1 = u"""digraph G{ λ -> b From noreply at buildbot.pypy.org Mon Mar 4 08:29:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 08:29:08 +0100 (CET) Subject: [pypy-commit] pypy default: simplify datetime.fromtimestamp Message-ID: <20130304072908.8F7301C0F4B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61990:61f429986074 Date: 2013-03-04 02:08 -0500 http://bitbucket.org/pypy/pypy/changeset/61f429986074/ Log: simplify datetime.fromtimestamp diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -1515,16 +1515,16 @@ converter = _time.localtime if tz is None else _time.gmtime - if t < 0.0: - us = int(round(((-t) % 1.0) * 1000000)) - if us > 0: - us = 1000000 - us - t -= 1.0 - else: - us = int(round((t % 1.0) * 1000000)) - if us == 1000000: - us = 0 - t += 1.0 + t, frac = divmod(t, 1.0) + us = int(round(frac * 1e6)) + + # If timestamp is less than one microsecond smaller than a + # full second, us can be rounded up to 1000000. In this case, + # roll over to seconds, otherwise, ValueError is raised + # by the constructor. + if us == 1000000: + t += 1 + us = 0 y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) ss = min(ss, 59) # clamp out leap seconds if the platform has them result = cls(y, m, d, hh, mm, ss, us, tz) From noreply at buildbot.pypy.org Mon Mar 4 08:29:07 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 08:29:07 +0100 (CET) Subject: [pypy-commit] pypy default: small clean-ups for datetime.py Message-ID: <20130304072907.5910D1C010A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61989:c739289c2397 Date: 2013-03-04 02:26 -0500 http://bitbucket.org/pypy/pypy/changeset/c739289c2397/ Log: small clean-ups for datetime.py diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -44,10 +44,6 @@ "year -> 1 if leap year, else 0." return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) -def _days_in_year(year): - "year -> number of days in year (366 if a leap year, else 365)." - return 365 + _is_leap(year) - def _days_before_year(year): "year -> number of days before January 1st of year." y = year - 1 @@ -527,7 +523,7 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = round(microseconds) + microseconds = round(microseconds, 0) seconds, microseconds = divmod(microseconds, 1e6) assert microseconds == int(microseconds) assert seconds == long(seconds) @@ -547,7 +543,7 @@ assert abs(s) <= 3 * 24 * 3600 microseconds = float(microseconds) microseconds += usdouble - microseconds = round(microseconds) + microseconds = round(microseconds, 0) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 @@ -600,6 +596,7 @@ return s def total_seconds(self): + """Total seconds in the duration.""" return ((self.days * 86400 + self.seconds) * 10**6 + self.microseconds) / 1e6 @@ -732,8 +729,6 @@ # Pickle support. - __safe_for_unpickling__ = True # For Python 2.2 - def _getstate(self): return (self._days, self._seconds, self._microseconds) @@ -842,7 +837,7 @@ # strftime("%c", ...) is locale specific. def ctime(self): - "Format a la ctime()." + "Return ctime() style string." return tmxxx(self._year, self._month, self._day).ctime() def strftime(self, fmt): @@ -988,7 +983,7 @@ self._checkOverflow(t.year) result = date(t.year, t.month, t.day) return result - return NotImplemented # note that this doesn't work on CPython 2.2 + return NotImplemented __radd__ = __add__ @@ -1042,8 +1037,6 @@ # Pickle support. - __safe_for_unpickling__ = True # For Python 2.2 - def _getstate(self): yhi, ylo = divmod(self._year, 256) return ("%c%c%c%c" % (yhi, ylo, self._month, self._day), ) @@ -1119,8 +1112,6 @@ # Pickle support. - __safe_for_unpickling__ = True # For Python 2.2 - def __reduce__(self): getinitargs = getattr(self, "__getinitargs__", None) if getinitargs: @@ -1137,7 +1128,7 @@ else: return (self.__class__, args, state) -_tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it +_tzinfo_class = tzinfo # so functions w/ args named "tzinfo" can get at the class class time(object): """Time with time zone. @@ -1274,7 +1265,6 @@ (other._hour, other._minute, other._second, other._microsecond)) if myoff is None or otoff is None: - # XXX Buggy in 2.2.2. raise TypeError("cannot compare naive and aware times") myhhmm = self._hour * 60 + self._minute - myoff othhmm = other._hour * 60 + other._minute - otoff @@ -1399,6 +1389,12 @@ offset = timedelta(minutes=offset) return offset + # Return an integer (or None) instead of a timedelta (or None). + def _dst(self): + offset = _call_tzinfo_method(self._tzinfo, "dst", None) + offset = _check_utc_offset("dst", offset) + return offset + def replace(self, hour=None, minute=None, second=None, microsecond=None, tzinfo=True): """Return a new time with new values for the specified fields.""" @@ -1416,12 +1412,6 @@ _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) - # Return an integer (or None) instead of a timedelta (or None). - def _dst(self): - offset = _call_tzinfo_method(self._tzinfo, "dst", None) - offset = _check_utc_offset("dst", offset) - return offset - def __nonzero__(self): if self.second or self.microsecond: return 1 @@ -1430,8 +1420,6 @@ # Pickle support. - __safe_for_unpickling__ = True # For Python 2.2 - def _getstate(self): us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) @@ -1524,10 +1512,9 @@ """ _check_tzinfo_arg(tz) - if tz is None: - converter = _time.localtime - else: - converter = _time.gmtime + + converter = _time.localtime if tz is None else _time.gmtime + if t < 0.0: us = int(round(((-t) % 1.0) * 1000000)) if us > 0: @@ -1673,7 +1660,7 @@ # Ways to produce a string. def ctime(self): - "Format a la ctime()." + "Return ctime() style string." t = tmxxx(self._year, self._month, self._day, self._hour, self._minute, self._second) return t.ctime() @@ -1775,13 +1762,13 @@ offset = timedelta(minutes=offset) return offset - # Return an integer (or None) instead of a timedelta (or None).1573 + # Return an integer (or None) instead of a timedelta (or None). def _dst(self): offset = _call_tzinfo_method(self._tzinfo, "dst", self) offset = _check_utc_offset("dst", offset) return offset - # Comparisons. + # Comparisons of datetime objects with other. def __eq__(self, other): if isinstance(other, datetime): @@ -1854,7 +1841,6 @@ other._hour, other._minute, other._second, other._microsecond)) if myoff is None or otoff is None: - # XXX Buggy in 2.2.2. raise TypeError("cannot compare naive and aware datetimes") # XXX What follows could be done more efficiently... diff = self - other # this will take offsets into account @@ -1915,8 +1901,6 @@ # Pickle support. - __safe_for_unpickling__ = True # For Python 2.2 - def _getstate(self): yhi, ylo = divmod(self._year, 256) us2, us3 = divmod(self._microsecond, 256) @@ -2154,4 +2138,3 @@ perverse time zone returns a negative dst()). So a breaking case must be pretty bizarre, and a tzinfo subclass can override fromutc() if it is. """ - From noreply at buildbot.pypy.org Mon Mar 4 08:29:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 08:29:09 +0100 (CET) Subject: [pypy-commit] pypy default: optimize datetime.strftime %f like others Message-ID: <20130304072909.D48C91C010A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61991:68cf7a8984a1 Date: 2013-03-04 02:12 -0500 http://bitbucket.org/pypy/pypy/changeset/68cf7a8984a1/ Log: optimize datetime.strftime %f like others diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -176,6 +176,7 @@ raise ValueError("year=%d is before 1900; the datetime strftime() " "methods require year >= 1900" % year) # Don't call _utcoffset() or tzname() unless actually needed. + freplace = None # the string to use for %f zreplace = None # the string to use for %z Zreplace = None # the string to use for %Z @@ -190,7 +191,12 @@ if i < n: ch = format[i] i += 1 - if ch == 'z': + if ch == 'f': + if freplace is None: + freplace = '%06d' % getattr(object, + 'microsecond', 0) + newformat.append(freplace) + elif ch == 'z': if zreplace is None: zreplace = "" if hasattr(object, "_utcoffset"): @@ -213,11 +219,6 @@ # strftime is going to have at this: escape % Zreplace = s.replace('%', '%%') newformat.append(Zreplace) - elif ch == 'f': - if isinstance(object, (time, datetime)): - newformat.append('%06d' % object.microsecond) - else: - newformat.append('000000') else: push('%') push(ch) From noreply at buildbot.pypy.org Mon Mar 4 10:03:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 10:03:37 +0100 (CET) Subject: [pypy-commit] pypy default: this didn't fix anything Message-ID: <20130304090337.B1FBF1C0F4B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61992:6fe2c02099ef Date: 2013-03-04 04:03 -0500 http://bitbucket.org/pypy/pypy/changeset/6fe2c02099ef/ Log: this didn't fix anything diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py b/pypy/module/test_lib_pypy/ctypes_tests/support.py --- a/pypy/module/test_lib_pypy/ctypes_tests/support.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/support.py @@ -44,7 +44,6 @@ del_funcptr_refs_maybe(mod, 'dll2') del_funcptr_refs_maybe(mod, 'lib') del_funcptr_refs_maybe(mod, 'testdll') - del_funcptr_refs_maybe(mod, 'windll') del_funcptr_refs_maybe(mod, 'ctdll') del_funcptr_refs_maybe(cls, '_dll') # From noreply at buildbot.pypy.org Mon Mar 4 10:04:46 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 10:04:46 +0100 (CET) Subject: [pypy-commit] pypy gc-del: in-progress Message-ID: <20130304090446.3F6901C3962@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r61993:ac5c5480c694 Date: 2013-03-04 10:04 +0100 http://bitbucket.org/pypy/pypy/changeset/ac5c5480c694/ Log: in-progress diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -11,7 +11,7 @@ WEAKREFPTR from rpython.tool.sourcetools import func_with_new_name from rpython.translator.backendopt import graphanalyze -from rpython.translator.backendopt.finalizer import FinalizerAnalyzer +from rpython.translator.backendopt.destructor import DestructorAnalyzer from rpython.translator.backendopt.support import var_needsgc import types @@ -650,21 +650,15 @@ info = self.layoutbuilder.get_info(type_id) c_size = rmodel.inputconst(lltype.Signed, info.fixedsize) kind_and_fptr = self.special_funcptr_for_type(TYPE) - has_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "finalizer") - has_light_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "light_finalizer") - if has_light_finalizer: - has_finalizer = True - c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer) - c_has_light_finalizer = rmodel.inputconst(lltype.Bool, - has_light_finalizer) + has_destructor = (kind_and_fptr is not None and + kind_and_fptr[0] == "destructor") + c_has_destructor = rmodel.inputconst(lltype.Bool, has_destructor) if not op.opname.endswith('_varsize') and not flags.get('varsize'): #malloc_ptr = self.malloc_fixedsize_ptr zero = flags.get('zero', False) if (self.malloc_fast_ptr is not None and - not c_has_finalizer.value and + not has_destructor and (self.malloc_fast_is_clearing or not zero)): malloc_ptr = self.malloc_fast_ptr elif zero: @@ -672,10 +666,9 @@ else: malloc_ptr = self.malloc_fixedsize_ptr args = [self.c_const_gc, c_type_id, c_size, - c_has_finalizer, c_has_light_finalizer, - rmodel.inputconst(lltype.Bool, False)] + c_has_destructor, rmodel.inputconst(lltype.Bool, False)] else: - assert not c_has_finalizer.value + assert not has_destructor info_varsize = self.layoutbuilder.get_info_varsize(type_id) v_length = op.args[-1] c_ofstolength = rmodel.inputconst(lltype.Signed, @@ -830,13 +823,12 @@ def gct_do_malloc_fixedsize_clear(self, hop): # used by the JIT (see rpython.jit.backend.llsupport.gc) op = hop.spaceop - [v_typeid, v_size, - v_has_finalizer, v_has_light_finalizer, v_contains_weakptr] = op.args + [v_typeid, v_size, v_has_destructor, v_contains_weakptr] = op.args livevars = self.push_roots(hop) hop.genop("direct_call", [self.malloc_fixedsize_clear_ptr, self.c_const_gc, v_typeid, v_size, - v_has_finalizer, v_has_light_finalizer, + v_has_destructor, v_contains_weakptr], resultvar=op.result) self.pop_roots(hop, livevars) @@ -1204,6 +1196,9 @@ def pop_roots(self, hop, livevars): raise NotImplementedError + def gct_gc_register_finalizer(self, op): + xxx + class TransformerLayoutBuilder(gctypelayout.TypeLayoutBuilder): @@ -1218,36 +1213,32 @@ self.translator = translator super(TransformerLayoutBuilder, self).__init__(GCClass, lltype2vtable) - def has_finalizer(self, TYPE): + def has_destructor(self, TYPE): rtti = get_rtti(TYPE) return rtti is not None and getattr(rtti._obj, 'destructor_funcptr', None) - def has_light_finalizer(self, TYPE): - special = self.special_funcptr_for_type(TYPE) - return special is not None and special[0] == 'light_finalizer' - def has_custom_trace(self, TYPE): rtti = get_rtti(TYPE) return rtti is not None and getattr(rtti._obj, 'custom_trace_funcptr', None) - def make_finalizer_funcptr_for_type(self, TYPE): - if not self.has_finalizer(TYPE): - return None, False + def make_destructor_funcptr_for_type(self, TYPE): + if not self.has_destructor(TYPE): + return None rtti = get_rtti(TYPE) destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] typename = TYPE.__name__ - def ll_finalizer(addr, ignored): + def ll_destructor(addr, ignored): v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) return llmemory.NULL - fptr = self.transformer.annotate_finalizer(ll_finalizer, + fptr = self.transformer.annotate_finalizer(ll_destructor, [llmemory.Address, llmemory.Address], llmemory.Address) g = destrptr._obj.graph - light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) - return fptr, light + DestructorAnalyzer(self.translator).check_destructor(g) + return fptr def make_custom_trace_funcptr_for_type(self, TYPE): if not self.has_custom_trace(TYPE): diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -377,15 +377,12 @@ def special_funcptr_for_type(self, TYPE): if TYPE in self._special_funcptrs: return self._special_funcptrs[TYPE] - fptr1, is_lightweight = self.make_finalizer_funcptr_for_type(TYPE) + fptr1 = self.make_destructor_funcptr_for_type(TYPE) fptr2 = self.make_custom_trace_funcptr_for_type(TYPE) assert not (fptr1 and fptr2), ( "type %r needs both a finalizer and a custom tracer" % (TYPE,)) if fptr1: - if is_lightweight: - kind_and_fptr = "light_finalizer", fptr1 - else: - kind_and_fptr = "finalizer", fptr1 + kind_and_fptr = "destructor", fptr1 elif fptr2: kind_and_fptr = "custom_trace", fptr2 else: @@ -393,9 +390,9 @@ self._special_funcptrs[TYPE] = kind_and_fptr return kind_and_fptr - def make_finalizer_funcptr_for_type(self, TYPE): + def make_destructor_funcptr_for_type(self, TYPE): # must be overridden for proper finalizer support - return None, False + return None def make_custom_trace_funcptr_for_type(self, TYPE): # must be overridden for proper custom tracer support diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -1,4 +1,4 @@ -from rpython.translator.backendopt.finalizer import FinalizerAnalyzer +from rpython.translator.backendopt.destructor import DestructorAnalyzer from rpython.rtyper.lltypesystem import lltype, llmemory, llheap from rpython.rtyper import llinterp from rpython.rtyper.annlowlevel import llhelper @@ -204,7 +204,7 @@ self.llinterp = llinterp super(DirectRunLayoutBuilder, self).__init__(GCClass, lltype2vtable) - def make_finalizer_funcptr_for_type(self, TYPE): + def make_destructor_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): @@ -212,10 +212,10 @@ DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] destrgraph = destrptr._obj.graph else: - return None, False + return None t = self.llinterp.typer.annotator.translator - light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) + DestructorAnalyzer(t).check_destructor(destrgraph) def ll_finalizer(addr, dummy): assert dummy == llmemory.NULL try: @@ -225,7 +225,7 @@ raise RuntimeError( "a finalizer raised an exception, shouldn't happen") return llmemory.NULL - return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light + return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer) def make_custom_trace_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -2,6 +2,7 @@ from rpython.tool.udir import udir from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib import rgc class SemiSpaceGCTestDefines: @@ -51,7 +52,8 @@ def __init__(self, key): self.key = key self.refs = [] - def __del__(self): + rgc.register_finalizer(self.finalize) + def finalize(self): assert state.age[self.key] == -1 state.age[self.key] = state.time state.progress = True @@ -113,8 +115,8 @@ return f - def test_finalizer_order(self): - res = self.run('finalizer_order') + def test_full_finalizer_order(self): + res = self.run('full_finalizer_order') if res != "ok": i, summary, msg = res.split('\n') i = int(i) diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -129,7 +129,7 @@ assert res == concat(100) #assert simulator.current_size - curr < 16000 * INT_SIZE / 4 - def test_finalizer(self): + def test_destructor(self): class B(object): pass b = B() @@ -153,88 +153,94 @@ res = self.interpret(f, [5]) assert res == 6 - def test_finalizer_calls_malloc(self): + def test_finalizer(self): class B(object): pass b = B() b.nextid = 0 + b.num_finalized = 0 + class A(object): + def __init__(self): + self.id = b.nextid + b.nextid += 1 + def finalizer(self): + b.num_finalized += 1 + def allocate(x): + i = 0 + while i < x: + i += 1 + a = A() + rgc.register_finalizer(a.finalizer) + def f(x): + allocate(x) + llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) + return b.num_finalized + res = self.interpret(f, [6]) + assert res == 6 + + def test_finalizer_and_destructor(self): + class B(object): + pass + b = B() + b.nextid = 0 + b.num_finalized = 0 b.num_deleted = 0 class A(object): def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): - b.num_deleted += 1 - C() - class C(A): + def finalizer(self): + assert n.num_deleted <= b.num_finalized + b.num_finalized += 1 def __del__(self): b.num_deleted += 1 def f(x): a = A() + rgc.register_finalizer(a.finalizer) i = 0 while i < x: i += 1 a = A() llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) - return b.num_deleted + return b.num_finalized * 100 + b.num_deleted res = self.interpret(f, [5]) - assert res == 12 + assert res == 606 - def test_finalizer_calls_collect(self): + def test_finalize_later(self): class B(object): pass b = B() b.nextid = 0 - b.num_deleted = 0 + b.num_finalized = 0 class A(object): def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): - b.num_deleted += 1 - llop.gc__collect(lltype.Void) + def finalizer(self): + b.num_finalized += 1 + if (b.num_finalized % 3) == 0: + raise rgc.FinalizeLater def f(x): a = A() + rgc.register_finalizer(a.finalizer) i = 0 while i < x: i += 1 a = A() llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) - return b.num_deleted + if b.num_finalized == 0: + llop.gc__collect(lltype.Void) + assert b.num_finalized == 3 + rgc.progress_through_finalizer_queue() + assert b.num_finalized == 6 + rgc.progress_through_finalizer_queue() + assert b.num_finalized == 8 + rgc.progress_through_finalizer_queue() + assert b.num_finalized == 8 res = self.interpret(f, [5]) - assert res == 6 - - def test_finalizer_resurrects(self): - class B(object): - pass - b = B() - b.nextid = 0 - b.num_deleted = 0 - class A(object): - def __init__(self): - self.id = b.nextid - b.nextid += 1 - def __del__(self): - b.num_deleted += 1 - b.a = self - def f(x): - a = A() - i = 0 - while i < x: - i += 1 - a = A() - llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) - aid = b.a.id - b.a = None - # check that __del__ is not called again - llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) - return b.num_deleted * 10 + aid + 100 * (b.a is None) - res = self.interpret(f, [5]) - assert 160 <= res <= 165 + assert res == 606 def test_custom_trace(self): from rpython.rtyper.annlowlevel import llhelper diff --git a/rpython/translator/backendopt/finalizer.py b/rpython/translator/backendopt/destructor.py rename from rpython/translator/backendopt/finalizer.py rename to rpython/translator/backendopt/destructor.py --- a/rpython/translator/backendopt/finalizer.py +++ b/rpython/translator/backendopt/destructor.py @@ -2,15 +2,12 @@ from rpython.translator.backendopt import graphanalyze from rpython.rtyper.lltypesystem import lltype -class FinalizerError(Exception): - """ __del__ marked as lightweight finalizer, but the analyzer did - not agree - """ +class DestructorError(Exception): + """The __del__() method contains unsupported operations""" -class FinalizerAnalyzer(graphanalyze.BoolGraphAnalyzer): - """ Analyzer that determines whether a finalizer is lightweight enough - so it can be called without all the complicated logic in the garbage - collector. The set of operations here is restrictive for a good reason +class DestructorAnalyzer(graphanalyze.BoolGraphAnalyzer): + """ Analyzer that checks if a destructor is lightweight enough for + RPython. The set of operations here is restrictive for a good reason - it's better to be safe. Specifically disallowed operations: * anything that escapes self @@ -20,12 +17,10 @@ 'direct_ptradd', 'force_cast', 'track_alloc_stop', 'raw_free'] - def analyze_light_finalizer(self, graph): + def check_destructor(self, graph): result = self.analyze_direct_call(graph) - if (result is self.top_result() and - getattr(graph.func, '_must_be_light_finalizer_', False)): - raise FinalizerError(FinalizerError.__doc__, graph) - return result + if result is self.top_result(): + raise DestructorError(DestructorError.__doc__, graph) def analyze_simple_operation(self, op, graphinfo): if op.opname in self.ok_operations: From noreply at buildbot.pypy.org Mon Mar 4 10:43:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 10:43:06 +0100 (CET) Subject: [pypy-commit] pypy default: Don't ever call makerepr()! That's always bogus. Message-ID: <20130304094306.0909D1C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61994:a6f10254f3ef Date: 2013-03-04 10:42 +0100 http://bitbucket.org/pypy/pypy/changeset/a6f10254f3ef/ Log: Don't ever call makerepr()! That's always bogus. diff --git a/rpython/rlib/rweakref.py b/rpython/rlib/rweakref.py --- a/rpython/rlib/rweakref.py +++ b/rpython/rlib/rweakref.py @@ -95,7 +95,7 @@ def rtyper_makerepr(self, rtyper): from rpython.rlib import _rweakvaldict return _rweakvaldict.WeakValueDictRepr(rtyper, - rtyper.makerepr(self.s_key)) + rtyper.getrepr(self.s_key)) def rtyper_makekey_ex(self, rtyper): return self.__class__, diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py --- a/rpython/rtyper/rint.py +++ b/rpython/rtyper/rint.py @@ -232,7 +232,7 @@ if not s_int1.nonneg or not s_int2.nonneg: raise TyperError("comparing a signed and an unsigned number") - repr = hop.rtyper.makerepr(annmodel.unionof(s_int1, s_int2)).as_int + repr = hop.rtyper.getrepr(annmodel.unionof(s_int1, s_int2)).as_int vlist = hop.inputargs(repr, repr) hop.exception_is_here() return hop.genop(repr.opprefix+func, vlist, resulttype=Bool) diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -162,7 +162,7 @@ def makekey(self, s_obj): return pair(self.type_system, s_obj).rtyper_makekey(self) - def makerepr(self, s_obj): + def _makerepr(self, s_obj): return pair(self.type_system, s_obj).rtyper_makerepr(self) def getrepr(self, s_obj): @@ -173,7 +173,7 @@ result = self.reprs[key] except KeyError: self.reprs[key] = None - result = self.makerepr(s_obj) + result = self._makerepr(s_obj) assert not isinstance(result.lowleveltype, ContainerType), ( "missing a Ptr in the type specification " "of %s:\n%r" % (s_obj, result.lowleveltype)) From noreply at buildbot.pypy.org Mon Mar 4 10:44:23 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 4 Mar 2013 10:44:23 +0100 (CET) Subject: [pypy-commit] pypy default: Small dotviewer fixes. Message-ID: <20130304094423.C41AB1C0175@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r61995:fc1de558db21 Date: 2013-03-04 09:06 +0100 http://bitbucket.org/pypy/pypy/changeset/fc1de558db21/ Log: Small dotviewer fixes. * use strunicode throughout, also in msgstruct. -> avoids "utf-8" in msgstuct.py * do not fail on garbage (+tests) diff --git a/dotviewer/msgstruct.py b/dotviewer/msgstruct.py --- a/dotviewer/msgstruct.py +++ b/dotviewer/msgstruct.py @@ -1,5 +1,6 @@ import sys, os from struct import pack, unpack, calcsize +from strunicode import forceencoded MAGIC = -0x3b83728b @@ -24,15 +25,10 @@ long_max = 2147483647 -def _encodeme(x): - if type(x) is unicode: - x = x.encode('utf-8') - return x - def message(tp, *values): #print >> sys.stderr, tp, values typecodes = [''] - values = map(_encodeme, values) + values = map(forceencoded, values) for v in values: if type(v) is str: typecodes.append('%ds' % len(v)) diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py --- a/dotviewer/strunicode.py +++ b/dotviewer/strunicode.py @@ -1,9 +1,15 @@ RAW_ENCODING = "utf-8" - +ENCODING_ERROR_HANDLING = "replace" def forceunicode(name): - return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + """ returns `name` as unicode, even if it wasn't before """ + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING, ENCODING_ERROR_HANDLING) def forcestr(name): - return name if isinstance(name, str) else name.encode(RAW_ENCODING) + """ returns `name` as (possibly `RAW_ENCODING` encoded) string, even if it wasn't before """ + return name if isinstance(name, str) else name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) + +def forceencoded(name): + """ returns `name` as encoded string if it was unicode before """ + return name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) if isinstance(name, unicode) else name diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py --- a/dotviewer/test/test_unicode_util.py +++ b/dotviewer/test/test_unicode_util.py @@ -3,7 +3,7 @@ # import py import codecs -from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode +from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode, forceencoded SOURCE1 = u"""digraph G{ λ -> b @@ -18,7 +18,7 @@ def test_idempotent(self): x = u"a" assert forceunicode(forcestr(x)) == x - + x = u"λ" assert forceunicode(forcestr(x)) == x @@ -40,7 +40,7 @@ x_u = forceunicode(x_e) assert forceunicode(x_u) == x_u - def test_file(self): + def test_file(self): udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) full_filename = str(udir.join(FILENAME)) f = codecs.open(full_filename, 'wb', RAW_ENCODING) @@ -55,3 +55,30 @@ f3.close() result = (c == SOURCE1) assert result + + def test_only_unicode_encode(self): + + sut = [1, u"a", "miau", u"λ"] + expected = [int, str, str , str ] + + results = map(forceencoded, sut) + + + for result, expected_type in zip(results, expected): + assert isinstance(result, expected_type) + + def test_forceunicode_should_not_fail(self): + + garbage = "\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage with a lambda + + result = forceunicode(garbage) + assert True, "should not raise" + + def test_forcestr_should_not_fail(self): + + garbage = u"\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage + + result = forcestr(garbage) + assert True, "should not raise" + + From noreply at buildbot.pypy.org Mon Mar 4 10:44:25 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 4 Mar 2013 10:44:25 +0100 (CET) Subject: [pypy-commit] pypy default: rename forceencoded to tryencode (as suggested by bdkearns) Message-ID: <20130304094425.31BAF1C0175@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r61996:3da1c6270c53 Date: 2013-03-04 10:27 +0100 http://bitbucket.org/pypy/pypy/changeset/3da1c6270c53/ Log: rename forceencoded to tryencode (as suggested by bdkearns) diff --git a/dotviewer/msgstruct.py b/dotviewer/msgstruct.py --- a/dotviewer/msgstruct.py +++ b/dotviewer/msgstruct.py @@ -1,6 +1,6 @@ import sys, os from struct import pack, unpack, calcsize -from strunicode import forceencoded +from strunicode import tryencode MAGIC = -0x3b83728b @@ -28,7 +28,7 @@ def message(tp, *values): #print >> sys.stderr, tp, values typecodes = [''] - values = map(forceencoded, values) + values = map(tryencode, values) for v in values: if type(v) is str: typecodes.append('%ds' % len(v)) diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py --- a/dotviewer/strunicode.py +++ b/dotviewer/strunicode.py @@ -10,6 +10,6 @@ """ returns `name` as (possibly `RAW_ENCODING` encoded) string, even if it wasn't before """ return name if isinstance(name, str) else name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) -def forceencoded(name): +def tryencode(name): """ returns `name` as encoded string if it was unicode before """ return name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) if isinstance(name, unicode) else name diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py --- a/dotviewer/test/test_unicode_util.py +++ b/dotviewer/test/test_unicode_util.py @@ -3,7 +3,7 @@ # import py import codecs -from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode, forceencoded +from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode, tryencode SOURCE1 = u"""digraph G{ λ -> b @@ -61,7 +61,7 @@ sut = [1, u"a", "miau", u"λ"] expected = [int, str, str , str ] - results = map(forceencoded, sut) + results = map(tryencode, sut) for result, expected_type in zip(results, expected): From noreply at buildbot.pypy.org Mon Mar 4 10:44:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 10:44:26 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in krono/pypy (pull request #130) Message-ID: <20130304094426.9E4D11C0175@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61997:ad521204bedf Date: 2013-03-04 01:43 -0800 http://bitbucket.org/pypy/pypy/changeset/ad521204bedf/ Log: Merged in krono/pypy (pull request #130) Small dotviewer fixes. diff --git a/dotviewer/msgstruct.py b/dotviewer/msgstruct.py --- a/dotviewer/msgstruct.py +++ b/dotviewer/msgstruct.py @@ -1,5 +1,6 @@ import sys, os from struct import pack, unpack, calcsize +from strunicode import tryencode MAGIC = -0x3b83728b @@ -24,15 +25,10 @@ long_max = 2147483647 -def _encodeme(x): - if type(x) is unicode: - x = x.encode('utf-8') - return x - def message(tp, *values): #print >> sys.stderr, tp, values typecodes = [''] - values = map(_encodeme, values) + values = map(tryencode, values) for v in values: if type(v) is str: typecodes.append('%ds' % len(v)) diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py --- a/dotviewer/strunicode.py +++ b/dotviewer/strunicode.py @@ -1,9 +1,15 @@ RAW_ENCODING = "utf-8" - +ENCODING_ERROR_HANDLING = "replace" def forceunicode(name): - return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + """ returns `name` as unicode, even if it wasn't before """ + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING, ENCODING_ERROR_HANDLING) def forcestr(name): - return name if isinstance(name, str) else name.encode(RAW_ENCODING) + """ returns `name` as (possibly `RAW_ENCODING` encoded) string, even if it wasn't before """ + return name if isinstance(name, str) else name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) + +def tryencode(name): + """ returns `name` as encoded string if it was unicode before """ + return name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) if isinstance(name, unicode) else name diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py --- a/dotviewer/test/test_unicode_util.py +++ b/dotviewer/test/test_unicode_util.py @@ -3,7 +3,7 @@ # import py import codecs -from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode +from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode, tryencode SOURCE1 = u"""digraph G{ λ -> b @@ -18,7 +18,7 @@ def test_idempotent(self): x = u"a" assert forceunicode(forcestr(x)) == x - + x = u"λ" assert forceunicode(forcestr(x)) == x @@ -40,7 +40,7 @@ x_u = forceunicode(x_e) assert forceunicode(x_u) == x_u - def test_file(self): + def test_file(self): udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) full_filename = str(udir.join(FILENAME)) f = codecs.open(full_filename, 'wb', RAW_ENCODING) @@ -55,3 +55,30 @@ f3.close() result = (c == SOURCE1) assert result + + def test_only_unicode_encode(self): + + sut = [1, u"a", "miau", u"λ"] + expected = [int, str, str , str ] + + results = map(tryencode, sut) + + + for result, expected_type in zip(results, expected): + assert isinstance(result, expected_type) + + def test_forceunicode_should_not_fail(self): + + garbage = "\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage with a lambda + + result = forceunicode(garbage) + assert True, "should not raise" + + def test_forcestr_should_not_fail(self): + + garbage = u"\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage + + result = forcestr(garbage) + assert True, "should not raise" + + From noreply at buildbot.pypy.org Mon Mar 4 10:52:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 10:52:18 +0100 (CET) Subject: [pypy-commit] pypy default: whitespace/comments Message-ID: <20130304095218.B17821C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61998:1bd1b46c3b04 Date: 2013-03-04 04:52 -0500 http://bitbucket.org/pypy/pypy/changeset/1bd1b46c3b04/ Log: whitespace/comments diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py --- a/dotviewer/strunicode.py +++ b/dotviewer/strunicode.py @@ -1,15 +1,17 @@ RAW_ENCODING = "utf-8" ENCODING_ERROR_HANDLING = "replace" + def forceunicode(name): """ returns `name` as unicode, even if it wasn't before """ return name if isinstance(name, unicode) else name.decode(RAW_ENCODING, ENCODING_ERROR_HANDLING) def forcestr(name): - """ returns `name` as (possibly `RAW_ENCODING` encoded) string, even if it wasn't before """ + """ returns `name` as string, even if it wasn't before """ return name if isinstance(name, str) else name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) + def tryencode(name): """ returns `name` as encoded string if it was unicode before """ return name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) if isinstance(name, unicode) else name diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py --- a/dotviewer/test/test_unicode_util.py +++ b/dotviewer/test/test_unicode_util.py @@ -57,28 +57,17 @@ assert result def test_only_unicode_encode(self): - sut = [1, u"a", "miau", u"λ"] - expected = [int, str, str , str ] + expected = [int, str, str, str ] results = map(tryencode, sut) - - for result, expected_type in zip(results, expected): assert isinstance(result, expected_type) def test_forceunicode_should_not_fail(self): - - garbage = "\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage with a lambda - - result = forceunicode(garbage) - assert True, "should not raise" + garbage = "\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage with a lambda + result = forceunicode(garbage) # should not raise def test_forcestr_should_not_fail(self): - - garbage = u"\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage - - result = forcestr(garbage) - assert True, "should not raise" - - + garbage = u"\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage + result = forcestr(garbage) # should not raise From noreply at buildbot.pypy.org Mon Mar 4 11:09:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Mar 2013 11:09:41 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: pfff Message-ID: <20130304100941.B373B1C010A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61999:0bed69cf536e Date: 2013-03-04 12:02 +0200 http://bitbucket.org/pypy/pypy/changeset/0bed69cf536e/ Log: pfff diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -113,6 +113,9 @@ elif fld == -3: (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -4 return obj_addr + getofs('jf_guard_exc') + elif fld == -4: + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -5 + return obj_addr + getofs('jf_forward') else: if not (obj_addr + getofs('jf_gcmap')).address[0]: return llmemory.NULL # done diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -296,20 +296,20 @@ assert all_addrs[counter] == frame_adr + jitframe.getofs(name) counter += 1 # gcpattern - assert all_addrs[4] == indexof(0) - assert all_addrs[5] == indexof(1) - assert all_addrs[6] == indexof(3) - assert all_addrs[7] == indexof(5) - assert all_addrs[8] == indexof(7) + assert all_addrs[5] == indexof(0) + assert all_addrs[6] == indexof(1) + assert all_addrs[7] == indexof(3) + assert all_addrs[8] == indexof(5) + assert all_addrs[9] == indexof(7) if sys.maxint == 2**31 - 1: - assert all_addrs[9] == indexof(31) - assert all_addrs[10] == indexof(33 + 32) + assert all_addrs[10] == indexof(31) + assert all_addrs[11] == indexof(33 + 32) else: - assert all_addrs[9] == indexof(63) - assert all_addrs[10] == indexof(65 + 64) + assert all_addrs[10] == indexof(63) + assert all_addrs[11] == indexof(65 + 64) - assert len(all_addrs) == 4 + 6 + 4 - # 4 static fields, 4 addresses from gcmap, 2 from gcpattern + assert len(all_addrs) == 5 + 6 + 4 + # 5 static fields, 4 addresses from gcmap, 2 from gcpattern lltype.free(frame_info, flavor='raw') lltype.free(frame.jf_gcmap, flavor='raw') From noreply at buildbot.pypy.org Mon Mar 4 11:09:43 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Mar 2013 11:09:43 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130304100943.49E8E1C010A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62000:2bf49cfc5d1e Date: 2013-03-04 12:08 +0200 http://bitbucket.org/pypy/pypy/changeset/2bf49cfc5d1e/ Log: merge diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -19,11 +19,6 @@ # - normal: self.sthread != None, not is_empty_handle(self.h) # - finished: self.sthread != None, is_empty_handle(self.h) - def __del__(self): - sthread = self.sthread - if sthread is not None and not sthread.is_empty_handle(self.h): - sthread.destroy(self.h) - def check_sthread(self): ec = self.space.getexecutioncontext() if ec.stacklet_thread is not self.sthread: diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -341,7 +341,7 @@ break obj = self.run_finalizers.popleft() finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj, llmemory.NULL) + finalizer(obj) finally: self.finalizer_lock_count -= 1 diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1890,7 +1890,7 @@ if not self.is_forwarded(obj): finalizer = self.getlightfinalizer(self.get_type_id(obj)) ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + finalizer(obj) else: obj = self.get_forwarding_address(obj) self.old_objects_with_light_finalizers.append(obj) @@ -1911,7 +1911,7 @@ # dying finalizer = self.getlightfinalizer(self.get_type_id(obj)) ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + finalizer(obj) self.old_objects_with_light_finalizers.delete() self.old_objects_with_light_finalizers = new_objects diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py --- a/rpython/memory/gc/semispace.py +++ b/rpython/memory/gc/semispace.py @@ -494,7 +494,7 @@ new_objects.append(self.get_forwarding_address(obj)) else: finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj, llmemory.NULL) + finalizer(obj) self.objects_with_light_finalizers.delete() self.objects_with_light_finalizers = new_objects 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 @@ -139,11 +139,13 @@ if self._with_jit: jit2gc = gctransformer.translator._jit2gc self.frame_tid = jit2gc['frame_tid'] + self.gctransformer = gctransformer def need_stacklet_support(self, gctransformer, getfn): # stacklet support: BIG HACK for rlib.rstacklet from rpython.rlib import _stacklet_asmgcc _stacklet_asmgcc._asmstackrootwalker = self # as a global! argh + _stacklet_asmgcc.complete_destrptr(gctransformer) def need_thread_support(self, gctransformer, getfn): # Threads supported "out of the box" by the rest of the code. diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -645,11 +645,9 @@ c_type_id = rmodel.inputconst(TYPE_ID, type_id) info = self.layoutbuilder.get_info(type_id) c_size = rmodel.inputconst(lltype.Signed, info.fixedsize) - kind_and_fptr = self.special_funcptr_for_type(TYPE) - has_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "finalizer") - has_light_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "light_finalizer") + fptrs = self.special_funcptr_for_type(TYPE) + has_finalizer = "finalizer" in fptrs + has_light_finalizer = "light_finalizer" in fptrs if has_light_finalizer: has_finalizer = True c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer) @@ -798,11 +796,6 @@ [self.root_walker.gc_shadowstackref_context_ptr, op.args[0]], resultvar=op.result) - def gct_gc_shadowstackref_destroy(self, hop): - op = hop.spaceop - hop.genop("direct_call", - [self.root_walker.gc_shadowstackref_destroy_ptr, op.args[0]]) - def gct_gc_save_current_state_away(self, hop): op = hop.spaceop hop.genop("direct_call", @@ -1213,8 +1206,8 @@ None) def has_light_finalizer(self, TYPE): - special = self.special_funcptr_for_type(TYPE) - return special is not None and special[0] == 'light_finalizer' + fptrs = self.special_funcptr_for_type(TYPE) + return "light_finalizer" in fptrs def has_custom_trace(self, TYPE): rtti = get_rtti(TYPE) @@ -1228,14 +1221,16 @@ destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] typename = TYPE.__name__ - def ll_finalizer(addr, ignored): + def ll_finalizer(addr): v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) - return llmemory.NULL fptr = self.transformer.annotate_finalizer(ll_finalizer, - [llmemory.Address, llmemory.Address], llmemory.Address) - g = destrptr._obj.graph - light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) + [llmemory.Address], lltype.Void) + try: + g = destrptr._obj.graph + light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) + except lltype.DelayedPointer: + light = False # XXX bah, too bad return fptr, light def make_custom_trace_funcptr_for_type(self, TYPE): diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -1,6 +1,7 @@ from rpython.annotator import model as annmodel from rpython.rlib.debug import ll_assert from rpython.rlib.nonconst import NonConstant +from rpython.rlib import rgc from rpython.rtyper import rmodel from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, llmemory @@ -226,10 +227,6 @@ ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) return ssref.context - def gc_shadowstackref_destroy(gcref): - ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) - shadow_stack_pool.destroy(ssref) - def gc_save_current_state_away(gcref, ncontext): ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) shadow_stack_pool.save_current_state_away(ssref, ncontext) @@ -252,9 +249,6 @@ self.gc_shadowstackref_context_ptr = getfn(gc_shadowstackref_context, [s_gcref], s_addr, inline=True) - self.gc_shadowstackref_destroy_ptr = getfn(gc_shadowstackref_destroy, - [s_gcref], annmodel.s_None, - inline=True) self.gc_save_current_state_away_ptr = getfn(gc_save_current_state_away, [s_gcref, s_addr], annmodel.s_None, @@ -340,10 +334,6 @@ self.gcdata.root_stack_top = self.unused_full_stack self.unused_full_stack = llmemory.NULL - def destroy(self, shadowstackref): - llmemory.raw_free(shadowstackref.base) - self._cleanup(shadowstackref) - def _cleanup(self, shadowstackref): shadowstackref.base = llmemory.NULL shadowstackref.top = llmemory.NULL @@ -402,7 +392,20 @@ CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) - lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr) + + def shadowstack_destructor(shadowstackref): + from rpython.rlib import _rffi_stacklet as _c + h = shadowstackref.context + h = llmemory.cast_adr_to_ptr(h, _c.handle) + llmemory.raw_free(shadowstackref.base) + if h: + _c.destroy(h) + + destrptr = gctransformer.annotate_helper(shadowstack_destructor, + [SHADOWSTACKREFPTR], lltype.Void) + + lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr, + destrptr=destrptr) gctransformer._SHADOWSTACKREF = SHADOWSTACKREF return SHADOWSTACKREF diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -17,20 +17,22 @@ OFFSETS_TO_GC_PTR = lltype.Array(lltype.Signed) - # When used as a finalizer, the following functions only take one - # address and ignore the second, and return NULL. When used as a - # custom tracer (CT), it enumerates the addresses that contain GCREFs. + # A custom tracer (CT), enumerates the addresses that contain GCREFs. # It is called with the object as first argument, and the previous # returned address (or NULL the first time) as the second argument. - FINALIZER_OR_CT_FUNC = lltype.FuncType([llmemory.Address, - llmemory.Address], - llmemory.Address) - FINALIZER_OR_CT = lltype.Ptr(FINALIZER_OR_CT_FUNC) + FINALIZER_FUNC = lltype.FuncType([llmemory.Address], lltype.Void) + CUSTOMTRACER_FUNC = lltype.FuncType([llmemory.Address, llmemory.Address], + llmemory.Address) + FINALIZER = lltype.Ptr(FINALIZER_FUNC) + CUSTOMTRACER = lltype.Ptr(CUSTOMTRACER_FUNC) + EXTRA = lltype.Struct("type_info_extra", + ('finalizer', FINALIZER), + ('customtracer', CUSTOMTRACER)) # structure describing the layout of a typeid TYPE_INFO = lltype.Struct("type_info", ("infobits", lltype.Signed), # combination of the T_xxx consts - ("finalizer_or_customtrace", FINALIZER_OR_CT), + ("extra", lltype.Ptr(EXTRA)), ("fixedsize", lltype.Signed), ("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)), hints={'immutable': True}, @@ -80,16 +82,16 @@ def q_finalizer(self, typeid): typeinfo = self.get(typeid) if typeinfo.infobits & T_HAS_FINALIZER: - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.finalizer else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.FINALIZER_FUNC) def q_light_finalizer(self, typeid): typeinfo = self.get(typeid) if typeinfo.infobits & T_HAS_LIGHTWEIGHT_FINALIZER: - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.finalizer else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.FINALIZER_FUNC) def q_offsets_to_gc_pointers(self, typeid): return self.get(typeid).ofstoptrs @@ -131,7 +133,7 @@ ll_assert(self.q_has_custom_trace(typeid), "T_HAS_CUSTOM_TRACE missing") typeinfo = self.get(typeid) - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.customtracer def q_fast_path_tracing(self, typeid): # return True if none of the flags T_HAS_GCPTR_IN_VARSIZE, @@ -196,18 +198,20 @@ infobits = index info.ofstoptrs = builder.offsets2table(offsets, TYPE) # - kind_and_fptr = builder.special_funcptr_for_type(TYPE) - if kind_and_fptr is not None: - kind, fptr = kind_and_fptr - info.finalizer_or_customtrace = fptr - if kind == "finalizer": + fptrs = builder.special_funcptr_for_type(TYPE) + if fptrs: + extra = lltype.malloc(GCData.EXTRA, zero=True, immortal=True, + flavor='raw') + if "finalizer" in fptrs: + extra.finalizer = fptrs["finalizer"] infobits |= T_HAS_FINALIZER - elif kind == 'light_finalizer': + if "light_finalizer" in fptrs: + extra.finalizer = fptrs["light_finalizer"] infobits |= T_HAS_FINALIZER | T_HAS_LIGHTWEIGHT_FINALIZER - elif kind == "custom_trace": + if "custom_trace" in fptrs: + extra.customtracer = fptrs["custom_trace"] infobits |= T_HAS_CUSTOM_TRACE - else: - assert 0, kind + info.extra = extra # if not TYPE._is_varsize(): info.fixedsize = llarena.round_up_for_allocation( @@ -379,19 +383,16 @@ return self._special_funcptrs[TYPE] fptr1, is_lightweight = self.make_finalizer_funcptr_for_type(TYPE) fptr2 = self.make_custom_trace_funcptr_for_type(TYPE) - assert not (fptr1 and fptr2), ( - "type %r needs both a finalizer and a custom tracer" % (TYPE,)) + result = {} if fptr1: if is_lightweight: - kind_and_fptr = "light_finalizer", fptr1 + result["light_finalizer"] = fptr1 else: - kind_and_fptr = "finalizer", fptr1 - elif fptr2: - kind_and_fptr = "custom_trace", fptr2 - else: - kind_and_fptr = None - self._special_funcptrs[TYPE] = kind_and_fptr - return kind_and_fptr + result["finalizer"] = fptr1 + if fptr2: + result["custom_trace"] = fptr2 + self._special_funcptrs[TYPE] = result + return result def make_finalizer_funcptr_for_type(self, TYPE): # must be overridden for proper finalizer support diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -216,16 +216,14 @@ t = self.llinterp.typer.annotator.translator light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) - def ll_finalizer(addr, dummy): - assert dummy == llmemory.NULL + def ll_finalizer(addr): try: v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) self.llinterp.eval_graph(destrgraph, [v], recursive=True) except llinterp.LLException: raise RuntimeError( "a finalizer raised an exception, shouldn't happen") - return llmemory.NULL - return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light + return llhelper(gctypelayout.GCData.FINALIZER, ll_finalizer), light def make_custom_trace_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti diff --git a/rpython/rlib/_rffi_stacklet.py b/rpython/rlib/_rffi_stacklet.py --- a/rpython/rlib/_rffi_stacklet.py +++ b/rpython/rlib/_rffi_stacklet.py @@ -56,9 +56,9 @@ new = llexternal('stacklet_new', [thread_handle, run_fn, llmemory.Address], handle, random_effects_on_gcobjs=True) -switch = llexternal('stacklet_switch', [thread_handle, handle], handle, +switch = llexternal('stacklet_switch', [handle], handle, random_effects_on_gcobjs=True) -destroy = llexternal('stacklet_destroy', [thread_handle, handle], lltype.Void) +destroy = llexternal('stacklet_destroy', [handle], lltype.Void) _translate_pointer = llexternal("_stacklet_translate_pointer", [llmemory.Address, llmemory.Address], diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -1,8 +1,9 @@ -from rpython.rlib import _rffi_stacklet as _c from rpython.rlib.debug import ll_assert from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.annlowlevel import llhelper +from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator +from rpython.annotator import model as annmodel +from rpython.rlib import _rffi_stacklet as _c _asmstackrootwalker = None # BIG HACK: monkey-patched by asmgcroot.py @@ -129,11 +130,26 @@ return _stackletrootwalker get_stackletrootwalker._annspecialcase_ = 'specialize:memo' +def complete_destrptr(gctransformer): + translator = gctransformer.translator + mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) + args_s = [annmodel.lltype_to_annotation(lltype.Ptr(SUSPSTACK))] + s_result = annmodel.s_None + destrptr = mixlevelannotator.delayedfunction(suspstack_destructor, + args_s, s_result) + mixlevelannotator.finish() + lltype.attachRuntimeTypeInfo(SUSPSTACK, destrptr=destrptr) + def customtrace(obj, prev): stackletrootwalker = get_stackletrootwalker() return stackletrootwalker.next(obj, prev) +def suspstack_destructor(suspstack): + h = suspstack.handle + if h: + _c.destroy(h) + SUSPSTACK = lltype.GcStruct('SuspStack', ('handle', _c.handle), @@ -169,7 +185,7 @@ # stacklet with stacklet_new(). If this call fails, then we # are just returning NULL. _stack_just_closed() - return _c.new(gcrootfinder.thrd, llhelper(_c.run_fn, _new_runfn), + return _c.new(gcrootfinder.newthrd, llhelper(_c.run_fn, _new_runfn), llmemory.NULL) def _stack_just_closed(): @@ -216,7 +232,7 @@ # # gcrootfinder.suspstack.anchor is left with the anchor of the # previous place (i.e. before the call to switch()). - h2 = _c.switch(gcrootfinder.thrd, h) + h2 = _c.switch(h) # if not h2: # MemoryError: restore gcrootfinder.suspstack.anchor = oldanchor @@ -228,7 +244,7 @@ suspstack = NULL_SUSPSTACK def new(self, thrd, callback, arg): - self.thrd = thrd._thrd + self.newthrd = thrd._thrd self.runfn = callback self.arg = arg # make a fresh new clean SUSPSTACK @@ -240,8 +256,7 @@ alternateanchor) return self.get_result_suspstack(h) - def switch(self, thrd, suspstack): - self.thrd = thrd._thrd + def switch(self, suspstack): self.suspstack = suspstack h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _switch_callback), alternateanchor) @@ -267,11 +282,6 @@ # This is a return that gave us a real handle. Store it. return self.attach_handle_on_suspstack(h) - def destroy(self, thrd, suspstack): - h = suspstack.handle - suspstack.handle = _c.null_handle - _c.destroy(thrd._thrd, h) - def is_empty_handle(self, suspstack): return not suspstack diff --git a/rpython/rlib/_stacklet_shadowstack.py b/rpython/rlib/_stacklet_shadowstack.py --- a/rpython/rlib/_stacklet_shadowstack.py +++ b/rpython/rlib/_stacklet_shadowstack.py @@ -79,25 +79,18 @@ return get_result_suspstack(h) new._dont_inline_ = True - def switch(thrd, suspstack): + def switch(suspstack): # suspstack has a handle to target, i.e. where to switch to ll_assert(suspstack != gcrootfinder.oldsuspstack, "stacklet: invalid use") gcrootfinder.newsuspstack = suspstack - thread_handle = thrd._thrd h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) h = llmemory.cast_adr_to_ptr(h, _c.handle) prepare_old_suspstack() - h = _c.switch(thread_handle, h) + h = _c.switch(h) return get_result_suspstack(h) switch._dont_inline_ = True - def destroy(thrd, suspstack): - h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) - h = llmemory.cast_adr_to_ptr(h, _c.handle) - llop.gc_shadowstackref_destroy(lltype.Void, suspstack) - _c.destroy(thrd._thrd, h) - def is_empty_handle(suspstack): return not suspstack diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py --- a/rpython/rlib/rstacklet.py +++ b/rpython/rlib/rstacklet.py @@ -34,17 +34,11 @@ def switch(self, stacklet): if DEBUG: debug.remove(stacklet) - h = self._gcrootfinder.switch(self, stacklet) + h = self._gcrootfinder.switch(stacklet) if DEBUG: debug.add(h) return h - @jit.dont_look_inside - def destroy(self, stacklet): - if DEBUG: - debug.remove(stacklet) - self._gcrootfinder.destroy(self, stacklet) - def is_empty_handle(self, stacklet): # note that "being an empty handle" and being equal to # "get_null_handle()" may be the same, or not; don't rely on it diff --git a/rpython/rlib/test/test_rstacklet.py b/rpython/rlib/test/test_rstacklet.py --- a/rpython/rlib/test/test_rstacklet.py +++ b/rpython/rlib/test/test_rstacklet.py @@ -6,7 +6,7 @@ except CompilationError, e: py.test.skip("cannot import rstacklet: %s" % e) -from rpython.rlib import rrandom +from rpython.rlib import rrandom, rgc from rpython.rlib.rarithmetic import intmask from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.c.test.test_standalone import StandaloneTests @@ -72,7 +72,9 @@ self.status = 0 h = self.sthread.new(switchbackonce_callback, rffi.cast(llmemory.Address, 321)) - self.sthread.destroy(h) + # 'h' ignored + if (i % 5000) == 2500: + rgc.collect() def any_alive(self): for task in self.tasks: diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -890,8 +890,6 @@ raise NotImplementedError("gc_shadowstackref_new") def op_gc_shadowstackref_context(self): raise NotImplementedError("gc_shadowstackref_context") - def op_gc_shadowstackref_destroy(self): - raise NotImplementedError("gc_shadowstackref_destroy") def op_gc_save_current_state_away(self): raise NotImplementedError("gc_save_current_state_away") def op_gc_forget_current_state(self): diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -518,7 +518,6 @@ # for stacklet+shadowstack support 'gc_shadowstackref_new': LLOp(canmallocgc=True), 'gc_shadowstackref_context': LLOp(), - 'gc_shadowstackref_destroy': LLOp(), 'gc_save_current_state_away': LLOp(), 'gc_forget_current_state': LLOp(), 'gc_restore_state_from': LLOp(), diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py --- a/rpython/translator/c/gc.py +++ b/rpython/translator/c/gc.py @@ -313,19 +313,19 @@ def struct_setup(self, structdefnode, rtti): if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): - destrptr = rtti._obj.destructor_funcptr + gctransf = self.db.gctransformer + TYPE = structdefnode.STRUCT + fptrs = gctransf.special_funcptr_for_type(TYPE) # make sure this is seen by the database early, i.e. before # finish_helpers() on the gctransformer + destrptr = rtti._obj.destructor_funcptr self.db.get(destrptr) # the following, on the other hand, will only discover ll_finalizer # helpers. The get() sees and records a delayed pointer. It is # still important to see it so that it can be followed as soon as # the mixlevelannotator resolves it. - gctransf = self.db.gctransformer - TYPE = structdefnode.STRUCT - kind_and_fptr = gctransf.special_funcptr_for_type(TYPE) - if kind_and_fptr: - self.db.get(kind_and_fptr[1]) + for fptr in fptrs.values(): + self.db.get(fptr) def array_setup(self, arraydefnode): pass diff --git a/rpython/translator/c/src/stacklet/stacklet.c b/rpython/translator/c/src/stacklet/stacklet.c --- a/rpython/translator/c/src/stacklet/stacklet.c +++ b/rpython/translator/c/src/stacklet/stacklet.c @@ -52,6 +52,8 @@ * main stack. */ struct stacklet_s *stack_prev; + + stacklet_thread_handle stack_thrd; /* the thread where the stacklet is */ }; void *(*_stacklet_switchstack)(void*(*)(void*, void*), @@ -132,6 +134,7 @@ stacklet->stack_stop = thrd->g_current_stack_stop; stacklet->stack_saved = 0; stacklet->stack_prev = thrd->g_stack_chain_head; + stacklet->stack_thrd = thrd; thrd->g_stack_chain_head = stacklet; return 0; } @@ -293,10 +296,10 @@ return thrd->g_source; } -stacklet_handle stacklet_switch(stacklet_thread_handle thrd, - stacklet_handle target) +stacklet_handle stacklet_switch(stacklet_handle target) { long stackmarker; + stacklet_thread_handle thrd = target->stack_thrd; if (thrd->g_current_stack_stop <= (char *)&stackmarker) thrd->g_current_stack_stop = ((char *)&stackmarker) + 1; @@ -305,15 +308,23 @@ return thrd->g_source; } -void stacklet_destroy(stacklet_thread_handle thrd, stacklet_handle target) +void stacklet_destroy(stacklet_handle target) { - /* remove 'target' from the chained list 'unsaved_stack', if it is there */ - struct stacklet_s **pp = &thrd->g_stack_chain_head; - for (; *pp != NULL; pp = &(*pp)->stack_prev) - if (*pp == target) { - *pp = target->stack_prev; - break; - } + if (target->stack_prev != NULL) { + /* 'target' appears to be in the chained list 'unsaved_stack', + so remove it from there. Note that if 'thrd' was already + deleted, it means that we left the thread and all stacklets + still in the thread should be fully copied away from the + stack --- so should have stack_prev == NULL. In this case + we don't even read 'stack_thrd', already deallocated. */ + stacklet_thread_handle thrd = target->stack_thrd; + struct stacklet_s **pp = &thrd->g_stack_chain_head; + for (; *pp != NULL; pp = &(*pp)->stack_prev) + if (*pp == target) { + *pp = target->stack_prev; + break; + } + } free(target); } diff --git a/rpython/translator/c/src/stacklet/stacklet.h b/rpython/translator/c/src/stacklet/stacklet.h --- a/rpython/translator/c/src/stacklet/stacklet.h +++ b/rpython/translator/c/src/stacklet/stacklet.h @@ -44,13 +44,12 @@ * Don't call this with an already-used target, with EMPTY_STACKLET_HANDLE, * or with a stack handle from another thread (in multithreaded apps). */ -stacklet_handle stacklet_switch(stacklet_thread_handle thrd, - stacklet_handle target); +stacklet_handle stacklet_switch(stacklet_handle target); /* Delete a stack handle without resuming it at all. * (This works even if the stack handle is of a different thread) */ -void stacklet_destroy(stacklet_thread_handle thrd, stacklet_handle target); +void stacklet_destroy(stacklet_handle target); /* stacklet_handle _stacklet_switch_to_copy(stacklet_handle) --- later */ From noreply at buildbot.pypy.org Mon Mar 4 11:23:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 11:23:30 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix: for debugging check we verify that ebp points to a JITFRAME here; Message-ID: <20130304102330.22BBB1C3962@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r62001:53913ed189c9 Date: 2013-03-04 11:17 +0100 http://bitbucket.org/pypy/pypy/changeset/53913ed189c9/ Log: Fix: for debugging check we verify that ebp points to a JITFRAME here; but it may actually point to an already-forwarded object at this point. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -940,6 +940,11 @@ def get_forwarding_address(self, obj): return llmemory.cast_adr_to_ptr(obj, FORWARDSTUBPTR).forw + def get_possibly_forwarded_type_id(self, obj): + if self.is_in_nursery(obj) and self.is_forwarded(obj): + obj = self.get_forwarding_address(obj) + return self.get_type_id(obj) + def get_total_memory_used(self): """Return the total memory used, not counting any object in the nursery: only objects in the ArenaCollection or raw-malloced. diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py --- a/rpython/memory/gc/semispace.py +++ b/rpython/memory/gc/semispace.py @@ -438,6 +438,12 @@ def visit_external_object(self, obj): pass # hook for the HybridGC + def get_possibly_forwarded_type_id(self, obj): + tid = self.header(obj).tid + if self.is_forwarded(obj) and not (tid & GCFLAG_EXTERNAL): + obj = self.get_forwarding_address(obj) + return self.get_type_id(obj) + def set_forwarding_address(self, obj, newobj, objsize): # To mark an object as forwarded, we set the GCFLAG_FORWARDED and # overwrite the object with a FORWARDSTUB. Doing so is a bit 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 @@ -413,7 +413,7 @@ # to a JITFRAME object. from rpython.jit.backend.llsupport.jitframe import STACK_DEPTH_OFS - tid = self.gc.get_type_id(ebp_in_caller) + tid = self.gc.get_possibly_forwarded_type_id(ebp_in_caller) ll_assert(rffi.cast(lltype.Signed, tid) == rffi.cast(lltype.Signed, self.frame_tid), "found a stack frame that does not belong " From noreply at buildbot.pypy.org Mon Mar 4 11:23:31 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 11:23:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130304102331.6CBDD1C3962@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r62002:b78f3e5cc346 Date: 2013-03-04 11:18 +0100 http://bitbucket.org/pypy/pypy/changeset/b78f3e5cc346/ Log: merge heads diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -113,6 +113,9 @@ elif fld == -3: (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -4 return obj_addr + getofs('jf_guard_exc') + elif fld == -4: + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -5 + return obj_addr + getofs('jf_forward') else: if not (obj_addr + getofs('jf_gcmap')).address[0]: return llmemory.NULL # done diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -296,20 +296,20 @@ assert all_addrs[counter] == frame_adr + jitframe.getofs(name) counter += 1 # gcpattern - assert all_addrs[4] == indexof(0) - assert all_addrs[5] == indexof(1) - assert all_addrs[6] == indexof(3) - assert all_addrs[7] == indexof(5) - assert all_addrs[8] == indexof(7) + assert all_addrs[5] == indexof(0) + assert all_addrs[6] == indexof(1) + assert all_addrs[7] == indexof(3) + assert all_addrs[8] == indexof(5) + assert all_addrs[9] == indexof(7) if sys.maxint == 2**31 - 1: - assert all_addrs[9] == indexof(31) - assert all_addrs[10] == indexof(33 + 32) + assert all_addrs[10] == indexof(31) + assert all_addrs[11] == indexof(33 + 32) else: - assert all_addrs[9] == indexof(63) - assert all_addrs[10] == indexof(65 + 64) + assert all_addrs[10] == indexof(63) + assert all_addrs[11] == indexof(65 + 64) - assert len(all_addrs) == 4 + 6 + 4 - # 4 static fields, 4 addresses from gcmap, 2 from gcpattern + assert len(all_addrs) == 5 + 6 + 4 + # 5 static fields, 4 addresses from gcmap, 2 from gcpattern lltype.free(frame_info, flavor='raw') lltype.free(frame.jf_gcmap, flavor='raw') From noreply at buildbot.pypy.org Mon Mar 4 11:24:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Mar 2013 11:24:37 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: reset the frame on reallocation Message-ID: <20130304102437.7DB351C3962@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62003:d7527e71a440 Date: 2013-03-04 12:24 +0200 http://bitbucket.org/pypy/pypy/changeset/d7527e71a440/ Log: reset the frame on reallocation diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -92,6 +92,7 @@ i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] + frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc From noreply at buildbot.pypy.org Mon Mar 4 11:33:06 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 4 Mar 2013 11:33:06 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix translation (?). Message-ID: <20130304103306.919291C0498@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r62004:dff1263c2d5e Date: 2013-03-04 11:32 +0100 http://bitbucket.org/pypy/pypy/changeset/dff1263c2d5e/ Log: Fix translation (?). diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -210,9 +210,7 @@ ovf_msg = "long too big to convert" def is_zero(space, w_ob): - return ((space.isinstance_w(w_ob, space.w_int) or - space.isinstance_w(w_ob, space.w_long)) - and not space.is_true(w_ob)) + return space.isinstance_w(w_ob, space.w_int) and not space.is_true(w_ob) # ____________________________________________________________ From noreply at buildbot.pypy.org Mon Mar 4 11:51:57 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 4 Mar 2013 11:51:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20130304105157.35D4A1C0313@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r62005:ed5327d22e7c Date: 2013-03-04 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/ed5327d22e7c/ Log: hg merge default diff --git a/dotviewer/msgstruct.py b/dotviewer/msgstruct.py --- a/dotviewer/msgstruct.py +++ b/dotviewer/msgstruct.py @@ -1,5 +1,6 @@ import sys, os from struct import pack, unpack, calcsize +from strunicode import tryencode MAGIC = -0x3b83728b @@ -24,15 +25,10 @@ long_max = 2147483647 -def _encodeme(x): - if type(x) is unicode: - x = x.encode('utf-8') - return x - def message(tp, *values): #print >> sys.stderr, tp, values typecodes = [''] - values = map(_encodeme, values) + values = map(tryencode, values) for v in values: if type(v) is str: typecodes.append('%ds' % len(v)) diff --git a/dotviewer/strunicode.py b/dotviewer/strunicode.py --- a/dotviewer/strunicode.py +++ b/dotviewer/strunicode.py @@ -1,9 +1,17 @@ RAW_ENCODING = "utf-8" +ENCODING_ERROR_HANDLING = "replace" def forceunicode(name): - return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + """ returns `name` as unicode, even if it wasn't before """ + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING, ENCODING_ERROR_HANDLING) def forcestr(name): - return name if isinstance(name, str) else name.encode(RAW_ENCODING) + """ returns `name` as string, even if it wasn't before """ + return name if isinstance(name, str) else name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) + + +def tryencode(name): + """ returns `name` as encoded string if it was unicode before """ + return name.encode(RAW_ENCODING, ENCODING_ERROR_HANDLING) if isinstance(name, unicode) else name diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py --- a/dotviewer/test/test_interactive_unicode.py +++ b/dotviewer/test/test_interactive_unicode.py @@ -4,7 +4,7 @@ import py import sys, os, signal, thread, time, codecs from dotviewer.conftest import option -from dotviewer.drawgraph import RAW_ENCODING +from dotviewer.strunicode import RAW_ENCODING SOURCE1 = u"""digraph G{ λ -> b diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py --- a/dotviewer/test/test_unicode_util.py +++ b/dotviewer/test/test_unicode_util.py @@ -3,7 +3,7 @@ # import py import codecs -from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode +from dotviewer.strunicode import RAW_ENCODING, forcestr, forceunicode, tryencode SOURCE1 = u"""digraph G{ λ -> b @@ -18,7 +18,7 @@ def test_idempotent(self): x = u"a" assert forceunicode(forcestr(x)) == x - + x = u"λ" assert forceunicode(forcestr(x)) == x @@ -40,7 +40,7 @@ x_u = forceunicode(x_e) assert forceunicode(x_u) == x_u - def test_file(self): + def test_file(self): udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) full_filename = str(udir.join(FILENAME)) f = codecs.open(full_filename, 'wb', RAW_ENCODING) @@ -55,3 +55,19 @@ f3.close() result = (c == SOURCE1) assert result + + def test_only_unicode_encode(self): + sut = [1, u"a", "miau", u"λ"] + expected = [int, str, str, str ] + + results = map(tryencode, sut) + for result, expected_type in zip(results, expected): + assert isinstance(result, expected_type) + + def test_forceunicode_should_not_fail(self): + garbage = "\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage with a lambda + result = forceunicode(garbage) # should not raise + + def test_forcestr_should_not_fail(self): + garbage = u"\xef\xff\xbb\xbf\xce\xbb\xff\xff" # garbage + result = forcestr(garbage) # should not raise diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py --- a/pypy/module/select/test/test_kqueue.py +++ b/pypy/module/select/test/test_kqueue.py @@ -101,10 +101,9 @@ try: client.connect(("127.0.0.1", server_socket.getsockname()[1])) except socket.error as e: - if 'bsd' in sys.platform: - assert e.args[0] == errno.ENOENT - else: - assert e.args[0] == errno.EINPROGRESS + assert e.args[0] == errno.EINPROGRESS + else: + assert False, "EINPROGRESS not raised" server, addr = server_socket.accept() if sys.platform.startswith("darwin"): diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py --- a/pypy/module/select/test/test_select.py +++ b/pypy/module/select/test/test_select.py @@ -193,29 +193,12 @@ readend, writeend = self.getpair() readend.close() try: - iwtd, owtd, ewtd = select.select([], [writeend], []) - assert owtd == [writeend] - assert iwtd == ewtd == [] + iwtd, owtd, ewtd = select.select([writeend], [writeend], [writeend]) + assert iwtd == owtd == [writeend] + assert ewtd == [] finally: writeend.close() - def test_select_bug(self): - import select, os - if not hasattr(os, 'fork'): - skip("no fork() on this platform") - read, write = os.pipe() - pid = os.fork() - if pid == 0: - os._exit(0) - else: - os.close(read) - os.waitpid(pid, 0) - res = select.select([write], [write], [write]) - assert len(res[0]) == 1 - assert len(res[1]) == 1 - assert len(res[2]) == 0 - assert res[0][0] == res[1][0] - def test_poll(self): import select if not hasattr(select, 'poll'): diff --git a/pypy/module/test_lib_pypy/test_os_wait.py b/pypy/module/test_lib_pypy/test_os_wait.py --- a/pypy/module/test_lib_pypy/test_os_wait.py +++ b/pypy/module/test_lib_pypy/test_os_wait.py @@ -4,9 +4,8 @@ import os -from lib_pypy._pypy_wait import wait3, wait4 - if hasattr(os, 'wait3'): + from lib_pypy._pypy_wait import wait3 def test_os_wait3(): exit_status = 0x33 @@ -25,6 +24,7 @@ assert isinstance(rusage.ru_maxrss, int) if hasattr(os, 'wait4'): + from lib_pypy._pypy_wait import wait4 def test_os_wait4(): exit_status = 0x33 diff --git a/rpython/rlib/rweakref.py b/rpython/rlib/rweakref.py --- a/rpython/rlib/rweakref.py +++ b/rpython/rlib/rweakref.py @@ -95,7 +95,7 @@ def rtyper_makerepr(self, rtyper): from rpython.rlib import _rweakvaldict return _rweakvaldict.WeakValueDictRepr(rtyper, - rtyper.makerepr(self.s_key)) + rtyper.getrepr(self.s_key)) def rtyper_makekey_ex(self, rtyper): return self.__class__, diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -367,7 +367,6 @@ if sys.platform == "win32": skip("dup does not work on Windows") s = RSocket(AF_INET, SOCK_STREAM) - s.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) s.bind(INETAddress('localhost', 50007)) s2 = s.dup() assert s.fd != s2.fd @@ -377,10 +376,10 @@ # rsocket.dup() duplicates fd, it also works on Windows # (but only on socket handles!) s = RSocket(AF_INET, SOCK_STREAM) - s.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) s.bind(INETAddress('localhost', 50007)) - fd2 = dup(s.fd) - assert s.fd != fd2 + s2 = RSocket(fd=dup(s.fd)) + assert s.fd != s2.fd + assert s.getsockname().eq(s2.getsockname()) def test_inet_aton(): assert inet_aton('1.2.3.4') == '\x01\x02\x03\x04' @@ -444,7 +443,6 @@ def setup_method(self, method): self.serv = RSocket(AF_INET, SOCK_STREAM) - self.serv.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) self.serv.bind(INETAddress(self.HOST, self.PORT)) self.serv.listen(1) diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py --- a/rpython/rtyper/rint.py +++ b/rpython/rtyper/rint.py @@ -232,7 +232,7 @@ if not s_int1.nonneg or not s_int2.nonneg: raise TyperError("comparing a signed and an unsigned number") - repr = hop.rtyper.makerepr(annmodel.unionof(s_int1, s_int2)).as_int + repr = hop.rtyper.getrepr(annmodel.unionof(s_int1, s_int2)).as_int vlist = hop.inputargs(repr, repr) hop.exception_is_here() return hop.genop(repr.opprefix+func, vlist, resulttype=Bool) diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -162,7 +162,7 @@ def makekey(self, s_obj): return pair(self.type_system, s_obj).rtyper_makekey(self) - def makerepr(self, s_obj): + def _makerepr(self, s_obj): return pair(self.type_system, s_obj).rtyper_makerepr(self) def getrepr(self, s_obj): @@ -173,7 +173,7 @@ result = self.reprs[key] except KeyError: self.reprs[key] = None - result = self.makerepr(s_obj) + result = self._makerepr(s_obj) assert not isinstance(result.lowleveltype, ContainerType), ( "missing a Ptr in the type specification " "of %s:\n%r" % (s_obj, result.lowleveltype)) From noreply at buildbot.pypy.org Mon Mar 4 12:31:04 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 12:31:04 +0100 (CET) Subject: [pypy-commit] pypy default: speed up datetime creation from timestamp significantly Message-ID: <20130304113104.614E21C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62006:91b8e2795113 Date: 2013-03-04 06:01 -0500 http://bitbucket.org/pypy/pypy/changeset/91b8e2795113/ Log: speed up datetime creation from timestamp significantly diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -19,6 +19,9 @@ import time as _time import math as _math +def _round(x): + return _math.floor(x + 0.5) if x >= 0.0 else _math.ceil(x - 0.5) + MINYEAR = 1 MAXYEAR = 9999 @@ -1517,7 +1520,7 @@ converter = _time.localtime if tz is None else _time.gmtime t, frac = divmod(t, 1.0) - us = int(round(frac * 1e6)) + us = int(_round(frac * 1e6)) # If timestamp is less than one microsecond smaller than a # full second, us can be rounded up to 1000000. In this case, @@ -1537,7 +1540,7 @@ def utcfromtimestamp(cls, t): "Construct a UTC datetime from a POSIX timestamp (like time.time())." t, frac = divmod(t, 1.0) - us = int(round(frac * 1e6)) + us = int(_round(frac * 1e6)) # If timestamp is less than one microsecond smaller than a # full second, us can be rounded up to 1000000. In this case, From noreply at buildbot.pypy.org Mon Mar 4 12:31:05 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 12:31:05 +0100 (CET) Subject: [pypy-commit] pypy default: also apply some optimizations to timedelta creation Message-ID: <20130304113105.AECFF1C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62007:043d831e8736 Date: 2013-03-04 06:25 -0500 http://bitbucket.org/pypy/pypy/changeset/043d831e8736/ Log: also apply some optimizations to timedelta creation diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -490,8 +490,8 @@ daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.)) assert daysecondswhole == int(daysecondswhole) # can't overflow s = int(daysecondswhole) - assert days == long(days) - d = long(days) + assert days == int(days) + d = int(days) else: daysecondsfrac = 0.0 d = days @@ -503,8 +503,8 @@ if isinstance(seconds, float): secondsfrac, seconds = _math.modf(seconds) - assert seconds == long(seconds) - seconds = long(seconds) + assert seconds == int(seconds) + seconds = int(seconds) secondsfrac += daysecondsfrac assert abs(secondsfrac) <= 2.0 else: @@ -527,14 +527,14 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = round(microseconds, 0) + microseconds = _round(microseconds) seconds, microseconds = divmod(microseconds, 1e6) assert microseconds == int(microseconds) - assert seconds == long(seconds) + assert seconds == int(seconds) days, seconds = divmod(seconds, 24.*3600.) - assert days == long(days) + assert days == int(days) assert seconds == int(seconds) - d += long(days) + d += int(days) s += int(seconds) # can't overflow assert isinstance(s, int) assert abs(s) <= 3 * 24 * 3600 @@ -547,7 +547,7 @@ assert abs(s) <= 3 * 24 * 3600 microseconds = float(microseconds) microseconds += usdouble - microseconds = round(microseconds, 0) + microseconds = _round(microseconds) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 From noreply at buildbot.pypy.org Mon Mar 4 14:47:32 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 4 Mar 2013 14:47:32 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: updated the bedisplay primitive and the according constants Message-ID: <20130304134732.1923B1C0313@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r114:2e5bc464d264 Date: 2013-03-04 12:52 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2e5bc464d264/ Log: updated the bedisplay primitive and the according constants diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -71,7 +71,7 @@ SO_BLOCKCONTEXT_CLASS = 11 SO_POINT_CLASS = 12 SO_LARGEPOSITIVEINTEGER_CLASS = 13 -SO_DISPLAY_CLASS = 14 +SO_DISPLAY_OBJECT = 14 SO_MESSAGE_CLASS = 15 SO_COMPILEDMETHOD_CLASS = 16 SO_LOW_SPACE_SEMAPHORE = 17 @@ -113,7 +113,6 @@ "BlockClosure" : SO_BLOCKCLOSURE_CLASS, "Point" : SO_POINT_CLASS, "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS, -# "Display" : SO_DISPLAY_CLASS, # "Message" : SO_MESSAGE_CLASS, "CompiledMethod" : SO_COMPILEDMETHOD_CLASS, "Semaphore" : SO_SEMAPHORE_CLASS, @@ -133,6 +132,7 @@ "schedulerassociationpointer" : SO_SCHEDULERASSOCIATIONPOINTER, "special_selectors": SO_SPECIAL_SELECTORS_ARRAY, "smalltalkdict" : SO_SMALLTALK, + "display" : SO_DISPLAY_OBJECT, } LONG_BIT = 32 diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -530,6 +530,9 @@ @expose_primitive(BE_DISPLAY, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): + if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 4: + raise PrimitiveFailedError + # the fields required are bits (a pointer to a Bitmap), width, height, depth interp.space.objtable['w_display'] = w_rcvr return w_rcvr diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -15,7 +15,7 @@ [ ] SMALLINT_AS_FLOAT = 40 # essential # the following are for graphics [ ] BE_CURSOR = 101 # this primitive has two different implementations, dependent on the argument count -[ ] BE_DISPLAY = 102 +[ ] DRAW_RECTANGLE = 127 [ ] GET_NEXT_EVENT = 94 ReValidate primitives From noreply at buildbot.pypy.org Mon Mar 4 14:47:33 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 4 Mar 2013 14:47:33 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: refactored the interpreter to build up a stack of c-frames, not of interpreters with c-frame Message-ID: <20130304134733.3FC5F1C039A@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r115:d950d90d00ce Date: 2013-03-04 14:47 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d950d90d00ce/ Log: refactored the interpreter to build up a stack of c-frames, not of interpreters with c-frame refactored loop-implementation into the trampoline function loop and c_loop, which are somewhat equivalent to frames added test which checks the stack depth by inspecting the method names on the stack diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -26,10 +26,9 @@ _w_last_active_context = None cnt = 0 _last_indent = "" - _loop = True jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], - reds=['s_active_context'], + reds=['s_active_context', 'w_active_context'], get_printable_location=get_printable_location ) @@ -38,6 +37,7 @@ self.image = image self.image_name = image_name self.max_stack_depth = max_stack_depth + self.stack_depth = max_stack_depth self._loop = False def interpret_with_w_frame(self, w_frame): @@ -54,7 +54,17 @@ return conftest.option.prim_trace def loop(self, w_active_context): + # just a trampoline for the actual loop implemented in c_loop self._loop = True + w_new_context = w_active_context + while True: + try: + w_new_context = self.c_loop(w_new_context) + except StackOverflow, e: + self.stack_depth = self.max_stack_depth + w_new_context = e.w_context + + def c_loop(self, w_active_context): s_active_context = w_active_context.as_context_get_shadow(self.space) while True: pc = s_active_context._pc @@ -62,14 +72,25 @@ self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, - s_active_context=s_active_context) - try: - w_new_context = self.step(s_active_context) - except StackOverflow, e: - w_new_context = e.w_context - if w_new_context is not None: - # we return to the context mentioned -> mark all contexts in between as mark_returned - s_active_context = w_new_context.as_context_get_shadow(self.space) + s_active_context=s_active_context, + w_active_context=w_active_context) + w_return_to_context = self.step(s_active_context) + if (w_return_to_context is not None + and not w_return_to_context.is_same_object(w_active_context)): + w_active_context.as_context_get_shadow(self.space).mark_returned() + return w_return_to_context + + def stack_frame(self, w_new_frame): + if not self._loop: + return w_new_frame # this test is done to not loop in test, + # but rather step just once where wanted + if self.stack_depth == 1: + raise StackOverflow(w_new_frame) + + self.stack_depth = self.stack_depth - 1 + retval = self.c_loop(w_new_frame) + self.stack_depth = self.stack_depth + 1 + return retval def perform(self, w_receiver, selector, *arguments_w): if isinstance(selector, str): @@ -97,41 +118,6 @@ except ReturnFromTopLevel, e: return e.object - def stack_frame(self, w_new_frame): - if not self._loop: - return w_new_frame # this test is done to not loop in test, - # but rather step just once where wanted - if self.max_stack_depth == 1: - raise StackOverflow(w_new_frame) - #method = s_active_context.w_method() - #print method.get_identifier_string() - interp = StackedInterpreter(self.space, self.image, self.image_name, - self.max_stack_depth - 1) - return interp.loop(w_new_frame) - -class StackedInterpreter(Interpreter): - def __init__(self, space, image, image_name, max_stack_depth): - self.space = space - self.image = image - self.image_name = image_name - self.max_stack_depth = max_stack_depth - - def loop(self, w_active_context): - s_active_context = w_active_context.as_context_get_shadow(self.space) - while True: - pc = s_active_context._pc - method = s_active_context.method() - - self.jit_driver.jit_merge_point( - pc=pc, self=self, method=method, - s_active_context=s_active_context) - w_return_to_context = self.step(s_active_context) - if (w_return_to_context is not None - and w_return_to_context is not w_active_context): - assert w_return_to_context._shadow._w_sender is not w_active_context - w_active_context.as_context_get_shadow(self.space).mark_returned() - return w_return_to_context - class ReturnFromTopLevel(Exception): def __init__(self, object): self.object = object diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -636,6 +636,7 @@ return 0 class MethodContextShadow(ContextPartShadow): + def __init__(self, space, w_self): self.w_closure_or_nil = space.w_nil self._w_receiver = None @@ -757,10 +758,10 @@ # XXX check whether we can actually return from that context if s_outerContext.pc() == -1: raise error.BlockCannotReturnError() - return s_outerContext._return(self.top(), interp, - s_outerContext.s_home().w_sender()) + return_to_context = s_outerContext.s_home().w_sender() else: - return self._return(self.top(), interp, self.s_home().w_sender()) + return_to_context = self.s_home().w_sender() + return self._return(self.top(), interp, return_to_context) def is_closure_context(self): return self.w_closure_or_nil is not self.space.w_nil diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -962,7 +962,7 @@ # ifFalse: [ (testBlock value: aNumber - 1) + aNumber ]]. # ^ testBlock value: 11 import operator - interp = interpreter.Interpreter(space, max_stack_depth=2) + interp = interpreter.Interpreter(space, max_stack_depth=3) #create a method with the correct bytecodes and a literal bytes = reduce(operator.add, map(chr, [0x8a, 0x01, 0x68, 0x10, 0x8f, 0x11, 0x00, 0x11, 0x10, 0x75, 0xb6, 0x9a, 0x75, 0xa4, 0x09, 0x8c, 0x00, 0x01, @@ -984,9 +984,49 @@ except interpreter.StackOverflow, e: assert False try: - interp = interpreter.StackedInterpreter(space, None, "", 10) - interp.loop(w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), [])) + interp = interpreter.Interpreter(space, None, "", max_stack_depth=10) + interp.c_loop(w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), [])) except interpreter.StackOverflow, e: assert e.w_context.getclass(space) is space.w_MethodContext except interpreter.ReturnFromTopLevel, e: + assert False + +class StackTestInterpreter(interpreter.Interpreter): + def stack_frame(self, w_frame): + import sys + stack_depth = self.max_stack_depth - self.stack_depth + for i in range(stack_depth + 1): + assert sys._getframe(4 + i * 6).f_code.co_name == 'c_loop' + assert sys._getframe(5 + stack_depth * 6).f_code.co_name == 'loop' + return interpreter.Interpreter.stack_frame(self, w_frame) + +def test_actual_stackdepth(): + # | testBlock | + # testBlock := [ :aNumber | + # aNumber = 0 + # ifTrue: [ 2 ] + # ifFalse: [ (testBlock value: aNumber - 1) + aNumber ]]. + # ^ testBlock value: 11 + import operator + interp = StackTestInterpreter(space, max_stack_depth=10) + #create a method with the correct bytecodes and a literal + bytes = reduce(operator.add, map(chr, [0x8a, 0x01, 0x68, 0x10, 0x8f, 0x11, + 0x00, 0x11, 0x10, 0x75, 0xb6, 0x9a, 0x77, 0xa4, 0x09, 0x8c, 0x00, 0x01, + 0x10, 0x76, 0xb1, 0xca, 0x10, 0xb0, 0x7d, 0x8e, 0x00, 0x00, 0x8c, 0x00, + 0x00, 0x20, 0xca, 0x7c])) + + w_method = model.W_CompiledMethod(len(bytes)) + w_method.islarge = 1 + w_method.bytes = bytes + w_method.argsize=0 + w_method.tempsize=1 + w_method.setliterals([space.wrap_int(11)]) + + #create a frame for that method + w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []) + try: + interp.loop(w_frame) + except interpreter.ReturnFromTopLevel, e: + assert space.unwrap_int(e.object) == 68 + except interpreter.StackOverflow, e: assert False \ No newline at end of file From noreply at buildbot.pypy.org Mon Mar 4 15:17:45 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Mar 2013 15:17:45 +0100 (CET) Subject: [pypy-commit] pypy remove-frame-force: I think this is enough to make frame forcing non-existant. Message-ID: <20130304141745.EA3CD1C039A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-frame-force Changeset: r62008:1531cf4492f0 Date: 2013-03-04 16:17 +0200 http://bitbucket.org/pypy/pypy/changeset/1531cf4492f0/ Log: I think this is enough to make frame forcing non-existant. diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -268,27 +268,9 @@ raise NotImplementedError def get_traceback(self): - """Calling this marks the PyTraceback as escaped, i.e. it becomes - accessible and inspectable by app-level Python code. For the JIT. - Note that this has no effect if there are already several traceback - frames recorded, because in this case they are already marked as - escaping by executioncontext.leave() being called with - got_exception=True. - """ - from pypy.interpreter.pytraceback import PyTraceback - tb = self._application_traceback - if tb is not None and isinstance(tb, PyTraceback): - tb.frame.mark_as_escaped() - return tb + return self._application_traceback def set_traceback(self, traceback): - """Set the current traceback. It should either be a traceback - pointing to some already-escaped frame, or a traceback for the - current frame. To support the latter case we do not mark the - frame as escaped. The idea is that it will be marked as escaping - only if the exception really propagates out of this frame, by - executioncontext.leave() being called with got_exception=True. - """ self._application_traceback = traceback # ____________________________________________________________ diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -59,22 +59,13 @@ frame.f_backref = self.topframeref self.topframeref = jit.virtual_ref(frame) - def leave(self, frame, w_exitvalue, got_exception): + def leave(self, frame, w_exitvalue): try: if self.profilefunc: self._trace(frame, 'leaveframe', w_exitvalue) finally: frame_vref = self.topframeref self.topframeref = frame.f_backref - if frame.escaped or got_exception: - # if this frame escaped to applevel, we must ensure that also - # f_back does - f_back = frame.f_backref() - if f_back: - f_back.mark_as_escaped() - # force the frame (from the JIT point of view), so that it can - # be accessed also later - frame_vref() jit.virtual_ref_finish(frame_vref, frame) if self.w_tracefunc is not None and not frame.hide(): diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -49,7 +49,6 @@ instr_ub = 0 instr_prev_plus_one = 0 is_being_profiled = False - escaped = False # see mark_as_escaped() def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): @@ -72,15 +71,6 @@ self.initialize_frame_scopes(outer_func, code) self.f_lineno = code.co_firstlineno - def mark_as_escaped(self): - """ - Must be called on frames that are exposed to applevel, e.g. by - sys._getframe(). This ensures that the virtualref holding the frame - is properly forced by ec.leave(), and thus the frame will be still - accessible even after the corresponding C stack died. - """ - self.escaped = True - def append_block(self, block): assert block.previous is self.lastblock self.lastblock = block @@ -153,7 +143,6 @@ not self.space.config.translating) executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) - got_exception = True w_exitvalue = self.space.w_None try: executioncontext.call_trace(self) @@ -180,9 +169,8 @@ # clean up the exception, might be useful for not # allocating exception objects in some cases self.last_exception = None - got_exception = False finally: - executioncontext.leave(self, w_exitvalue, got_exception) + executioncontext.leave(self, w_exitvalue) return w_exitvalue execute_frame.insert_stack_check_here = True diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -43,7 +43,6 @@ break depth -= 1 f = ec.getnextframe_nohidden(f) - f.mark_as_escaped() return space.wrap(f) @unwrap_spec(new_limit="c_int") diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1170,16 +1170,10 @@ # virtual_ref_finish() assumes that we have a stack-like, last-in # first-out order. metainterp = self.metainterp - vrefbox = metainterp.virtualref_boxes.pop() + metainterp.virtualref_boxes.pop() lastbox = metainterp.virtualref_boxes.pop() assert box.getref_base() == lastbox.getref_base() - vrefinfo = metainterp.staticdata.virtualref_info - vref = vrefbox.getref_base() - if vrefinfo.is_virtual_ref(vref): - # XXX write a comment about nullbox - nullbox = self.metainterp.cpu.ts.CONST_NULL - metainterp.history.record(rop.VIRTUAL_REF_FINISH, - [vrefbox, nullbox], None) + # we just pop it @arguments() def opimpl_ll_read_timestamp(self): diff --git a/rpython/jit/metainterp/test/test_virtualref.py b/rpython/jit/metainterp/test/test_virtualref.py --- a/rpython/jit/metainterp/test/test_virtualref.py +++ b/rpython/jit/metainterp/test/test_virtualref.py @@ -59,7 +59,7 @@ self.interp_operations(f, []) self.check_operations_history(new_with_vtable=1, # X() virtual_ref=1, - virtual_ref_finish=1) + virtual_ref_finish=0) def test_make_vref_guard(self): if not isinstance(self, TestLLtype): @@ -551,7 +551,7 @@ assert res == 1 self.check_resops(new_with_vtable=4) # vref, xy - def test_cannot_use_invalid_virtualref(self): + def test_force_after_finish(self): myjitdriver = JitDriver(greens = [], reds = ['n']) # class XY: diff --git a/rpython/jit/metainterp/virtualref.py b/rpython/jit/metainterp/virtualref.py --- a/rpython/jit/metainterp/virtualref.py +++ b/rpython/jit/metainterp/virtualref.py @@ -163,8 +163,8 @@ assert not vref.forced from rpython.jit.metainterp.compile import ResumeGuardForcedDescr ResumeGuardForcedDescr.force_now(self.cpu, token) - assert vref.virtual_token == TOKEN_NONE - assert vref.forced + if vref.virtual_token != TOKEN_NONE or not vref.forced: + raise InvalidVirtualRef elif not vref.forced: # token == TOKEN_NONE and the vref was not forced: it's invalid raise InvalidVirtualRef From noreply at buildbot.pypy.org Mon Mar 4 15:38:51 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Mar 2013 15:38:51 +0100 (CET) Subject: [pypy-commit] pypy remove-frame-force: fix emulator Message-ID: <20130304143851.68E6A1C039A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-frame-force Changeset: r62009:27f12c24316e Date: 2013-03-04 16:38 +0200 http://bitbucket.org/pypy/pypy/changeset/27f12c24316e/ Log: fix emulator diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -369,8 +369,6 @@ def __call__(self): if self._state == 'non-forced': self._state = 'forced' - elif self._state == 'invalid': - raise InvalidVirtualRef return self._x @property @@ -381,7 +379,7 @@ def _finish(self): if self._state == 'non-forced': - self._state = 'invalid' + self._state = 'forced' class DirectJitVRef(DirectVRef): def __init__(self, x): From noreply at buildbot.pypy.org Mon Mar 4 15:41:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 15:41:38 +0100 (CET) Subject: [pypy-commit] cffi default: Document how to work around these limitations. Message-ID: <20130304144138.86B891C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1181:24398a1b3048 Date: 2013-03-04 15:40 +0100 http://bitbucket.org/cffi/cffi/changeset/24398a1b3048/ Log: Document how to work around these limitations. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -937,7 +937,9 @@ **pointer** to such a struct is fine). If you pass a struct (not a **pointer** to a struct), the struct type cannot have been declared with "``...;``" and completed with ``verify()``; you need to declare it -completely in ``cdef()``. +completely in ``cdef()``. You can work around these limitations by +writing a C function with a simpler signature in the code passed to +``ffi.verify()``, which calls the real C function. Aside from these limitations, functions and callbacks can return structs. From noreply at buildbot.pypy.org Mon Mar 4 15:41:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 15:41:40 +0100 (CET) Subject: [pypy-commit] cffi default: merge heads Message-ID: <20130304144140.1AFB41C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1182:a9b47162788d Date: 2013-03-04 15:40 +0100 http://bitbucket.org/cffi/cffi/changeset/a9b47162788d/ Log: merge heads diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -937,7 +937,9 @@ **pointer** to such a struct is fine). If you pass a struct (not a **pointer** to a struct), the struct type cannot have been declared with "``...;``" and completed with ``verify()``; you need to declare it -completely in ``cdef()``. +completely in ``cdef()``. You can work around these limitations by +writing a C function with a simpler signature in the code passed to +``ffi.verify()``, which calls the real C function. Aside from these limitations, functions and callbacks can return structs. From noreply at buildbot.pypy.org Mon Mar 4 16:47:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Mar 2013 16:47:07 +0100 (CET) Subject: [pypy-commit] pypy gc-del: More in-progress. Message-ID: <20130304154707.B51E81C039A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62010:84eb06294ac8 Date: 2013-03-04 16:35 +0100 http://bitbucket.org/pypy/pypy/changeset/84eb06294ac8/ Log: More in-progress. diff --git a/pypy/doc/discussion/finalizer-order.rst b/pypy/doc/discussion/finalizer-order.rst --- a/pypy/doc/discussion/finalizer-order.rst +++ b/pypy/doc/discussion/finalizer-order.rst @@ -39,7 +39,7 @@ by the GC when the last reference to the object goes away, like in CPython. However (like "lightweight finalizers" used to be), all ``__del__()`` methods must only contain simple enough code, and this - is checked. + is checked. This is now called "destructors". * For any more advanced usage --- in particular for any app-level object with a __del__ --- we don't use the RPython-level ``__del__()`` @@ -54,13 +54,12 @@ last; nothing can be done with the object any more. -Lightweight finalizers ----------------------- +Destructors +----------- -A lightweight finalizer is an RPython ``__del__()`` method that is -called directly by the GC when there is no more reference to an object -(including from other objects with finalizers). Intended for objects -that just need to free a block of raw memory or close a file. +A destructor is an RPython ``__del__()`` method that is called directly +by the GC when there is no more reference to an object. Intended for +objects that just need to free a block of raw memory or close a file. There are restrictions on the kind of code you can put in ``__del__()``, including all other functions called by it. These restrictions are @@ -68,11 +67,16 @@ and if you call an external C function, it must be a "safe" function. (XXX check/implement this) +If there are several objects with destructors, they are called in a +random order --- but that should be fine because destructors cannot +do much anyway. + Register_finalizer ------------------ -The interface is made with PyPy in mind, but should be generally useful. +The interface for full finalizers is made with PyPy in mind, but should +be generally useful. ``rgc.register_finalizer(obj.finalizer_method)`` @@ -82,9 +86,9 @@ picks a topological ordering (breaking cycles randomly) and enqueues the objects and their registered finalizer functions in that order. Finally, when the major collection is done, it calls - ``rgc.progress_through_finalizer_queue()`` once, unless there is + ``rgc.progress_through_finalizer_queue()`` once (unless there is already a call to ``rgc.progress_through_finalizer_queue()`` in - progress. + progress). It is only allowed to register one finalizer per object, but we can cumulate one register_finalizer() and a __del__(). It is @@ -99,15 +103,16 @@ function remains at the front of the queue, and will be called again by the next call to ``progress_through_finalizer_queue()``. -The idea is that the finalizer functions in PyPy either do their clean-up -immediately (for the case where they are not lightweight finalizers, but -don't require synchronization), or are postponed to be executed at the -end of the current bytecode by the interpreter. This is done by writing -such functions with this logic:: +The idea is that the finalizer functions in PyPy either do their +clean-up immediately (for the case where destructors are not +appropriate, but they still don't require complete synchronization with +the Python code), or are postponed to be executed at the end of the +current bytecode by the interpreter. This is done by writing such +functions with this logic:: def finalize(self): ec = self.space.getexecutioncontext() - if not ec.running_finalizers: + if not ec.running_finalizers_between_bytecodes: ec.schedule_later_call_to_progress_through_finalizer_queue() raise FinalizeLater else: diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -62,8 +62,7 @@ def set_query_functions(self, is_varsize, has_gcptr_in_varsize, is_gcarrayofgcptr, - getfinalizer, - getlightfinalizer, + getdestructor, offsets_to_gc_pointers, fixed_size, varsize_item_sizes, varsize_offset_to_variable_part, @@ -75,8 +74,7 @@ has_custom_trace, get_custom_trace, fast_path_tracing): - self.getfinalizer = getfinalizer - self.getlightfinalizer = getlightfinalizer + self.getdestructor = getdestructor self.is_varsize = is_varsize self.has_gcptr_in_varsize = has_gcptr_in_varsize self.is_gcarrayofgcptr = is_gcarrayofgcptr @@ -138,10 +136,9 @@ # to malloc_varsize(), but always uses malloc_varsize_clear() size = self.fixed_size(typeid) - needs_finalizer = bool(self.getfinalizer(typeid)) - finalizer_is_light = bool(self.getlightfinalizer(typeid)) + has_destructor = bool(self.getdestructor(typeid)) contains_weakptr = self.weakpointer_offset(typeid) >= 0 - assert not (needs_finalizer and contains_weakptr) + assert not (has_destructor and contains_weakptr) if self.is_varsize(typeid): assert not contains_weakptr assert not needs_finalizer @@ -158,8 +155,7 @@ malloc_fixedsize = self.malloc_fixedsize_clear else: malloc_fixedsize = self.malloc_fixedsize - ref = malloc_fixedsize(typeid, size, needs_finalizer, - finalizer_is_light, + ref = malloc_fixedsize(typeid, size, has_destructor, contains_weakptr) # lots of cast and reverse-cast around... return llmemory.cast_ptr_to_adr(ref) diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -104,9 +104,8 @@ # translation and is statically recorded. GCFLAG_HAS_SHADOW = first_gcflag << 3 -# The following flag is set temporarily on some objects during a major -# collection. See pypy/doc/discussion/finalizer-order.txt -GCFLAG_FINALIZATION_ORDERING = first_gcflag << 4 +# The following flag is set when we call rgc.register_finalizer(). +GCFLAG_HAS_FINALIZER= first_gcflag << 4 # This flag is reserved for RPython. GCFLAG_EXTRA = first_gcflag << 5 @@ -294,10 +293,9 @@ self.old_rawmalloced_objects = self.AddressStack() self.rawmalloced_total_size = r_uint(0) # - # A list of all objects with finalizers (these are never young). - self.objects_with_finalizers = self.AddressDeque() - self.young_objects_with_light_finalizers = self.AddressStack() - self.old_objects_with_light_finalizers = self.AddressStack() + # Two lists of all objects with destructors + self.young_objects_with_destructors = self.AddressStack() + self.old_objects_with_destructors = self.AddressStack() # # Two lists of the objects with weakrefs. No weakref can be an # old object weakly pointing to a young object: indeed, weakrefs @@ -467,25 +465,16 @@ def malloc_fixedsize_clear(self, typeid, size, - needs_finalizer=False, - is_finalizer_light=False, + has_destructor=False, contains_weakptr=False): size_gc_header = self.gcheaderbuilder.size_gc_header totalsize = size_gc_header + size rawtotalsize = raw_malloc_usage(totalsize) # - # If the object needs a finalizer, ask for a rawmalloc. - # The following check should be constant-folded. - if needs_finalizer and not is_finalizer_light: - ll_assert(not contains_weakptr, - "'needs_finalizer' and 'contains_weakptr' both specified") - obj = self.external_malloc(typeid, 0, can_make_young=False) - self.objects_with_finalizers.append(obj) - # # If totalsize is greater than nonlarge_max (which should never be # the case in practice), ask for a rawmalloc. The following check # should be constant-folded. - elif rawtotalsize > self.nonlarge_max: + if rawtotalsize > self.nonlarge_max: ll_assert(not contains_weakptr, "'contains_weakptr' specified for a large object") obj = self.external_malloc(typeid, 0) @@ -507,11 +496,12 @@ # Build the object. llarena.arena_reserve(result, totalsize) obj = result + size_gc_header - if is_finalizer_light: - self.young_objects_with_light_finalizers.append(obj) self.init_gc_object(result, typeid, flags=0) # - # If it is a weakref, record it (check constant-folded). + # If it is a weakref or has a destructor, record it + # (checks constant-folded). + if has_destructor: + self.young_objects_with_destructors.append(obj) if contains_weakptr: self.young_objects_with_weakrefs.append(obj) # @@ -876,7 +866,7 @@ """ assert self.is_in_nursery(obj) tid = self.header(obj).tid - result = (tid & GCFLAG_FINALIZATION_ORDERING != 0) + result = (tid & GCFLAG_NO_HEAP_PTRS != 0) if result: ll_assert(tid == -42, "bogus header for young obj") else: @@ -929,9 +919,6 @@ # the GCFLAG_VISITED should not be set between collections ll_assert(self.header(obj).tid & GCFLAG_VISITED == 0, "unexpected GCFLAG_VISITED") - # the GCFLAG_FINALIZATION_ORDERING should not be set between coll. - ll_assert(self.header(obj).tid & GCFLAG_FINALIZATION_ORDERING == 0, - "unexpected GCFLAG_FINALIZATION_ORDERING") # the GCFLAG_CARDS_SET should not be set between collections ll_assert(self.header(obj).tid & GCFLAG_CARDS_SET == 0, "unexpected GCFLAG_CARDS_SET") @@ -1251,8 +1238,8 @@ # weakrefs' targets. if self.young_objects_with_weakrefs.non_empty(): self.invalidate_young_weakrefs() - if self.young_objects_with_light_finalizers.non_empty(): - self.deal_with_young_objects_with_finalizers() + if self.young_objects_with_destructors.non_empty(): + self.deal_with_young_objects_with_destructors() # # Clear this mapping. if self.nursery_objects_shadows.length() > 0: @@ -1569,16 +1556,18 @@ # with a finalizer and all objects reachable from there (and also # moves some objects from 'objects_with_finalizers' to # 'run_finalizers'). - if self.objects_with_finalizers.non_empty(): - self.deal_with_objects_with_finalizers() + #if self.objects_with_finalizers.non_empty(): + # self.deal_with_objects_with_finalizers() # self.objects_to_trace.delete() # # Weakref support: clear the weak pointers to dying objects if self.old_objects_with_weakrefs.non_empty(): self.invalidate_old_weakrefs() - if self.old_objects_with_light_finalizers.non_empty(): - self.deal_with_old_objects_with_finalizers() + # + # Destructor support + if self.old_objects_with_destructors.non_empty(): + self.deal_with_old_objects_with_destructors() # # Walk all rawmalloced objects and free the ones that don't @@ -1834,24 +1823,23 @@ self.extra_threshold += diff - # ---------- - # Finalizers + # ----------- + # Destructors - def deal_with_young_objects_with_finalizers(self): - """ This is a much simpler version of dealing with finalizers - and an optimization - we can reasonably assume that those finalizers - don't do anything fancy and *just* call them. Among other things - they won't resurrect objects + def deal_with_young_objects_with_destructors(self): + """We can reasonably assume that destructors don't do anything + fancy and *just* call them. Among other things they won't + resurrect objects """ - while self.young_objects_with_light_finalizers.non_empty(): - obj = self.young_objects_with_light_finalizers.pop() + while self.young_objects_with_destructors.non_empty(): + obj = self.young_objects_with_destructors.pop() if not self.is_forwarded(obj): - finalizer = self.getlightfinalizer(self.get_type_id(obj)) - ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + destructor = self.getdestructor(self.get_type_id(obj)) + ll_assert(bool(destructor), "destructor missing") + destructor(obj, llmemory.NULL) else: obj = self.get_forwarding_address(obj) - self.old_objects_with_light_finalizers.append(obj) + self.old_objects_with_destructors.append(obj) def deal_with_old_objects_with_finalizers(self): """ This is a much simpler version of dealing with finalizers @@ -1874,6 +1862,7 @@ self.old_objects_with_light_finalizers = new_objects def deal_with_objects_with_finalizers(self): + XXXXXXXXX # Walk over list of objects with finalizers. # If it is not surviving, add it to the list of to-be-called # finalizers and make it survive, to make the finalizer runnable. diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -22,15 +22,15 @@ # custom tracer (CT), it enumerates the addresses that contain GCREFs. # It is called with the object as first argument, and the previous # returned address (or NULL the first time) as the second argument. - FINALIZER_OR_CT_FUNC = lltype.FuncType([llmemory.Address, + DESTRUCTOR_OR_CT_FUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) - FINALIZER_OR_CT = lltype.Ptr(FINALIZER_OR_CT_FUNC) + DESTRUCTOR_OR_CT = lltype.Ptr(DESTRUCTOR_OR_CT_FUNC) # structure describing the layout of a typeid TYPE_INFO = lltype.Struct("type_info", ("infobits", lltype.Signed), # combination of the T_xxx consts - ("finalizer_or_customtrace", FINALIZER_OR_CT), + ("destructor_or_customtrace", DESTRUCTOR_OR_CT), ("fixedsize", lltype.Signed), ("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)), hints={'immutable': True}, @@ -77,19 +77,12 @@ infobits = self.get(typeid).infobits return (infobits & T_IS_GCARRAY_OF_GCPTR) != 0 - def q_finalizer(self, typeid): + def q_getdestructor(self, typeid): typeinfo = self.get(typeid) - if typeinfo.infobits & T_HAS_FINALIZER: - return typeinfo.finalizer_or_customtrace + if typeinfo.infobits & T_HAS_DESTRUCTOR: + return typeinfo.destructor_or_customtrace else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) - - def q_light_finalizer(self, typeid): - typeinfo = self.get(typeid) - if typeinfo.infobits & T_HAS_LIGHTWEIGHT_FINALIZER: - return typeinfo.finalizer_or_customtrace - else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.DESTRUCTOR_OR_CT_FUNC) def q_offsets_to_gc_pointers(self, typeid): return self.get(typeid).ofstoptrs @@ -131,7 +124,7 @@ ll_assert(self.q_has_custom_trace(typeid), "T_HAS_CUSTOM_TRACE missing") typeinfo = self.get(typeid) - return typeinfo.finalizer_or_customtrace + return typeinfo.destructor_or_customtrace def q_fast_path_tracing(self, typeid): # return True if none of the flags T_HAS_GCPTR_IN_VARSIZE, @@ -147,8 +140,7 @@ self.q_is_varsize, self.q_has_gcptr_in_varsize, self.q_is_gcarrayofgcptr, - self.q_finalizer, - self.q_light_finalizer, + self.q_getdestructor, self.q_offsets_to_gc_pointers, self.q_fixed_size, self.q_varsize_item_sizes, @@ -170,9 +162,8 @@ T_IS_GCARRAY_OF_GCPTR = 0x040000 T_IS_WEAKREF = 0x080000 T_IS_RPYTHON_INSTANCE = 0x100000 # the type is a subclass of OBJECT -T_HAS_FINALIZER = 0x200000 +T_HAS_DESTRUCTOR = 0x200000 T_HAS_CUSTOM_TRACE = 0x400000 -T_HAS_LIGHTWEIGHT_FINALIZER = 0x800000 T_KEY_MASK = intmask(0xFF000000) T_KEY_VALUE = intmask(0x5A000000) # bug detection only @@ -199,11 +190,9 @@ kind_and_fptr = builder.special_funcptr_for_type(TYPE) if kind_and_fptr is not None: kind, fptr = kind_and_fptr - info.finalizer_or_customtrace = fptr - if kind == "finalizer": - infobits |= T_HAS_FINALIZER - elif kind == 'light_finalizer': - infobits |= T_HAS_FINALIZER | T_HAS_LIGHTWEIGHT_FINALIZER + info.destructor_or_customtrace = fptr + if kind == "destructor": + infobits |= T_HAS_DESTRUCTOR elif kind == "custom_trace": infobits |= T_HAS_CUSTOM_TRACE else: diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -225,7 +225,7 @@ raise RuntimeError( "a finalizer raised an exception, shouldn't happen") return llmemory.NULL - return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer) + return llhelper(gctypelayout.GCData.DESTRUCTOR_OR_CT, ll_finalizer) def make_custom_trace_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -115,8 +115,8 @@ return f - def test_full_finalizer_order(self): - res = self.run('full_finalizer_order') + def test_finalizer_order(self): + res = self.run('finalizer_order') if res != "ok": i, summary, msg = res.split('\n') i = int(i) diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -153,7 +153,7 @@ res = self.interpret(f, [5]) assert res == 6 - def test_finalizer(self): + def test_finalizer_simple(self): class B(object): pass b = B() @@ -303,7 +303,7 @@ res = self.interpret(f, []) assert res - def test_weakref_to_object_with_finalizer(self): + def test_weakref_to_object_with_destructor(self): import weakref class A(object): count = 0 @@ -323,6 +323,32 @@ res = self.interpret(f, []) assert res + def test_weakref_to_object_with_finalizer(self): + import weakref + class A(object): + count = 0 + a = A() + class B(object): + def __init__(self, ref): + rgc.register_finalizer(self.finalizer) + def finalizer(self): + # when the finalizer is called, the weakref to myself is + # still valid in RPython + a.count += 100 + (self.ref() is None) + def g(): + b = B() + ref = weakref.ref(b) + b.ref = ref + return b + def f(): + ref = g() + llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) + result = a.count + 10 * (ref() is None) + return result + res = self.interpret(f, []) + assert res == 110 + def test_bug_1(self): import weakref class B(object): @@ -348,8 +374,10 @@ count = 0 a = A() class B(object): - def __del__(self): - # when __del__ is called, the weakref to c should be dead + def __init__(self, ref): + rgc.register_finalizer(self.finalizer) + def finalizer(self): + # when the finalizer is called, the weakref to c should be dead if self.ref() is None: a.count += 10 # ok else: @@ -371,40 +399,14 @@ res = self.interpret(f, []) assert res == 11 - def test_weakref_to_object_with_finalizer_ordering(self): - import weakref - class A(object): - count = 0 - a = A() - class B(object): - def __del__(self): - # when __del__ is called, the weakref to myself is still valid - # in RPython (at least with most GCs; this test might be - # skipped for specific GCs) - if self.ref() is self: - a.count += 10 # ok - else: - a.count = 666 # not ok - def g(): - b = B() - ref = weakref.ref(b) - b.ref = ref - return ref - def f(): - ref = g() - llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) - result = a.count + (ref() is None) - return result - res = self.interpret(f, []) - assert res == 11 - def test_weakref_bug_1(self): import weakref class A(object): pass class B(object): - def __del__(self): + def __init__(self, ref): + rgc.register_finalizer(self.finalizer) + def finalizer(self): self.wref().x += 1 def g(a): b = B() @@ -453,7 +455,8 @@ def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): + rgc.register_finalizer(self.finalizer) + def finalizer(self): b.num_deleted += 1 b.all.append(D(b.num_deleted)) class D(object): @@ -486,14 +489,16 @@ def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): + rgc.register_finalizer(self.finalizer) + def finalizer(self): + b.num_deleted += 1 + self.do_finalizer() + def do_finalizer(self): llop.gc__collect(lltype.Void) - b.num_deleted += 1 C() C() class C(A): - def __del__(self): - b.num_deleted += 1 + def do_finalizer(self): b.num_deleted_c += 1 def f(x, y): persistent_a1 = A() @@ -873,7 +878,8 @@ def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): + rgc.register_finalizer(self.finalizer) + def finalizer(self): b.num_deleted += 1 def f(x): a = A() diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -333,7 +333,8 @@ func(obj) except FinalizeLater: _finalizer_queue.appendleft((obj, func)) - break + return False # interrupted + return True # completed class RegisterFinalizerEntry(ExtRegistryEntry): _about_ = register_finalizer @@ -342,8 +343,10 @@ from rpython.annotator import model as annmodel from rpython.annotator.description import MethodDesc assert (isinstance(s_method, annmodel.SomePBC) and - s_method.getKind() is MethodDesc and - len(s_method.descriptions) == 1) + s_method.getKind() is MethodDesc) + if len(s_method.descriptions) != 1: + raise Exception("rgc.register_finalizer(method): the method must " + "not be overridden. Add an indirection if needed") # [methoddesc] = s_method.descriptions key = (register_finalizer, methoddesc.funcdesc, methoddesc.name) From noreply at buildbot.pypy.org Mon Mar 4 17:40:54 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 4 Mar 2013 17:40:54 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: enable inlining Message-ID: <20130304164054.D1AF11C034F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r116:f395aad2770a Date: 2013-03-04 15:43 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/f395aad2770a/ Log: enable inlining diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -69,4 +69,4 @@ def interp_w(): interp.loop(w_frame) - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True, inline=True) From noreply at buildbot.pypy.org Mon Mar 4 17:40:56 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 4 Mar 2013 17:40:56 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: integer are immutable -> tell the jit Message-ID: <20130304164056.2377B1C034F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r117:c38b0994784c Date: 2013-03-04 17:38 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c38b0994784c/ Log: integer are immutable -> tell the jit diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -113,6 +113,7 @@ """Boxed integer value""" # TODO can we tell pypy that its never larger then 31-bit? __slots__ = ('value',) # the only allowed slot here + _immutable_fields_ = ["value"] def __init__(self, value): self.value = value From noreply at buildbot.pypy.org Mon Mar 4 17:40:57 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 4 Mar 2013 17:40:57 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added some annotations and temporary variables to enable virtualizable contexts Message-ID: <20130304164057.96A7A1C034F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r118:20243a9dbe6b Date: 2013-03-04 17:40 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/20243a9dbe6b/ Log: added some annotations and temporary variables to enable virtualizable contexts added comments which include the code for virtualizables. unfortunately, the return-implementations forbids virtualizables diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -29,6 +29,7 @@ jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], reds=['s_active_context', 'w_active_context'], + #virtualizables=['s_active_context'], get_printable_location=get_printable_location ) @@ -695,7 +696,7 @@ prefix = "el" code.append("bytecode_step_translated._always_inline_ = True") source = py.code.Source("\n".join(code)) - print source + #print source miniglob = {} exec source.compile() in miniglob return miniglob["bytecode_step_translated"] diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -312,6 +312,12 @@ __metaclass__ = extendabletype + # _virtualizable2_ = [ + # "_w_sender", "_pc", "_w_sender", + # "_temps_and_stack[*]", "_stack_ptr", + # "_w_self", "_w_self_size" + # ] + def __init__(self, space, w_self): self._w_sender = space.w_nil @@ -331,7 +337,9 @@ if n0 == constants.CTXPART_STACKP_INDEX: return self.wrap_stackpointer() if self.stackstart() <= n0 < self.external_stackpointer(): - return self.peek(self.stackdepth() - (n0-self.stackstart()) - 1) + temp_i = self.stackdepth() - (n0-self.stackstart()) - 1 + assert temp_i >= 0 + return self.peek(temp_i) if self.external_stackpointer() <= n0 < self.stackend(): return self.space.w_nil else: @@ -345,10 +353,10 @@ return self.store_unwrap_pc(w_value) if n0 == constants.CTXPART_STACKP_INDEX: return self.unwrap_store_stackpointer(w_value) - if self.stackstart() <= n0 < self.external_stackpointer(): - return self.set_top(w_value, - self.stackdepth() - (n0-self.stackstart()) - 1) - return + if self.stackstart() <= n0 < self.external_stackpointer(): # XXX can be simplified? + temp_i = self.stackdepth() - (n0-self.stackstart()) - 1 + assert temp_i >= 0 + return self.set_top(w_value, temp_i) if self.external_stackpointer() <= n0 < self.stackend(): return else: @@ -553,6 +561,7 @@ contextsize = w_home.as_methodcontext_get_shadow(space).myblocksize() w_result = model.W_PointersObject(space.w_BlockContext, contextsize) s_result = BlockContextShadow(space, w_result) + s_result = jit.hint(s_result, access_directly=True, fresh_virtualizable=True) w_result.store_shadow(s_result) s_result.store_expected_argument_count(argcnt) s_result.store_initialip(initialip) @@ -581,6 +590,7 @@ else: return ContextPartShadow.store(self, n0, w_value) + @jit.dont_look_inside def attach_shadow(self): # Make sure the home context is updated first self.copy_from_w_self(constants.BLKCTX_HOME_INDEX) @@ -637,6 +647,7 @@ class MethodContextShadow(ContextPartShadow): + def __init__(self, space, w_self): self.w_closure_or_nil = space.w_nil self._w_receiver = None @@ -655,6 +666,8 @@ # into the right places in the W_PointersObject # XXX could hack some more to never have to create the _vars of w_result s_result = MethodContextShadow(space, w_result) + s_result = jit.hint(s_result, access_directly=True, fresh_virtualizable=True) + w_result.store_shadow(s_result) if closure is not None: s_result.w_closure_or_nil = closure._w_self @@ -681,8 +694,9 @@ return self.w_closure_or_nil if n0 == constants.MTHDCTX_RECEIVER: return self.w_receiver() - if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START < self.tempsize()): - return self.gettemp(n0-constants.MTHDCTX_TEMP_FRAME_START) + temp_i = n0-constants.MTHDCTX_TEMP_FRAME_START + if (0 <= temp_i < self.tempsize()): + return self.gettemp(temp_i) else: return ContextPartShadow.fetch(self, n0) @@ -695,13 +709,13 @@ if n0 == constants.MTHDCTX_RECEIVER: self.store_w_receiver(w_value) return - if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START < - self.tempsize()): - return self.settemp(n0-constants.MTHDCTX_TEMP_FRAME_START, - w_value) + temp_i = n0-constants.MTHDCTX_TEMP_FRAME_START + if (0 <= temp_i < self.tempsize()): + return self.settemp(temp_i, w_value) else: return ContextPartShadow.store(self, n0, w_value) + @jit.dont_look_inside def attach_shadow(self): # Make sure the method is updated first self.copy_from_w_self(constants.MTHDCTX_METHOD) From noreply at buildbot.pypy.org Mon Mar 4 19:28:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Mar 2013 19:28:42 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: (arigo, fijal) Message-ID: <20130304182842.A5BAE1C039A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62011:b78a2b0c8885 Date: 2013-03-04 20:28 +0200 http://bitbucket.org/pypy/pypy/changeset/b78a2b0c8885/ Log: (arigo, fijal) * kill function that is not necessary any more * make sure we can only ever upgrade the frame depth diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -598,7 +598,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.set_frame_depth(0, 0) # for now + clt.frame_info.update_frame_depth(0, 0) # for now if False and log: operations = self._inject_debugging_code(looptoken, operations, @@ -854,7 +854,7 @@ def update_frame_depth(self, frame_depth): baseofs = self.cpu.get_baseofs_of_frame_field() - self.current_clt.frame_info.set_frame_depth(baseofs, frame_depth) + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) def write_pending_failure_recoveries(self): for tok in self.pending_guards: diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -15,9 +15,10 @@ NULLGCMAP = lltype.nullptr(GCMAP) @enforceargs(None, int, int) -def jitframeinfo_set_depth(jfi, base_ofs, new_depth): - jfi.jfi_frame_depth = new_depth - jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED +def jitframeinfo_update_depth(jfi, base_ofs, new_depth): + if new_depth > jfi.jfi_frame_depth: + jfi.jfi_frame_depth = new_depth + jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED JITFRAMEINFO_SIZE = 2 * SIZEOFSIGNED # make sure this stays correct @@ -28,7 +29,7 @@ # the total size of the frame, in bytes ('jfi_frame_size', lltype.Signed), adtmeths = { - 'set_frame_depth': jitframeinfo_set_depth, + 'update_frame_depth': jitframeinfo_update_depth, }, ) diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -86,7 +86,7 @@ if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date - frame.jf_frame_info.set_frame_depth(base_ofs, size) + frame.jf_frame_info.update_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 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 @@ -315,10 +315,11 @@ for ref in oldlooptoken.looptokens_redirected_to: looptoken = ref() if looptoken: - looptoken.frame_info.set_frame_depth(baseofs, + looptoken.frame_info.update_frame_depth(baseofs, new_fi.jfi_frame_depth) new_loop_tokens.append(ref) - oldlooptoken.frame_info.set_frame_depth(baseofs, new_fi.jfi_frame_depth) + oldlooptoken.frame_info.update_frame_depth(baseofs, + new_fi.jfi_frame_depth) assert oldlooptoken is not None new_loop_tokens.append(weakref.ref(oldlooptoken)) self.looptokens_redirected_to = new_loop_tokens diff --git a/rpython/jit/backend/test/test_model.py b/rpython/jit/backend/test/test_model.py --- a/rpython/jit/backend/test/test_model.py +++ b/rpython/jit/backend/test/test_model.py @@ -13,7 +13,7 @@ def __init__(self, depth): self.jfi_frame_depth = depth - def set_frame_depth(self, baseofs, newdepth): + def update_frame_depth(self, baseofs, newdepth): self.jfi_frame_depth = newdepth def test_redirect_loop_token(): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -471,7 +471,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.set_frame_depth(0, 0) # for now + clt.frame_info.update_frame_depth(0, 0) # for now if log: operations = self._inject_debugging_code(looptoken, operations, @@ -622,7 +622,7 @@ def update_frame_depth(self, frame_depth): baseofs = self.cpu.get_baseofs_of_frame_field() - self.current_clt.frame_info.set_frame_depth(baseofs, frame_depth) + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. @@ -2392,18 +2392,6 @@ not_implemented("not implemented operation (guard): %s" % op.getopname()) - def check_frame_before_jump(self, target_token): - if target_token in self.target_tokens_currently_compiling: - return - if target_token._x86_clt is self.current_clt: - return - # We can have a frame coming from god knows where that's - # passed to a jump to another loop. Make sure it has the - # correct depth - expected_size = target_token._x86_clt.frame_info.jfi_frame_depth - self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), - expected_size=expected_size) - def closing_jump(self, target_token): target = target_token._ll_loop_code if target_token in self.target_tokens_currently_compiling: 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 @@ -1238,7 +1238,6 @@ tmpreg = None xmmtmp = None # Do the remapping - assembler.check_frame_before_jump(self.jump_target_descr) remap_frame_layout_mixed(assembler, src_locations1, dst_locations1, tmpreg, src_locations2, dst_locations2, xmmtmp) From noreply at buildbot.pypy.org Mon Mar 4 19:51:43 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Mar 2013 19:51:43 +0100 (CET) Subject: [pypy-commit] pypy default: skip readline, interrupt in pyrepl on windows Message-ID: <20130304185143.123541C039A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r62012:2951995a57bf Date: 2013-03-04 20:48 +0200 http://bitbucket.org/pypy/pypy/changeset/2951995a57bf/ Log: skip readline, interrupt in pyrepl on windows diff --git a/pypy/module/test_lib_pypy/pyrepl/test_basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py --- a/pypy/module/test_lib_pypy/pyrepl/test_basic.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_basic.py @@ -16,6 +16,7 @@ # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import os import pytest from .infrastructure import read_spec @@ -76,6 +77,7 @@ ( 'accept', ['cd '])]) + at pytest.mark.skipif("os.name == 'nt'") def test_interrupt(): with pytest.raises(KeyboardInterrupt): read_spec([('interrupt', [''])]) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -25,6 +25,9 @@ import pytest +import os +if os.name == 'nt': + pytest.skip('pyrepl does not work properly on windows') class HistoricalTestReader(HistoricalReader, BaseTestReader): pass diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py --- a/pypy/module/test_lib_pypy/pyrepl/test_readline.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py @@ -1,5 +1,11 @@ +import os +import pytest + +if os.name == 'nt': + pytest.skip('No pyrepl.readline in windows, requires termios') + from pyrepl.readline import _ReadlineWrapper -import os + import pty From noreply at buildbot.pypy.org Mon Mar 4 20:45:10 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 4 Mar 2013 20:45:10 +0100 (CET) Subject: [pypy-commit] pypy py3k: Exact argument error messages are an implementation detail. Message-ID: <20130304194510.666D51C0313@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r62013:1752ebfa1756 Date: 2013-03-04 13:16 +0100 http://bitbucket.org/pypy/pypy/changeset/1752ebfa1756/ Log: Exact argument error messages are an implementation detail. diff --git a/lib-python/3/test/test_extcall.py b/lib-python/3/test/test_extcall.py --- a/lib-python/3/test/test_extcall.py +++ b/lib-python/3/test/test_extcall.py @@ -89,19 +89,19 @@ >>> class Nothing: pass ... - >>> g(*Nothing()) + >>> g(*Nothing()) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: g() argument after * must be a sequence, not Nothing + TypeError: ...argument after * must be a sequence, not Nothing >>> class Nothing: ... def __len__(self): return 5 ... - >>> g(*Nothing()) + >>> g(*Nothing()) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: g() argument after * must be a sequence, not Nothing + TypeError: ...argument after * must be a sequence, not Nothing >>> class Nothing(): ... def __len__(self): return 5 @@ -153,52 +153,52 @@ ... TypeError: g() got multiple values for keyword argument 'x' - >>> f(**{1:2}) + >>> f(**{1:2}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() keywords must be strings + TypeError: ...keywords must be strings >>> h(**{'e': 2}) Traceback (most recent call last): ... TypeError: h() got an unexpected keyword argument 'e' - >>> h(*h) + >>> h(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after * must be a sequence, not function + TypeError: ...argument after * must be a sequence, not function - >>> dir(*h) + >>> dir(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() argument after * must be a sequence, not function + TypeError: ...argument after * must be a sequence, not function - >>> None(*h) + >>> None(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: NoneType object argument after * must be a sequence, \ + TypeError: ...argument after * must be a sequence, \ not function - >>> h(**h) + >>> h(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> dir(**h) + >>> dir(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> None(**h) + >>> None(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: NoneType object argument after ** must be a mapping, \ + TypeError: ...argument after ** must be a mapping, \ not function - >>> dir(b=1, **{'b': 1}) + >>> dir(b=1, **{'b': 1}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() got multiple values for keyword argument 'b' + TypeError: ...got multiple values for keyword argument 'b' Another helper function @@ -239,10 +239,10 @@ ... False True - >>> id(1, **{'foo': 1}) + >>> id(1, **{'foo': 1}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: id() takes no keyword arguments + TypeError: id() ... keyword argument... A corner case of keyword dictionary items being deleted during the function call setup. See . @@ -276,16 +276,16 @@ >>> def f(a): ... pass - >>> f(6, a=4, *(1, 2, 3)) + >>> f(6, a=4, *(1, 2, 3)) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() takes exactly 1 positional argument (5 given) + TypeError: f() takes exactly 1 ...argument (5 given) >>> def f(a, *, kw): ... pass - >>> f(6, 4, kw=4) + >>> f(6, 4, kw=4) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() takes exactly 1 positional argument (3 given) + TypeError: f() takes exactly 1 ...argument (3 given) """ import sys From noreply at buildbot.pypy.org Mon Mar 4 21:36:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 21:36:26 +0100 (CET) Subject: [pypy-commit] pypy default: clean up pyrepl test skips Message-ID: <20130304203626.080321C039A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62016:cfa3750d858f Date: 2013-03-04 15:26 -0500 http://bitbucket.org/pypy/pypy/changeset/cfa3750d858f/ Log: clean up pyrepl test skips diff --git a/pypy/module/test_lib_pypy/pyrepl/test_basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py --- a/pypy/module/test_lib_pypy/pyrepl/test_basic.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_basic.py @@ -16,7 +16,6 @@ # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import os import pytest from .infrastructure import read_spec diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -25,9 +25,6 @@ import pytest -import os -if os.name == 'nt': - pytest.skip('pyrepl does not work properly on windows') class HistoricalTestReader(HistoricalReader, BaseTestReader): pass @@ -48,6 +45,7 @@ ] read_spec(spec, HistoricalTestReader) + at pytest.mark.skipif("os.name != 'posix'") def test_signal_failure(monkeypatch): import os import pty diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py --- a/pypy/module/test_lib_pypy/pyrepl/test_readline.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py @@ -1,15 +1,16 @@ import os -import pytest -if os.name == 'nt': - pytest.skip('No pyrepl.readline in windows, requires termios') - -from pyrepl.readline import _ReadlineWrapper - -import pty +if os.name == 'posix': + from pyrepl.readline import _ReadlineWrapper +else: + import pytest + e = pytest.raises(ImportError, "import pyrepl.readline") + assert 'termios' in e.value.message + pytest.skip('pyrepl.readline requires termios') def test_raw_input(): + import pty master, slave = pty.openpty() readline_wrapper = _ReadlineWrapper(slave, slave) os.write(master, b'input\n') From noreply at buildbot.pypy.org Mon Mar 4 22:12:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 4 Mar 2013 22:12:19 +0100 (CET) Subject: [pypy-commit] pypy default: more small clean-ups and a comment for pyrepl tests Message-ID: <20130304211219.8682A1C039A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62017:a8699a951447 Date: 2013-03-04 16:11 -0500 http://bitbucket.org/pypy/pypy/changeset/a8699a951447/ Log: more small clean-ups and a comment for pyrepl tests diff --git a/pypy/module/test_lib_pypy/pyrepl/test_basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py --- a/pypy/module/test_lib_pypy/pyrepl/test_basic.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_basic.py @@ -76,6 +76,7 @@ ( 'accept', ['cd '])]) +# interrupt uses os.kill which doesn't go through signal handlers on windows @pytest.mark.skipif("os.name == 'nt'") def test_interrupt(): with pytest.raises(KeyboardInterrupt): diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -45,6 +45,7 @@ ] read_spec(spec, HistoricalTestReader) + @pytest.mark.skipif("os.name != 'posix'") def test_signal_failure(monkeypatch): import os diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py --- a/pypy/module/test_lib_pypy/pyrepl/test_readline.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py @@ -1,16 +1,12 @@ -import os +import pytest -if os.name == 'posix': + + at pytest.mark.skipif("os.name != 'posix'") +def test_raw_input(): + import os + import pty from pyrepl.readline import _ReadlineWrapper -else: - import pytest - e = pytest.raises(ImportError, "import pyrepl.readline") - assert 'termios' in e.value.message - pytest.skip('pyrepl.readline requires termios') - -def test_raw_input(): - import pty master, slave = pty.openpty() readline_wrapper = _ReadlineWrapper(slave, slave) os.write(master, b'input\n') From noreply at buildbot.pypy.org Mon Mar 4 22:41:35 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 4 Mar 2013 22:41:35 +0100 (CET) Subject: [pypy-commit] pypy py3k: match our output Message-ID: <20130304214135.C07FC1C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62018:e260e32ec658 Date: 2013-03-04 13:39 -0800 http://bitbucket.org/pypy/pypy/changeset/e260e32ec658/ Log: match our output diff --git a/lib-python/3/test/test_cprofile.py b/lib-python/3/test/test_cprofile.py --- a/lib-python/3/test/test_cprofile.py +++ b/lib-python/3/test/test_cprofile.py @@ -9,7 +9,7 @@ class CProfileTest(ProfileTest): profilerclass = cProfile.Profile - expected_max_output = "{built-in method max}" + expected_max_output = "{built-in function max}" def get_expected_output(self): return _ProfileOutput @@ -68,8 +68,8 @@ profilee.py:98(subhelper) <- 8 0.064 0.080 profilee.py:88(helper2) {built-in function hasattr} <- 4 0.000 0.004 profilee.py:73(helper1) 8 0.000 0.008 profilee.py:88(helper2) -{method 'append' of 'list' objects} <- 4 0.000 0.000 profilee.py:73(helper1) -{built-in function sys.exc_info} <- 4 0.000 0.000 profilee.py:73(helper1)""" +{built-in function sys.exc_info} <- 4 0.000 0.000 profilee.py:73(helper1) +{method 'append' of 'list' objects} <- 4 0.000 0.000 profilee.py:73(helper1)""" _ProfileOutput['print_callees'] = """\ :1() -> 1 0.270 1.000 profilee.py:25(testfunc) profilee.py:110(__getattr__) -> From noreply at buildbot.pypy.org Mon Mar 4 22:41:37 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 4 Mar 2013 22:41:37 +0100 (CET) Subject: [pypy-commit] pypy py3k: update code object's repr Message-ID: <20130304214137.8E3031C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62019:8f19c9e0e9c9 Date: 2013-03-04 13:39 -0800 http://bitbucket.org/pypy/pypy/changeset/8f19c9e0e9c9/ Log: update code object's repr diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1403,6 +1403,11 @@ w_obj = self.fsencode(w_obj) return self.bytes0_w(w_obj) + def fsdecode_w(self, w_obj): + if self.isinstance_w(w_obj, self.w_bytes): + w_obj = self.fsdecode(w_obj) + return self.unicode0_w(w_obj) + def bool_w(self, w_obj): # Unwraps a bool, also accepting an int for compatibility. # This is here mostly just for gateway.int_unwrapping_space_method(). diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -426,8 +426,13 @@ return space.newtuple([new_inst, space.newtuple(tup)]) def get_repr(self): - return "" % ( - self.co_name, self.co_filename, self.co_firstlineno) + space = self.space + # co_name should be an identifier + name = self.co_name.decode('utf-8') + fn = space.fsdecode_w(space.wrapbytes(self.co_filename)) + return u'' % ( + name, unicode(self.getaddrstring(space)), fn, + -1 if self.co_firstlineno == 0 else self.co_firstlineno) def repr(self, space): return space.wrap(self.get_repr()) diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -164,11 +164,9 @@ def f(): xxx res = repr(f.__code__) - expected = ["') def test_code_extra(self): d = {} diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -55,9 +55,7 @@ return self.space.bytes0_w(self.w_obj) def as_unicode(self): - space = self.space - w_unicode = space.fsdecode(self.w_obj) - return space.unicode0_w(w_unicode) + return self.space.fsdecode_w(self.w_obj) @specialize.memo() def dispatch_filename(func, tag=0): diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -29,7 +29,9 @@ def get_printable_location(next_instr, is_being_profiled, bytecode): from pypy.tool.stdlib_opcode import opcode_method_names name = opcode_method_names[ord(bytecode.co_code[next_instr])] - return '%s #%d %s' % (bytecode.get_repr(), next_instr, name) + # XXX: lame + repre = bytecode.get_repr().encode('utf-8', 'backslashreplace') + return '%s #%d %s' % (repre, next_instr, name) def get_jitcell_at(next_instr, is_being_profiled, bytecode): return bytecode.jit_cells.get((next_instr, is_being_profiled), None) From noreply at buildbot.pypy.org Mon Mar 4 22:41:39 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 4 Mar 2013 22:41:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: accommodate pure python pickle: these are automatically ignored when provided Message-ID: <20130304214139.2331D1C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62020:65d2eb0d0f42 Date: 2013-03-04 13:40 -0800 http://bitbucket.org/pypy/pypy/changeset/65d2eb0d0f42/ Log: accommodate pure python pickle: these are automatically ignored when provided by _pickle diff --git a/lib-python/3/test/test_pyclbr.py b/lib-python/3/test/test_pyclbr.py --- a/lib-python/3/test/test_pyclbr.py +++ b/lib-python/3/test/test_pyclbr.py @@ -157,7 +157,7 @@ # These were once about the 10 longest modules cm('random', ignore=('Random',)) # from _random import Random as CoreGenerator cm('cgi', ignore=('log',)) # set with = in module - cm('pickle') + cm('pickle', ignore=('Pickler', 'Unpickler',)) # from _pickle import * cm('aifc', ignore=('openfp',)) # set with = in module cm('sre_parse', ignore=('dump',)) # from sre_constants import * cm('pdb') From noreply at buildbot.pypy.org Mon Mar 4 22:41:41 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 4 Mar 2013 22:41:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: add str.__iter__ Message-ID: <20130304214141.C3F6F1C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62021:a45b0a662588 Date: 2013-03-04 13:40 -0800 http://bitbucket.org/pypy/pypy/changeset/a45b0a662588/ Log: add str.__iter__ 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 @@ -741,6 +741,13 @@ assert s[1:-1] == "b" assert s[-2:-1] == "b" + def test_iter(self): + foo = "\u1111\u2222\u3333" + assert hasattr(foo, '__iter__') + iter = foo.__iter__() + assert next(iter) == '\u1111' + assert next(iter) == '\u2222' + def test_no_len_on_str_iter(self): iterable = "hello" raises(TypeError, len, iter(iterable)) diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -881,6 +881,9 @@ def format__Unicode_ANY(space, w_unicode, w_spec): return newformat.run_formatter(space, w_spec, "format_string", w_unicode) +def iter__Unicode(space, w_unicode): + return space.newseqiter(w_unicode) + from pypy.objspace.std import unicodetype register_all(vars(), unicodetype) From noreply at buildbot.pypy.org Mon Mar 4 22:41:43 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 4 Mar 2013 22:41:43 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix cpython impl detail Message-ID: <20130304214143.5698F1C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62022:73738029fbf6 Date: 2013-03-04 13:40 -0800 http://bitbucket.org/pypy/pypy/changeset/73738029fbf6/ Log: fix cpython impl detail diff --git a/lib-python/3/test/string_tests.py b/lib-python/3/test/string_tests.py --- a/lib-python/3/test/string_tests.py +++ b/lib-python/3/test/string_tests.py @@ -2,6 +2,7 @@ Common tests shared by test_str, test_unicode, test_userstring and test_string. """ +import operator import unittest, string, sys, struct from test import support from collections import UserList @@ -1059,7 +1060,7 @@ self.checkequal('abc', 'abc', '__mul__', 1) self.checkequal('abcabcabc', 'abc', '__mul__', 3) self.checkraises(TypeError, 'abc', '__mul__') - self.checkraises(TypeError, 'abc', '__mul__', '') + self.checkraises(TypeError, operator.mul, 'abc', '') # XXX: on a 64-bit system, this doesn't raise an overflow error, # but either raises a MemoryError, or succeeds (if you have 54TiB) #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) From noreply at buildbot.pypy.org Mon Mar 4 22:41:44 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 4 Mar 2013 22:41:44 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge upstream Message-ID: <20130304214144.CEA871C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62023:1f5c86d3b78b Date: 2013-03-04 13:40 -0800 http://bitbucket.org/pypy/pypy/changeset/1f5c86d3b78b/ Log: merge upstream diff --git a/lib-python/3/test/test_extcall.py b/lib-python/3/test/test_extcall.py --- a/lib-python/3/test/test_extcall.py +++ b/lib-python/3/test/test_extcall.py @@ -89,19 +89,19 @@ >>> class Nothing: pass ... - >>> g(*Nothing()) + >>> g(*Nothing()) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: g() argument after * must be a sequence, not Nothing + TypeError: ...argument after * must be a sequence, not Nothing >>> class Nothing: ... def __len__(self): return 5 ... - >>> g(*Nothing()) + >>> g(*Nothing()) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: g() argument after * must be a sequence, not Nothing + TypeError: ...argument after * must be a sequence, not Nothing >>> class Nothing(): ... def __len__(self): return 5 @@ -153,52 +153,52 @@ ... TypeError: g() got multiple values for keyword argument 'x' - >>> f(**{1:2}) + >>> f(**{1:2}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() keywords must be strings + TypeError: ...keywords must be strings >>> h(**{'e': 2}) Traceback (most recent call last): ... TypeError: h() got an unexpected keyword argument 'e' - >>> h(*h) + >>> h(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after * must be a sequence, not function + TypeError: ...argument after * must be a sequence, not function - >>> dir(*h) + >>> dir(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() argument after * must be a sequence, not function + TypeError: ...argument after * must be a sequence, not function - >>> None(*h) + >>> None(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: NoneType object argument after * must be a sequence, \ + TypeError: ...argument after * must be a sequence, \ not function - >>> h(**h) + >>> h(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> dir(**h) + >>> dir(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> None(**h) + >>> None(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: NoneType object argument after ** must be a mapping, \ + TypeError: ...argument after ** must be a mapping, \ not function - >>> dir(b=1, **{'b': 1}) + >>> dir(b=1, **{'b': 1}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() got multiple values for keyword argument 'b' + TypeError: ...got multiple values for keyword argument 'b' Another helper function @@ -239,10 +239,10 @@ ... False True - >>> id(1, **{'foo': 1}) + >>> id(1, **{'foo': 1}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: id() takes no keyword arguments + TypeError: id() ... keyword argument... A corner case of keyword dictionary items being deleted during the function call setup. See . @@ -276,16 +276,16 @@ >>> def f(a): ... pass - >>> f(6, a=4, *(1, 2, 3)) + >>> f(6, a=4, *(1, 2, 3)) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() takes exactly 1 positional argument (5 given) + TypeError: f() takes exactly 1 ...argument (5 given) >>> def f(a, *, kw): ... pass - >>> f(6, 4, kw=4) + >>> f(6, 4, kw=4) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() takes exactly 1 positional argument (3 given) + TypeError: f() takes exactly 1 ...argument (3 given) """ import sys From noreply at buildbot.pypy.org Mon Mar 4 22:53:41 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 4 Mar 2013 22:53:41 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: hg backout 8fd11c9b3613 Message-ID: <20130304215341.89D4F1C034F@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62024:5e417536ec16 Date: 2013-03-04 21:30 +0100 http://bitbucket.org/pypy/pypy/changeset/5e417536ec16/ Log: hg backout 8fd11c9b3613 diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -26,7 +26,7 @@ class Buffer(Wrappable): """Abstract base class for memory views.""" - _attrs_ = ('format', 'itemsize') + __slots__ = ('format', 'itemsize') format = 'B' itemsize = 1 From noreply at buildbot.pypy.org Mon Mar 4 22:53:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 4 Mar 2013 22:53:42 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: hg backout 48a23a9cfefd Message-ID: <20130304215342.CDB981C0512@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62025:5e83707d05bd Date: 2013-03-04 21:32 +0100 http://bitbucket.org/pypy/pypy/changeset/5e83707d05bd/ Log: hg backout 48a23a9cfefd diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -27,8 +27,6 @@ """Abstract base class for memory views.""" __slots__ = ('format', 'itemsize') - format = 'B' - itemsize = 1 def getlength(self): raise NotImplementedError From noreply at buildbot.pypy.org Mon Mar 4 22:53:44 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 4 Mar 2013 22:53:44 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: Define format/itemsize on each Buffer subclass. Message-ID: <20130304215344.314B71C034F@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62026:61e3a8d0d557 Date: 2013-03-04 22:53 +0100 http://bitbucket.org/pypy/pypy/changeset/61e3a8d0d557/ Log: Define format/itemsize on each Buffer subclass. diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -218,6 +218,8 @@ def __init__(self, value): self.value = value + self.format = 'B' + self.itemsize = 1 def getlength(self): return len(self.value) @@ -246,6 +248,8 @@ def __init__(self, space, w_obj): self.space = space self.w_obj = w_obj + self.format = 'B' + self.itemsize = 1 def getlength(self): space = self.space @@ -284,6 +288,8 @@ self.buffer = buffer self.offset = offset self.size = size + self.format = 'B' + self.itemsize = 1 def getlength(self): at_most = self.buffer.getlength() - self.offset diff --git a/pypy/module/__pypy__/bytebuffer.py b/pypy/module/__pypy__/bytebuffer.py --- a/pypy/module/__pypy__/bytebuffer.py +++ b/pypy/module/__pypy__/bytebuffer.py @@ -10,6 +10,8 @@ def __init__(self, len): self.data = ['\x00'] * len + self.format = 'B' + self.itemsize = 1 def getlength(self): return len(self.data) diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -14,6 +14,8 @@ def __init__(self, raw_cdata, size): self.raw_cdata = raw_cdata self.size = size + self.format = 'B' + self.itemsize = 1 def getlength(self): return self.size diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -124,6 +124,8 @@ self.buf = buf self.start = start self.length = length + self.format = 'B' + self.itemsize = 1 def getlength(self): return self.length diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -18,6 +18,8 @@ class BytesIOBuffer(RWBuffer): def __init__(self, w_bytesio): self.w_bytesio = w_bytesio + self.format = 'B' + self.itemsize = 1 def getlength(self): return int(self.w_bytesio.string_size) diff --git a/pypy/module/_rawffi/buffer.py b/pypy/module/_rawffi/buffer.py --- a/pypy/module/_rawffi/buffer.py +++ b/pypy/module/_rawffi/buffer.py @@ -7,6 +7,8 @@ def __init__(self, datainstance): self.datainstance = datainstance + self.format = 'B' + self.itemsize = 1 def getlength(self): return self.datainstance.getrawsize() diff --git a/pypy/module/cpyext/buffer.py b/pypy/module/cpyext/buffer.py --- a/pypy/module/cpyext/buffer.py +++ b/pypy/module/cpyext/buffer.py @@ -20,6 +20,8 @@ self.c_buf = c_buf self.c_len = c_len self.w_obj = w_obj + self.format = 'B' + self.itemsize = 1 def destructor(self): assert isinstance(self, CBufferMixin) diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -235,6 +235,8 @@ self.ptr = ptr self.size = size self.w_obj = w_obj # kept alive + self.format = 'B' + self.itemsize = 1 def getlength(self): return self.size diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -411,6 +411,9 @@ class ArrayBuffer(RWBuffer): def __init__(self, impl): self.impl = impl + #XXX + self.format = 'B' + self.itemsize = 1 def getitem(self, item): return raw_storage_getitem(lltype.Char, self.impl.storage, item) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -662,6 +662,8 @@ class BytearrayBuffer(RWBuffer): def __init__(self, data): self.data = data + self.format = 'B' + self.itemsize = 1 def getlength(self): return len(self.data) From noreply at buildbot.pypy.org Tue Mar 5 00:29:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 00:29:34 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _sqlite3.Connection.__init__ check Message-ID: <20130304232934.9FB261C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62027:4e1f05782c7d Date: 2013-03-04 17:28 -0500 http://bitbucket.org/pypy/pypy/changeset/4e1f05782c7d/ Log: test and fix for _sqlite3.Connection.__init__ check diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -304,6 +304,8 @@ class Connection(object): + db = None + def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): self.db = c_void_p() @@ -509,6 +511,8 @@ self._reset_cursors() def _check_closed(self): + if self.db is None: + raise ProgrammingError("Base Connection.__init__ not called.") if getattr(self, 'closed', True): raise ProgrammingError("Cannot operate on a closed database.") 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 @@ -4,10 +4,12 @@ if sys.version_info < (2, 7): skip("lib_pypy._sqlite3 doesn't work with python < 2.7") +import pytest +from lib_pypy import _sqlite3 + def test_list_ddl(): """From issue996. Mostly just looking for lack of exceptions.""" - from lib_pypy._sqlite3 import connect - connection = connect(':memory:') + connection = _sqlite3.connect(':memory:') cursor = connection.cursor() cursor.execute('CREATE TABLE foo (bar INTEGER)') result = list(cursor) @@ -18,3 +20,12 @@ cursor.execute('SELECT * FROM foo') result = list(cursor) assert result == [(42,)] + +def test_connection_check_init(): + class Connection(_sqlite3.Connection): + def __init__(self, name): + pass + + con = Connection(":memory:") + e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()") + assert '__init__' in e.value.message From noreply at buildbot.pypy.org Tue Mar 5 00:29:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 00:29:35 +0100 (CET) Subject: [pypy-commit] pypy default: remove unnecessary _sqlite3.Connection.closed Message-ID: <20130304232935.DD1AF1C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62028:b17d5445e672 Date: 2013-03-04 17:57 -0500 http://bitbucket.org/pypy/pypy/changeset/b17d5445e672/ Log: remove unnecessary _sqlite3.Connection.closed diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -316,7 +316,6 @@ sqlite.sqlite3_busy_timeout(self.db, timeout) self.text_factory = unicode_text_factory - self.closed = False self.statements = [] self.statement_counter = 0 self.row_factory = None @@ -513,7 +512,7 @@ def _check_closed(self): if self.db is None: raise ProgrammingError("Base Connection.__init__ not called.") - if getattr(self, 'closed', True): + if not self.db: raise ProgrammingError("Cannot operate on a closed database.") def __enter__(self): @@ -531,18 +530,17 @@ def close(self): self._check_thread() - if self.closed: - return + for statement in self.statements: obj = statement() if obj is not None: obj.finalize() - self.closed = True - ret = sqlite.sqlite3_close(self.db) - self._reset_cursors() - if ret != SQLITE_OK: - raise self._get_exception(ret) + if self.db: + ret = sqlite.sqlite3_close(self.db) + if ret != SQLITE_OK: + raise self._get_exception(ret) + self.db.value = 0 def create_collation(self, name, callback): self._check_thread() From noreply at buildbot.pypy.org Tue Mar 5 00:29:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 00:29:37 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _sqlite3.Connection.__del__ (fixes issue 1325) Message-ID: <20130304232937.240271C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62029:3bf4d0b6f5e8 Date: 2013-03-04 17:49 -0500 http://bitbucket.org/pypy/pypy/changeset/3bf4d0b6f5e8/ Log: test and fix for _sqlite3.Connection.__del__ (fixes issue 1325) diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -343,6 +343,10 @@ if check_same_thread: self.thread_ident = thread_get_ident() + def __del__(self): + if self.db: + sqlite.sqlite3_close(self.db) + def _get_exception(self, error_code = None): if error_code is None: error_code = sqlite.sqlite3_errcode(self.db) 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 @@ -29,3 +29,20 @@ con = Connection(":memory:") e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()") assert '__init__' in e.value.message + + at pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") +def test_connection_del(tmpdir): + """For issue1325.""" + import gc + + def open_many(cleanup): + con = [] + for i in range(1024): + con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) + if cleanup: + con[i] = None + gc.collect(); gc.collect() + + pytest.raises(_sqlite3.OperationalError, open_many, False) + gc.collect(); gc.collect() + open_many(True) From noreply at buildbot.pypy.org Tue Mar 5 01:10:33 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 01:10:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix and test execve's fsencoding of env. fsencode the other obvious paths/cmd Message-ID: <20130305001033.28DC81C0313@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62030:9055369c8b5f Date: 2013-03-04 16:08 -0800 http://bitbucket.org/pypy/pypy/changeset/9055369c8b5f/ Log: fix and test execve's fsencoding of env. fsencode the other obvious paths/cmd line args diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -362,7 +362,7 @@ space.wrap(times[3]), space.wrap(times[4])]) - at unwrap_spec(cmd='str0') + at unwrap_spec(cmd='fsencode') def system(space, cmd): """Execute the command (a string) in a subshell.""" try: @@ -636,7 +636,7 @@ import signal rposix.os_kill(os.getpid(), signal.SIGABRT) - at unwrap_spec(src='str0', dst='str0') + at unwrap_spec(src='fsencode', dst='fsencode') def link(space, src, dst): "Create a hard link to a file." try: @@ -651,7 +651,7 @@ except OSError, e: raise wrap_oserror(space, e) - at unwrap_spec(path='str0') + at unwrap_spec(path='fsencode') def readlink(space, path): "Return a string representing the path to which the symbolic link points." try: @@ -751,7 +751,7 @@ w_keys = space.call_method(w_env, 'keys') for w_key in space.unpackiterable(w_keys): w_value = space.getitem(w_env, w_key) - env[space.str0_w(w_key)] = space.str0_w(w_value) + env[space.fsencode_w(w_key)] = space.fsencode_w(w_value) return env def execve(space, w_command, w_args, w_env): @@ -788,18 +788,18 @@ except OSError, e: raise wrap_oserror(space, e) - at unwrap_spec(mode=int, path='str0') + at unwrap_spec(mode=int, path='fsencode') def spawnv(space, mode, path, w_args): - args = [space.str0_w(w_arg) for w_arg in space.unpackiterable(w_args)] + args = [space.fsencode_w(w_arg) for w_arg in space.unpackiterable(w_args)] try: ret = os.spawnv(mode, path, args) except OSError, e: raise wrap_oserror(space, e) return space.wrap(ret) - at unwrap_spec(mode=int, path='str0') + at unwrap_spec(mode=int, path='fsencode') def spawnve(space, mode, path, w_args, w_env): - args = [space.str0_w(w_arg) for w_arg in space.unpackiterable(w_args)] + args = [space.fsencode_w(w_arg) for w_arg in space.unpackiterable(w_args)] env = _env2interp(space, w_env) try: ret = os.spawnve(mode, path, args, env) @@ -917,7 +917,7 @@ raise wrap_oserror(space, e) return space.w_None - at unwrap_spec(path='str0') + at unwrap_spec(path='fsencode') def chroot(space, path): """ chroot(path) @@ -1106,7 +1106,7 @@ except OSError, e: raise wrap_oserror(space, e) - at unwrap_spec(path='str0', uid=c_uid_t, gid=c_gid_t) + at unwrap_spec(path='fsencode', uid=c_uid_t, gid=c_gid_t) def chown(space, path, uid, gid): """Change the owner and group id of path to the numeric uid and gid.""" check_uid_range(space, uid) @@ -1116,7 +1116,7 @@ except OSError, e: raise wrap_oserror(space, e, path) - at unwrap_spec(path='str0', uid=c_uid_t, gid=c_gid_t) + at unwrap_spec(path='fsencode', uid=c_uid_t, gid=c_gid_t) def lchown(space, path, uid, gid): """Change the owner and group id of path to the numeric uid and gid. This function will not follow symbolic links.""" diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -442,16 +442,19 @@ if not hasattr(os, "fork"): skip("Need fork() to test execve()") try: - output = "caf\xe9 \u1234\n".encode(sys.getfilesystemencoding()) + output = "caf\xe9 \u1234".encode(sys.getfilesystemencoding()) except UnicodeEncodeError: skip("encoding not good enough") + t = ' abc\uDCFF' + output += t.encode(sys.getfilesystemencoding(), + 'surrogateescape') pid = os.fork() if pid == 0: os.execve("/bin/sh", ["sh", "-c", - "echo caf\xe9 \u1234 > onefile"], - {'ddd': 'xxx'}) + "echo caf\xe9 \u1234 $t > onefile"], + {'ddd': 'xxx', 't': t}) os.waitpid(pid, 0) - assert open("onefile", "rb").read() == output + assert open("onefile", "rb").read() == output + b'\n' os.unlink("onefile") pass # <- please, inspect.getsource(), don't crash From noreply at buildbot.pypy.org Tue Mar 5 01:10:34 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 01:10:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: impl details Message-ID: <20130305001034.5F9181C0313@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62031:ef3b5808a96a Date: 2013-03-04 16:09 -0800 http://bitbucket.org/pypy/pypy/changeset/ef3b5808a96a/ Log: impl details diff --git a/lib-python/3/test/test_subprocess.py b/lib-python/3/test/test_subprocess.py --- a/lib-python/3/test/test_subprocess.py +++ b/lib-python/3/test/test_subprocess.py @@ -855,6 +855,7 @@ self.fail("Exception raised by preexec_fn did not make it " "to the parent process.") + @support.impl_detail("PyPy's _posixsubprocess doesn't have to disable gc") def test_preexec_gc_module_failure(self): # This tests the code that disables garbage collection if the child # process will execute any Python. @@ -1438,6 +1439,7 @@ ident = id(p) pid = p.pid del p + support.gc_collect() # check that p is in the active processes list self.assertIn(ident, [id(o) for o in subprocess._active]) @@ -1457,6 +1459,7 @@ ident = id(p) pid = p.pid del p + support.gc_collect() os.kill(pid, signal.SIGKILL) # check that p is in the active processes list self.assertIn(ident, [id(o) for o in subprocess._active]) From noreply at buildbot.pypy.org Tue Mar 5 01:36:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 01:36:57 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix segfault in _sqlite3.Connection.total_changes after close() Message-ID: <20130305003657.BDDD41C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62032:88af669ec637 Date: 2013-03-04 19:36 -0500 http://bitbucket.org/pypy/pypy/changeset/88af669ec637/ Log: test and fix segfault in _sqlite3.Connection.total_changes after close() diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -529,6 +529,7 @@ self.rollback() def _get_total_changes(self): + self._check_closed() return sqlite.sqlite3_total_changes(self.db) total_changes = property(_get_total_changes) 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 @@ -21,6 +21,11 @@ result = list(cursor) assert result == [(42,)] +def test_total_changes_after_close(): + con = _sqlite3.connect(':memory:') + con.close() + pytest.raises(_sqlite3.ProgrammingError, "con.total_changes") + def test_connection_check_init(): class Connection(_sqlite3.Connection): def __init__(self, name): From noreply at buildbot.pypy.org Tue Mar 5 02:16:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 02:16:24 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _sqlite3.Cursor.__init__ check Message-ID: <20130305011624.5D3AB1C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62033:d085b86816f2 Date: 2013-03-04 20:00 -0500 http://bitbucket.org/pypy/pypy/changeset/d085b86816f2/ Log: test and fix for _sqlite3.Cursor.__init__ check diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -742,6 +742,8 @@ class Cursor(object): + initialized = False + def __init__(self, con): if not isinstance(con, Connection): raise TypeError @@ -756,8 +758,11 @@ self.statement = None self.reset = False self.locked = False + self.initialized = True def _check_closed(self): + if not self.initialized: + raise ProgrammingError("Base Cursor.__init__ not called.") if not getattr(self, 'connection', None): raise ProgrammingError("Cannot operate on a closed cursor.") self.connection._check_thread() 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 @@ -35,6 +35,16 @@ e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()") assert '__init__' in e.value.message +def test_cursor_check_init(): + class Cursor(_sqlite3.Cursor): + def __init__(self, name): + pass + + con = _sqlite3.connect(":memory:") + cur = Cursor(con) + e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')") + assert '__init__' in e.value.message + @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): """For issue1325.""" From noreply at buildbot.pypy.org Tue Mar 5 02:16:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 02:16:25 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _sqlite3.Cursor.close behavior Message-ID: <20130305011625.842401C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62034:38cd1a49ec1e Date: 2013-03-04 20:12 -0500 http://bitbucket.org/pypy/pypy/changeset/38cd1a49ec1e/ Log: test and fix for _sqlite3.Cursor.close behavior diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -758,12 +758,13 @@ self.statement = None self.reset = False self.locked = False + self.closed = False self.initialized = True def _check_closed(self): if not self.initialized: raise ProgrammingError("Base Cursor.__init__ not called.") - if not getattr(self, 'connection', None): + if self.closed: raise ProgrammingError("Cannot operate on a closed cursor.") self.connection._check_thread() self.connection._check_closed() @@ -925,14 +926,16 @@ return sqlite.sqlite3_last_insert_rowid(self.connection.db) def close(self): - if not self.connection: - return - self._check_closed() + self.connection._check_thread() + self.connection._check_closed() if self.statement: self.statement.reset() self.statement = None - self.connection.cursors.remove(weakref.ref(self)) - self.connection = None + self.closed = True + try: + self.connection.cursors.remove(weakref.ref(self)) + except ValueError: + pass def setinputsizes(self, *args): pass 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 @@ -45,6 +45,13 @@ e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')") assert '__init__' in e.value.message +def test_cursor_after_close(): + con = _sqlite3.connect(':memory:') + cur = con.execute('select 1') + cur.close() + con.close() + pytest.raises(_sqlite3.ProgrammingError, "cur.close()") + @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): """For issue1325.""" From noreply at buildbot.pypy.org Tue Mar 5 02:36:39 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 02:36:39 +0100 (CET) Subject: [pypy-commit] pypy default: pep8/whitespace Message-ID: <20130305013639.0CA0B1C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62035:c08d0191bb62 Date: 2013-03-04 20:36 -0500 http://bitbucket.org/pypy/pypy/changeset/c08d0191bb62/ Log: pep8/whitespace diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -40,7 +40,7 @@ except OSError: continue else: - raise ImportError("Could not load C-library, tried: %s" %(names,)) + raise ImportError("Could not load C-library, tried: %s" % (names,)) # pysqlite version information version = "2.6.0" @@ -151,7 +151,7 @@ sqlite.sqlite3_value_type.argtypes = [c_void_p] sqlite.sqlite3_value_type.restype = c_int -sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p] +sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p] sqlite.sqlite3_bind_blob.restype = c_int sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] sqlite.sqlite3_bind_double.restype = c_int @@ -167,7 +167,7 @@ sqlite.sqlite3_bind_parameter_index.restype = c_int sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] sqlite.sqlite3_bind_parameter_name.restype = c_char_p -sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int,c_void_p] +sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p] sqlite.sqlite3_bind_text.restype = c_int sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] sqlite.sqlite3_busy_timeout.restype = c_int @@ -312,7 +312,7 @@ if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: - timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds + timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds sqlite.sqlite3_busy_timeout(self.db, timeout) self.text_factory = unicode_text_factory @@ -347,7 +347,7 @@ if self.db: sqlite.sqlite3_close(self.db) - def _get_exception(self, error_code = None): + def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self.db) error_message = sqlite.sqlite3_errmsg(self.db) @@ -359,8 +359,8 @@ elif error_code == SQLITE_NOMEM: exc = MemoryError elif error_code in (SQLITE_ERROR, SQLITE_PERM, SQLITE_ABORT, SQLITE_BUSY, SQLITE_LOCKED, - SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, - SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): + SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, + SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): exc = OperationalError elif error_code == SQLITE_CORRUPT: exc = DatabaseError @@ -438,6 +438,7 @@ def _get_isolation_level(self): return self._isolation_level + def _set_isolation_level(self, val): if val is None: self.commit() @@ -570,7 +571,6 @@ c_collation_callback = COLLATION(collation_callback) self._collations[name] = c_collation_callback - ret = sqlite.sqlite3_create_collation(self.db, name, SQLITE_UTF8, None, @@ -654,7 +654,7 @@ aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( - context, sizeof(c_ssize_t)), + context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) if not aggregate_ptr[0]: @@ -683,7 +683,7 @@ aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( - context, sizeof(c_ssize_t)), + context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) if aggregate_ptr[0]: @@ -728,6 +728,7 @@ DML, DQL, DDL = range(3) + class CursorLock(object): def __init__(self, cursor): self.cursor = cursor @@ -939,20 +940,21 @@ def setinputsizes(self, *args): pass + def setoutputsize(self, *args): pass - description = property(_getdescription) lastrowid = property(_getlastrowid) + class Statement(object): def __init__(self, connection, sql): self.statement = None if not isinstance(sql, str): raise ValueError("sql must be a string") self.con = connection - self.sql = sql # DEBUG ONLY + self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): self.kind = DML @@ -1020,11 +1022,11 @@ for c in param: if ord(c) & 0x80 != 0: raise self.con.ProgrammingError( - "You must not use 8-bit bytestrings unless " - "you use a text_factory that can interpret " - "8-bit bytestrings (like text_factory = str). " - "It is highly recommended that you instead " - "just switch your application to Unicode strings.") + "You must not use 8-bit bytestrings unless " + "you use a text_factory that can interpret " + "8-bit bytestrings (like text_factory = str). " + "It is highly recommended that you instead " + "just switch your application to Unicode strings.") def set_param(self, idx, param): cvt = converters.get(type(param)) @@ -1086,7 +1088,7 @@ try: param = params[param_name] except KeyError: - raise ProgrammingError("missing parameter '%s'" %param) + raise ProgrammingError("missing parameter '%s'" % param) self.set_param(idx, param) def next(self, cursor): @@ -1176,6 +1178,7 @@ desc.append((name, None, None, None, None, None, None)) return desc + class Row(object): def __init__(self, cursor, values): self.description = cursor.description @@ -1209,6 +1212,7 @@ def __hash__(self): return hash(tuple(self.description)) ^ hash(tuple(self.values)) + def _check_remaining_sql(s): state = "NORMAL" for char in s: @@ -1251,8 +1255,9 @@ return 1 return 0 + def _convert_params(con, nargs, params): - _params = [] + _params = [] for i in range(nargs): typ = sqlite.sqlite3_value_type(params[i]) if typ == SQLITE_INTEGER: @@ -1276,6 +1281,7 @@ _params.append(val) return _params + def _convert_result(con, val): if val is None: sqlite.sqlite3_result_null(con) @@ -1294,6 +1300,7 @@ else: raise NotImplementedError + def function_callback(real_cb, context, nargs, c_params): params = _convert_params(context, nargs, c_params) try: @@ -1328,15 +1335,19 @@ converters = {} adapters = {} + class PrepareProtocol(object): pass + def register_adapter(typ, callable): adapters[typ, PrepareProtocol] = callable + def register_converter(name, callable): converters[name.upper()] = callable + def register_adapters_and_converters(): def adapt_date(val): return val.isoformat() @@ -1356,16 +1367,15 @@ microseconds = int(timepart_full[1]) else: microseconds = 0 - - val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds) - return val - + return datetime.datetime(year, month, day, + hours, minutes, seconds, microseconds) register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) register_converter("date", convert_date) register_converter("timestamp", convert_timestamp) + def adapt(val, proto=PrepareProtocol): # look for an adapter in the registry adapter = adapters.get((type(val), proto), None) @@ -1396,6 +1406,7 @@ register_adapters_and_converters() + def OptimizedUnicode(s): try: val = unicode(s, "ascii").encode("ascii") From noreply at buildbot.pypy.org Tue Mar 5 03:13:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 03:13:28 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _sqlite3.Cursor.__del__ Message-ID: <20130305021328.723FF1C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62036:811b9dc8cc2c Date: 2013-03-04 21:13 -0500 http://bitbucket.org/pypy/pypy/changeset/811b9dc8cc2c/ Log: test and fix for _sqlite3.Cursor.__del__ diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -933,6 +933,10 @@ self.statement.reset() self.statement = None self.closed = True + + def __del__(self): + if self.statement: + self.statement.reset() try: self.connection.cursors.remove(weakref.ref(self)) except ValueError: 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 @@ -53,6 +53,18 @@ pytest.raises(_sqlite3.ProgrammingError, "cur.close()") @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") +def test_cursor_del(): + con = _sqlite3.connect(':memory:') + cur = con.execute('select 1') + stmt = cur.statement + cur.close() + cur = con.execute('select 1') + assert cur.statement is stmt + del cur; import gc; gc.collect(); gc.collect() + cur = con.execute('select 1') + assert cur.statement is stmt + + at pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): """For issue1325.""" import gc From noreply at buildbot.pypy.org Tue Mar 5 03:29:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 03:29:15 +0100 (CET) Subject: [pypy-commit] pypy default: clean up some warnings in _sqlite3 __del__ methods Message-ID: <20130305022915.3292F1C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62037:06dad1b827c9 Date: 2013-03-04 21:28 -0500 http://bitbucket.org/pypy/pypy/changeset/06dad1b827c9/ Log: clean up some warnings in _sqlite3 __del__ methods diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -935,12 +935,13 @@ self.closed = True def __del__(self): - if self.statement: - self.statement.reset() - try: - self.connection.cursors.remove(weakref.ref(self)) - except ValueError: - pass + if self.initialized: + if self.statement: + self.statement.reset() + try: + self.connection.cursors.remove(weakref.ref(self)) + except ValueError: + pass def setinputsizes(self, *args): pass @@ -953,8 +954,9 @@ class Statement(object): + statement = None + def __init__(self, connection, sql): - self.statement = None if not isinstance(sql, str): raise ValueError("sql must be a string") self.con = connection @@ -1170,8 +1172,8 @@ self.in_use = True def __del__(self): - sqlite.sqlite3_finalize(self.statement) - self.statement = None + if self.statement: + sqlite.sqlite3_finalize(self.statement) def _get_description(self): if self.kind == DML: From noreply at buildbot.pypy.org Tue Mar 5 03:32:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 03:32:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: we expect the pypy specific CO_CONTAINSGLOBALS Message-ID: <20130305023249.D0A8D1C0FD4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62038:631a86b75fe6 Date: 2013-03-04 18:31 -0800 http://bitbucket.org/pypy/pypy/changeset/631a86b75fe6/ Log: we expect the pypy specific CO_CONTAINSGLOBALS diff --git a/lib-python/3/test/test_dis.py b/lib-python/3/test/test_dis.py --- a/lib-python/3/test/test_dis.py +++ b/lib-python/3/test/test_dis.py @@ -218,7 +218,7 @@ Kw-only arguments: 0 Number of locals: 1 Stack size: 4 -Flags: OPTIMIZED, NEWLOCALS, NOFREE +Flags: OPTIMIZED, NEWLOCALS, NOFREE, 0x80000 Constants: 0: %r 1: '__func__' @@ -285,7 +285,7 @@ Kw-only arguments: 0 Number of locals: 1 Stack size: 8 -Flags: OPTIMIZED, NEWLOCALS, NESTED +Flags: OPTIMIZED, NEWLOCALS, NESTED, 0x80000 Constants: 0: None Names: @@ -307,7 +307,7 @@ Kw-only arguments: 0 Number of locals: 0 Stack size: 2 -Flags: NOFREE +Flags: NOFREE, 0x80000 Constants: 0: 1 Names: @@ -320,7 +320,7 @@ Kw-only arguments: 0 Number of locals: 0 Stack size: 2 -Flags: NOFREE +Flags: NOFREE, 0x80000 Constants: 0: 1 1: None @@ -334,7 +334,7 @@ Kw-only arguments: 0 Number of locals: 0 Stack size: 2 -Flags: NOFREE +Flags: NOFREE, 0x80000 Constants: 0: 0 1: 1 From noreply at buildbot.pypy.org Tue Mar 5 03:32:51 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 03:32:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: match cpython: top level defs may have CO_NOFREE Message-ID: <20130305023251.28A5B1C0FD4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62039:ec6e34cac076 Date: 2013-03-04 18:31 -0800 http://bitbucket.org/pypy/pypy/changeset/ec6e34cac076/ Log: match cpython: top level defs may have CO_NOFREE diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -1198,7 +1198,10 @@ tree.walkabout(self) def _get_code_flags(self): - return 0 + flags = 0 + if not self.cell_vars and not self.free_vars: + flags |= consts.CO_NOFREE + return flags class AbstractFunctionCodeGenerator(PythonCodeGenerator): diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -10,6 +10,7 @@ cls.w_file = cls.space.wrap(filename) cls.w_CO_CONTAINSGLOBALS = cls.space.wrap(consts.CO_CONTAINSGLOBALS) + cls.w_CO_NOFREE = cls.space.wrap(consts.CO_NOFREE) def test_attributes(self): def f(): pass @@ -169,6 +170,8 @@ assert res.endswith('>') def test_code_extra(self): + assert compile("x = x + 1", 'baz', 'exec').co_flags & self.CO_NOFREE + d = {} exec("""if 1: def f(): @@ -178,7 +181,7 @@ """, d) # check for new flag, CO_NOFREE - assert d['f'].__code__.co_flags & 0x40 + assert d['f'].__code__.co_flags & self.CO_NOFREE exec("""if 1: def f(x): From noreply at buildbot.pypy.org Tue Mar 5 03:32:52 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 03:32:52 +0100 (CET) Subject: [pypy-commit] pypy py3k: error message impl details (we'll probably try to match these in 3.3) Message-ID: <20130305023252.641771C0FD4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62040:06f397a33874 Date: 2013-03-04 18:31 -0800 http://bitbucket.org/pypy/pypy/changeset/06f397a33874/ Log: error message impl details (we'll probably try to match these in 3.3) diff --git a/lib-python/3/test/test_keywordonlyarg.py b/lib-python/3/test/test_keywordonlyarg.py --- a/lib-python/3/test/test_keywordonlyarg.py +++ b/lib-python/3/test/test_keywordonlyarg.py @@ -78,7 +78,7 @@ pass with self.assertRaises(TypeError) as exc: f(1, 2, 3) - expected = "f() takes at most 2 positional arguments (3 given)" + expected = "f() takes at most 2 arguments (3 given)" self.assertEqual(str(exc.exception), expected) def testSyntaxErrorForFunctionCall(self): diff --git a/lib-python/3/test/test_metaclass.py b/lib-python/3/test/test_metaclass.py --- a/lib-python/3/test/test_metaclass.py +++ b/lib-python/3/test/test_metaclass.py @@ -134,11 +134,11 @@ Another way. >>> kwds = {'metaclass': type} - >>> class C(metaclass=type, **kwds): pass + >>> class C(metaclass=type, **kwds): pass #doctest: +ELLIPSIS ... Traceback (most recent call last): [...] - TypeError: __build_class__() got multiple values for keyword argument 'metaclass' + TypeError: ...got multiple values for keyword argument 'metaclass' >>> Use a __prepare__ method that returns an instrumented dict. From noreply at buildbot.pypy.org Tue Mar 5 03:32:53 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 03:32:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: +target Message-ID: <20130305023253.90ECD1C0FD4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62041:afa1b1b0f238 Date: 2013-03-04 18:32 -0800 http://bitbucket.org/pypy/pypy/changeset/afa1b1b0f238/ Log: +target diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -964,7 +964,7 @@ if star.ctx != ast.Store: self.error("can use starred expression only as assignment target", star) - self.error("starred assignment must be in list or tuple", star) + self.error("starred assignment target must be in a list or tuple", star) def visit_Tuple(self, tup): self.update_position(tup.lineno) From noreply at buildbot.pypy.org Tue Mar 5 05:05:45 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 05:05:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: type check SRE_Pattern's pattern object when compiling and allow it to be None Message-ID: <20130305040545.4EF5D1C034F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62042:37e87954b442 Date: 2013-03-04 20:04 -0800 http://bitbucket.org/pypy/pypy/changeset/37e87954b442/ Log: type check SRE_Pattern's pattern object when compiling and allow it to be None diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -104,7 +104,8 @@ if endpos < pos: endpos = pos if space.is_true(space.isinstance(w_string, space.w_unicode)): unicodestr = space.unicode_w(w_string) - if not space.isinstance_w(self.w_pattern, space.w_unicode): + if not (space.is_none(self.w_pattern) or + space.isinstance_w(self.w_pattern, space.w_unicode)): raise OperationError(space.w_TypeError, space.wrap( "can't use a string pattern on a bytes-like object")) if pos > len(unicodestr): pos = len(unicodestr) @@ -113,7 +114,8 @@ pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) - if space.isinstance_w(self.w_pattern, space.w_unicode): + if (not space.is_none(self.w_pattern) and + space.isinstance_w(self.w_pattern, space.w_unicode)): raise OperationError(space.w_TypeError, space.wrap( "can't use a bytes pattern on a string-like object")) if pos > len(str): pos = len(str) @@ -292,6 +294,10 @@ w_srepat = space.allocate_instance(W_SRE_Pattern, w_subtype) srepat = space.interp_w(W_SRE_Pattern, w_srepat) srepat.space = space + # Type check + if not (space.is_none(w_pattern) or + space.isinstance_w(w_pattern, space.w_unicode)): + space.bufferstr_w(w_pattern) srepat.w_pattern = w_pattern # the original uncompiled pattern srepat.flags = flags srepat.code = code diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -93,6 +93,10 @@ import re, _weakref _weakref.ref(re.compile(r"")) + def test_pattern_check(self): + import _sre + raises(TypeError, _sre.compile, {}, 0, []) + class AppTestSreMatch: spaceconfig = dict(usemodules=('array',)) @@ -325,6 +329,12 @@ assert ("bla", "") == (p.search().group(0), p.search().group(0)) assert None == p.search() + def test_no_pattern(self): + import sre_compile, sre_parse + sre_pattern = sre_compile.compile( + sre_parse.SubPattern(sre_parse.Pattern())) + assert sre_pattern.scanner('s') is not None + class AppTestGetlower: spaceconfig = dict(usemodules=('_locale',)) From noreply at buildbot.pypy.org Tue Mar 5 05:14:58 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:14:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: port datetime optimizations in 91b8e2795113 and 043d831e8736 Message-ID: <20130305041458.756231C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62043:275233336f3c Date: 2013-03-04 21:56 -0500 http://bitbucket.org/pypy/pypy/changeset/275233336f3c/ Log: port datetime optimizations in 91b8e2795113 and 043d831e8736 diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -22,6 +22,9 @@ def _cmp(x, y): return 0 if x == y else 1 if x > y else -1 +def _round(x): + return _math.floor(x + 0.5) if x >= 0.0 else _math.ceil(x - 0.5) + MINYEAR = 1 MAXYEAR = 9999 _MAXORDINAL = 3652059 # date.max.toordinal() @@ -379,7 +382,7 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = round(microseconds, 0) + microseconds = float(_round(microseconds)) seconds, microseconds = divmod(microseconds, 1e6) assert microseconds == int(microseconds) assert seconds == int(seconds) @@ -399,7 +402,7 @@ assert abs(s) <= 3 * 24 * 3600 microseconds = float(microseconds) microseconds += usdouble - microseconds = round(microseconds, 0) + microseconds = float(_round(microseconds)) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 @@ -1364,7 +1367,7 @@ converter = _time.localtime if tz is None else _time.gmtime t, frac = divmod(t, 1.0) - us = round(frac * 1e6) + us = _round(frac * 1e6) # If timestamp is less than one microsecond smaller than a # full second, us can be rounded up to 1000000. In this case, @@ -1384,7 +1387,7 @@ def utcfromtimestamp(cls, t): "Construct a UTC datetime from a POSIX timestamp (like time.time())." t, frac = divmod(t, 1.0) - us = round(frac * 1e6) + us = _round(frac * 1e6) # If timestamp is less than one microsecond smaller than a # full second, us can be rounded up to 1000000. In this case, From noreply at buildbot.pypy.org Tue Mar 5 05:14:59 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:14:59 +0100 (CET) Subject: [pypy-commit] pypy py3k: port datetime changes in b62868397a09 Message-ID: <20130305041459.CDDC61C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62044:768e6f96277d Date: 2013-03-04 22:15 -0500 http://bitbucket.org/pypy/pypy/changeset/768e6f96277d/ Log: port datetime changes in b62868397a09 diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -930,6 +930,7 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1016,6 +1017,7 @@ Properties (readonly): hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1308,10 +1310,8 @@ The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ - __slots__ = date.__slots__ + ( - '_hour', '_minute', '_second', - '_microsecond', '_tzinfo') def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): if isinstance(year, bytes) and len(year) == 10: From noreply at buildbot.pypy.org Tue Mar 5 05:15:01 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:01 +0100 (CET) Subject: [pypy-commit] pypy default: whitespace Message-ID: <20130305041501.1206C1C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62045:526e593733b5 Date: 2013-03-04 22:16 -0500 http://bitbucket.org/pypy/pypy/changeset/526e593733b5/ Log: whitespace diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -458,7 +458,6 @@ Representation: (days, seconds, microseconds). Why? Because I felt like it. """ - __slots__ = '_days', '_seconds', '_microseconds' def __new__(cls, days=0, seconds=0, microseconds=0, @@ -772,7 +771,6 @@ Properties (readonly): year, month, day """ - __slots__ = '_year', '_month', '_day' def __new__(cls, year, month=None, day=None): @@ -1065,7 +1063,6 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ - __slots__ = () def tzname(self, dt): @@ -1157,7 +1154,6 @@ Properties (readonly): hour, minute, second, microsecond, tzinfo """ - __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): @@ -1458,7 +1454,6 @@ The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ - __slots__ = date.__slots__ + time.__slots__ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, From noreply at buildbot.pypy.org Tue Mar 5 05:15:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:02 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130305041502.676221C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62046:3306e356c360 Date: 2013-03-04 22:19 -0500 http://bitbucket.org/pypy/pypy/changeset/3306e356c360/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -40,7 +40,7 @@ except OSError: continue else: - raise ImportError("Could not load C-library, tried: %s" %(names,)) + raise ImportError("Could not load C-library, tried: %s" % (names,)) # pysqlite version information version = "2.6.0" @@ -158,7 +158,7 @@ sqlite.sqlite3_value_type.argtypes = [c_void_p] sqlite.sqlite3_value_type.restype = c_int -sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p] +sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p] sqlite.sqlite3_bind_blob.restype = c_int sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] sqlite.sqlite3_bind_double.restype = c_int @@ -174,7 +174,7 @@ sqlite.sqlite3_bind_parameter_index.restype = c_int sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] sqlite.sqlite3_bind_parameter_name.restype = c_char_p -sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, TEXT, c_int,c_void_p] +sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, TEXT, c_int, c_void_p] sqlite.sqlite3_bind_text.restype = c_int sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] sqlite.sqlite3_busy_timeout.restype = c_int @@ -311,17 +311,18 @@ class Connection(object): + db = None + def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): self.db = c_void_p() if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: - timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds + timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds sqlite.sqlite3_busy_timeout(self.db, timeout) self.text_factory = unicode_text_factory - self.closed = False self.statements = [] self.statement_counter = 0 self.row_factory = None @@ -349,7 +350,11 @@ if check_same_thread: self.thread_ident = thread_get_ident() - def _get_exception(self, error_code = None): + def __del__(self): + if self.db: + sqlite.sqlite3_close(self.db) + + def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self.db) error_message = sqlite.sqlite3_errmsg(self.db) @@ -362,8 +367,8 @@ elif error_code == SQLITE_NOMEM: exc = MemoryError elif error_code in (SQLITE_ERROR, SQLITE_PERM, SQLITE_ABORT, SQLITE_BUSY, SQLITE_LOCKED, - SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, - SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): + SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, + SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): exc = OperationalError elif error_code == SQLITE_CORRUPT: exc = DatabaseError @@ -441,6 +446,7 @@ def _get_isolation_level(self): return self._isolation_level + def _set_isolation_level(self, val): if val is None: self.commit() @@ -517,7 +523,9 @@ self._reset_cursors() def _check_closed(self): - if getattr(self, 'closed', True): + if self.db is None: + raise ProgrammingError("Base Connection.__init__ not called.") + if not self.db: raise ProgrammingError("Cannot operate on a closed database.") def __enter__(self): @@ -530,23 +538,23 @@ self.rollback() def _get_total_changes(self): + self._check_closed() return sqlite.sqlite3_total_changes(self.db) total_changes = property(_get_total_changes) def close(self): self._check_thread() - if self.closed: - return + for statement in self.statements: obj = statement() if obj is not None: obj.finalize() - self.closed = True - ret = sqlite.sqlite3_close(self.db) - self._reset_cursors() - if ret != SQLITE_OK: - raise self._get_exception(ret) + if self.db: + ret = sqlite.sqlite3_close(self.db) + if ret != SQLITE_OK: + raise self._get_exception(ret) + self.db.value = 0 def create_collation(self, name, callback): self._check_thread() @@ -571,7 +579,6 @@ c_collation_callback = COLLATION(collation_callback) self._collations[name] = c_collation_callback - ret = sqlite.sqlite3_create_collation(self.db, name, SQLITE_UTF8, None, @@ -655,7 +662,7 @@ aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( - context, sizeof(c_ssize_t)), + context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) if not aggregate_ptr[0]: @@ -684,7 +691,7 @@ aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( - context, sizeof(c_ssize_t)), + context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) if aggregate_ptr[0]: @@ -729,6 +736,7 @@ DML, DQL, DDL = range(3) + class CursorLock(object): def __init__(self, cursor): self.cursor = cursor @@ -743,6 +751,8 @@ class Cursor(object): + initialized = False + def __init__(self, con): if not isinstance(con, Connection): raise TypeError @@ -757,9 +767,13 @@ self.statement = None self.reset = False self.locked = False + self.closed = False + self.initialized = True def _check_closed(self): - if not getattr(self, 'connection', None): + if not self.initialized: + raise ProgrammingError("Base Cursor.__init__ not called.") + if self.closed: raise ProgrammingError("Cannot operate on a closed cursor.") self.connection._check_thread() self.connection._check_closed() @@ -915,31 +929,40 @@ return sqlite.sqlite3_last_insert_rowid(self.connection.db) def close(self): - if not self.connection: - return - self._check_closed() + self.connection._check_thread() + self.connection._check_closed() if self.statement: self.statement.reset() self.statement = None - self.connection.cursors.remove(weakref.ref(self)) - self.connection = None + self.closed = True + + def __del__(self): + if self.initialized: + if self.statement: + self.statement.reset() + try: + self.connection.cursors.remove(weakref.ref(self)) + except ValueError: + pass def setinputsizes(self, *args): pass + def setoutputsize(self, *args): pass - description = property(_getdescription) lastrowid = property(_getlastrowid) + class Statement(object): + statement = None + def __init__(self, connection, sql): - self.statement = None if not isinstance(sql, str): raise ValueError("sql must be a string") self.con = connection - self.sql = sql # DEBUG ONLY + self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): self.kind = DML @@ -1141,8 +1164,8 @@ self.in_use = True def __del__(self): - sqlite.sqlite3_finalize(self.statement) - self.statement = None + if self.statement: + sqlite.sqlite3_finalize(self.statement) def _get_description(self): if self.kind == DML: @@ -1154,6 +1177,7 @@ desc.append((name, None, None, None, None, None, None)) return desc + class Row(object): def __init__(self, cursor, values): self.description = cursor.description @@ -1187,6 +1211,7 @@ def __hash__(self): return hash(tuple(self.description)) ^ hash(tuple(self.values)) + def _check_remaining_sql(s): state = "NORMAL" for char in s: @@ -1229,8 +1254,9 @@ return 1 return 0 + def _convert_params(con, nargs, params): - _params = [] + _params = [] for i in range(nargs): typ = sqlite.sqlite3_value_type(params[i]) if typ == SQLITE_INTEGER: @@ -1254,6 +1280,7 @@ _params.append(val) return _params + def _convert_result(con, val): if val is None: sqlite.sqlite3_result_null(con) @@ -1270,6 +1297,7 @@ else: raise NotImplementedError + def function_callback(real_cb, context, nargs, c_params): params = _convert_params(context, nargs, c_params) try: @@ -1304,15 +1332,19 @@ converters = {} adapters = {} + class PrepareProtocol(object): pass + def register_adapter(typ, callable): adapters[typ, PrepareProtocol] = callable + def register_converter(name, callable): converters[name.upper()] = callable + def register_adapters_and_converters(): def adapt_date(val): return val.isoformat() @@ -1332,16 +1364,15 @@ microseconds = int(timepart_full[1]) else: microseconds = 0 - - val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds) - return val - + return datetime.datetime(year, month, day, + hours, minutes, seconds, microseconds) register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) register_converter("date", convert_date) register_converter("timestamp", convert_timestamp) + def adapt(val, proto=PrepareProtocol): # look for an adapter in the registry adapter = adapters.get((type(val), proto), None) @@ -1372,6 +1403,7 @@ register_adapters_and_converters() + def OptimizedUnicode(s): try: val = str(s, "ascii").encode("ascii") diff --git a/pypy/module/test_lib_pypy/pyrepl/test_basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py --- a/pypy/module/test_lib_pypy/pyrepl/test_basic.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_basic.py @@ -76,6 +76,8 @@ ( 'accept', ['cd '])]) +# interrupt uses os.kill which doesn't go through signal handlers on windows + at pytest.mark.skipif("os.name == 'nt'") def test_interrupt(): with pytest.raises(KeyboardInterrupt): read_spec([('interrupt', [''])]) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -45,6 +45,8 @@ ] read_spec(spec, HistoricalTestReader) + + at pytest.mark.skipif("os.name != 'posix'") def test_signal_failure(monkeypatch): import os import pty diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py --- a/pypy/module/test_lib_pypy/pyrepl/test_readline.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py @@ -1,9 +1,12 @@ -from pyrepl.readline import _ReadlineWrapper -import os -import pty +import pytest + at pytest.mark.skipif("os.name != 'posix'") def test_raw_input(): + import os + import pty + from pyrepl.readline import _ReadlineWrapper + master, slave = pty.openpty() readline_wrapper = _ReadlineWrapper(slave, slave) os.write(master, b'input\n') 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 @@ -4,10 +4,12 @@ if sys.version_info < (2, 7): skip("lib_pypy._sqlite3 doesn't work with python < 2.7") +import pytest +from lib_pypy import _sqlite3 + def test_list_ddl(): """From issue996. Mostly just looking for lack of exceptions.""" - from lib_pypy._sqlite3 import connect - connection = connect(':memory:') + connection = _sqlite3.connect(':memory:') cursor = connection.cursor() cursor.execute('CREATE TABLE foo (bar INTEGER)') result = list(cursor) @@ -18,3 +20,63 @@ cursor.execute('SELECT * FROM foo') result = list(cursor) assert result == [(42,)] + +def test_total_changes_after_close(): + con = _sqlite3.connect(':memory:') + con.close() + pytest.raises(_sqlite3.ProgrammingError, "con.total_changes") + +def test_connection_check_init(): + class Connection(_sqlite3.Connection): + def __init__(self, name): + pass + + con = Connection(":memory:") + e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()") + assert '__init__' in e.value.message + +def test_cursor_check_init(): + class Cursor(_sqlite3.Cursor): + def __init__(self, name): + pass + + con = _sqlite3.connect(":memory:") + cur = Cursor(con) + e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')") + assert '__init__' in e.value.message + +def test_cursor_after_close(): + con = _sqlite3.connect(':memory:') + cur = con.execute('select 1') + cur.close() + con.close() + pytest.raises(_sqlite3.ProgrammingError, "cur.close()") + + at pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") +def test_cursor_del(): + con = _sqlite3.connect(':memory:') + cur = con.execute('select 1') + stmt = cur.statement + cur.close() + cur = con.execute('select 1') + assert cur.statement is stmt + del cur; import gc; gc.collect(); gc.collect() + cur = con.execute('select 1') + assert cur.statement is stmt + + at pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") +def test_connection_del(tmpdir): + """For issue1325.""" + import gc + + def open_many(cleanup): + con = [] + for i in range(1024): + con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) + if cleanup: + con[i] = None + gc.collect(); gc.collect() + + pytest.raises(_sqlite3.OperationalError, open_many, False) + gc.collect(); gc.collect() + open_many(True) From noreply at buildbot.pypy.org Tue Mar 5 05:15:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:03 +0100 (CET) Subject: [pypy-commit] pypy py3k: port some datetime changes from 72e79a8305c7 Message-ID: <20130305041503.B38821C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62047:a94c76ff11ca Date: 2013-03-04 22:30 -0500 http://bitbucket.org/pypy/pypy/changeset/a94c76ff11ca/ Log: port some datetime changes from 72e79a8305c7 diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -1028,13 +1028,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, bytes) and len(hour) == 6: # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1319,9 +1320,13 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + _check_date_fields(year, month, day) + _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) + self = object.__new__(cls) + self._year = year + self._month = month + self._day = day self._hour = hour self._minute = minute self._second = second From noreply at buildbot.pypy.org Tue Mar 5 05:15:05 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:05 +0100 (CET) Subject: [pypy-commit] pypy py3k: add a test for 768e6f96277d Message-ID: <20130305041505.03A0D1C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62048:79cd14e8279b Date: 2013-03-04 22:48 -0500 http://bitbucket.org/pypy/pypy/changeset/79cd14e8279b/ Log: add a test for 768e6f96277d diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -3676,6 +3676,18 @@ self.assertEqual(as_datetime, datetime_sc) self.assertEqual(datetime_sc, as_datetime) + def test_attributes(): + a = datetime.date.today() + with self.assertRaises(AttributeError): a.abc = 1 + a = datetime.time() + with self.assertRaises(AttributeError): a.abc = 1 + a = datetime.tzinfo() + with self.assertRaises(AttributeError): a.abc = 1 + a = datetime.datetime.utcnow() + with self.assertRaises(AttributeError): a.abc = 1 + a = datetime.timedelta() + with self.assertRaises(AttributeError): a.abc = 1 + def test_main(): support.run_unittest(__name__) From noreply at buildbot.pypy.org Tue Mar 5 05:15:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:06 +0100 (CET) Subject: [pypy-commit] pypy py3k: port datetime arg handling cleanups from 72e79a8305c7 and 43e61ecb2e40 Message-ID: <20130305041506.400E31C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62049:5956d289d64f Date: 2013-03-04 23:04 -0500 http://bitbucket.org/pypy/pypy/changeset/5956d289d64f/ Log: port datetime arg handling cleanups from 72e79a8305c7 and 43e61ecb2e40 diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -267,9 +267,23 @@ " -timedelta(hours=24) and timedelta(hours=24)" % (name, offset)) +def _check_int_field(value): + if isinstance(value, int): + return value + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, int): + return value + raise TypeError('an integer is required') + def _check_date_fields(year, month, day): - if not isinstance(year, int): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -277,10 +291,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - if not isinstance(hour, int): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -289,6 +306,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -674,7 +692,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -797,7 +815,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1033,8 +1051,8 @@ self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) self = object.__new__(cls) self._hour = hour self._minute = minute @@ -1263,7 +1281,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1320,8 +1338,8 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) self = object.__new__(cls) self._year = year @@ -1487,8 +1505,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -3688,6 +3688,50 @@ a = datetime.timedelta() with self.assertRaises(AttributeError): a.abc = 1 + def test_check_arg_types(): + import decimal + class Number: + def __init__(self, value): + self.value = value + def __int__(self): + return self.value + i10 = 10 + d10 = decimal.Decimal(10) + d11 = decimal.Decimal('10.9') + c10 = Number(10) + assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ + datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ + datetime.datetime(d11, d11, d11, d11, d11, d11, d11) == \ + datetime.datetime(c10, c10, c10, c10, c10, c10, c10) + + with self.assertRaises(TypeError): + datetime.datetime(10, 10, '10') + + f10 = Number(10.9) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, f10) + + class Float(float): + pass + s10 = Float(10.9) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, s10) + + with self.assertRaises(TypeError): + datetime.datetime(10., 10, 10) + with self.assertRaises(TypeError): + datetime.datetime(10, 10., 10) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, 10.) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, 10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime.datetime(10, 10, 10, 10, 10, 10, 10.) + def test_main(): support.run_unittest(__name__) From noreply at buildbot.pypy.org Tue Mar 5 05:15:07 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:07 +0100 (CET) Subject: [pypy-commit] pypy default: these are asserts upstream Message-ID: <20130305041507.794A71C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62050:ae243d6654b4 Date: 2013-03-04 23:09 -0500 http://bitbucket.org/pypy/pypy/changeset/ae243d6654b4/ Log: these are asserts upstream diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -61,17 +61,14 @@ def _days_before_month(year, month): "year, month -> number of days in year preceeding first day of month." - if not 1 <= month <= 12: - raise ValueError('month must be in 1..12', month) + assert 1 <= month <= 12, 'month must be in 1..12' return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year)) def _ymd2ord(year, month, day): "year, month, day -> ordinal, considering 01-Jan-0001 as day 1." - if not 1 <= month <= 12: - raise ValueError('month must be in 1..12', month) + assert 1 <= month <= 12, 'month must be in 1..12' dim = _days_in_month(year, month) - if not 1 <= day <= dim: - raise ValueError('day must be in 1..%d' % dim, day) + assert 1 <= day <= dim, ('day must be in 1..%d' % dim) return (_days_before_year(year) + _days_before_month(year, month) + day) From noreply at buildbot.pypy.org Tue Mar 5 05:15:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130305041508.99BB71C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62051:6b10ac90686d Date: 2013-03-04 23:14 -0500 http://bitbucket.org/pypy/pypy/changeset/6b10ac90686d/ Log: merge default From noreply at buildbot.pypy.org Tue Mar 5 05:15:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:15:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130305041509.D777A1C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62052:c0ea2f3113b3 Date: 2013-03-04 23:14 -0500 http://bitbucket.org/pypy/pypy/changeset/c0ea2f3113b3/ Log: merge heads diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -104,7 +104,8 @@ if endpos < pos: endpos = pos if space.is_true(space.isinstance(w_string, space.w_unicode)): unicodestr = space.unicode_w(w_string) - if not space.isinstance_w(self.w_pattern, space.w_unicode): + if not (space.is_none(self.w_pattern) or + space.isinstance_w(self.w_pattern, space.w_unicode)): raise OperationError(space.w_TypeError, space.wrap( "can't use a string pattern on a bytes-like object")) if pos > len(unicodestr): pos = len(unicodestr) @@ -113,7 +114,8 @@ pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) - if space.isinstance_w(self.w_pattern, space.w_unicode): + if (not space.is_none(self.w_pattern) and + space.isinstance_w(self.w_pattern, space.w_unicode)): raise OperationError(space.w_TypeError, space.wrap( "can't use a bytes pattern on a string-like object")) if pos > len(str): pos = len(str) @@ -292,6 +294,10 @@ w_srepat = space.allocate_instance(W_SRE_Pattern, w_subtype) srepat = space.interp_w(W_SRE_Pattern, w_srepat) srepat.space = space + # Type check + if not (space.is_none(w_pattern) or + space.isinstance_w(w_pattern, space.w_unicode)): + space.bufferstr_w(w_pattern) srepat.w_pattern = w_pattern # the original uncompiled pattern srepat.flags = flags srepat.code = code diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -93,6 +93,10 @@ import re, _weakref _weakref.ref(re.compile(r"")) + def test_pattern_check(self): + import _sre + raises(TypeError, _sre.compile, {}, 0, []) + class AppTestSreMatch: spaceconfig = dict(usemodules=('array',)) @@ -325,6 +329,12 @@ assert ("bla", "") == (p.search().group(0), p.search().group(0)) assert None == p.search() + def test_no_pattern(self): + import sre_compile, sre_parse + sre_pattern = sre_compile.compile( + sre_parse.SubPattern(sre_parse.Pattern())) + assert sre_pattern.scanner('s') is not None + class AppTestGetlower: spaceconfig = dict(usemodules=('_locale',)) From noreply at buildbot.pypy.org Tue Mar 5 05:26:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:26:45 +0100 (CET) Subject: [pypy-commit] pypy default: use resource.{get, set}rlimit to make this test work more generally Message-ID: <20130305042645.633301C034F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62053:0dadb5d6844b Date: 2013-03-04 23:26 -0500 http://bitbucket.org/pypy/pypy/changeset/0dadb5d6844b/ Log: use resource.{get,set}rlimit to make this test work more generally 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 @@ -68,15 +68,24 @@ def test_connection_del(tmpdir): """For issue1325.""" import gc + try: + import resource + except ImportError: + pytest.skip("needs resource module") - def open_many(cleanup): - con = [] - for i in range(1024): - con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) - if cleanup: - con[i] = None - gc.collect(); gc.collect() + limit = resource.getrlimit(resource.RLIMIT_NOFILE) + try: + resource.setrlimit(resource.RLIMIT_NOFILE, (min(10, limit[0]), limit[1])) + def open_many(cleanup): + con = [] + for i in range(20): + con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) + if cleanup: + con[i] = None + gc.collect(); gc.collect() - pytest.raises(_sqlite3.OperationalError, open_many, False) - gc.collect(); gc.collect() - open_many(True) + pytest.raises(_sqlite3.OperationalError, open_many, False) + gc.collect(); gc.collect() + open_many(True) + finally: + resource.setrlimit(resource.RLIMIT_NOFILE, limit) From noreply at buildbot.pypy.org Tue Mar 5 05:38:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 05:38:55 +0100 (CET) Subject: [pypy-commit] pypy default: spelling in error message Message-ID: <20130305043855.44BF91C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62054:ee108d35ae7f Date: 2013-03-04 23:38 -0500 http://bitbucket.org/pypy/pypy/changeset/ee108d35ae7f/ Log: spelling in error message diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -845,7 +845,7 @@ def __format__(self, fmt): if not isinstance(fmt, (str, unicode)): - raise ValueError("__format__ excepts str or unicode, not %s" % + raise ValueError("__format__ expects str or unicode, not %s" % fmt.__class__.__name__) if len(fmt) != 0: return self.strftime(fmt) @@ -1337,7 +1337,7 @@ def __format__(self, fmt): if not isinstance(fmt, (str, unicode)): - raise ValueError("__format__ excepts str or unicode, not %s" % + raise ValueError("__format__ expects str or unicode, not %s" % fmt.__class__.__name__) if len(fmt) != 0: return self.strftime(fmt) From noreply at buildbot.pypy.org Tue Mar 5 06:30:47 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 06:30:47 +0100 (CET) Subject: [pypy-commit] pypy default: reduce usage of non-standard datetime.tmxxx Message-ID: <20130305053047.BFFE41C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62055:d629bd7cbbf5 Date: 2013-03-04 23:45 -0500 http://bitbucket.org/pypy/pypy/changeset/d629bd7cbbf5/ Log: reduce usage of non-standard datetime.tmxxx diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -349,8 +349,6 @@ # second-guess timezones or DST. Instead fold whatever adjustments you want # into the minutes argument (and the constructor will normalize). -_ORD1970 = _ymd2ord(1970, 1, 1) # base ordinal for UNIX epoch - class tmxxx: ordinal = None @@ -412,32 +410,6 @@ self.hour, self.minute, self.second = hour, minute, second self.microsecond = microsecond - def toordinal(self): - """Return proleptic Gregorian ordinal for the year, month and day. - - January 1 of year 1 is day 1. Only the year, month and day values - contribute to the result. - """ - if self.ordinal is None: - self.ordinal = _ymd2ord(self.year, self.month, self.day) - return self.ordinal - - def time(self): - "Return Unixish timestamp, as a float (assuming UTC)." - days = self.toordinal() - _ORD1970 # convert to UNIX epoch - seconds = ((days * 24. + self.hour)*60. + self.minute)*60. - return seconds + self.second + self.microsecond / 1e6 - - def ctime(self): - "Return ctime() style string." - weekday = self.toordinal() % 7 or 7 - return "%s %s %2d %02d:%02d:%02d %04d" % ( - _DAYNAMES[weekday], - _MONTHNAMES[self.month], - self.day, - self.hour, self.minute, self.second, - self.year) - class timedelta(object): """Represent the difference between two datetime objects. @@ -458,7 +430,6 @@ __slots__ = '_days', '_seconds', '_microseconds' def __new__(cls, days=0, seconds=0, microseconds=0, - # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): # Doing this efficiently and accurately in C is going to be difficult # and error-prone, due to ubiquitous overflow possibilities, and that @@ -835,9 +806,14 @@ # easily done without using strftime() -- that's better too because # strftime("%c", ...) is locale specific. + def ctime(self): "Return ctime() style string." - return tmxxx(self._year, self._month, self._day).ctime() + weekday = self.toordinal() % 7 or 7 + return "%s %s %2d 00:00:00 %04d" % ( + _DAYNAMES[weekday], + _MONTHNAMES[self._month], + self._day, self._year) def strftime(self, fmt): "Format using strftime()." @@ -1126,7 +1102,7 @@ else: return (self.__class__, args, state) -_tzinfo_class = tzinfo # so functions w/ args named "tzinfo" can get at the class +_tzinfo_class = tzinfo class time(object): """Time with time zone. @@ -1657,9 +1633,13 @@ def ctime(self): "Return ctime() style string." - t = tmxxx(self._year, self._month, self._day, self._hour, - self._minute, self._second) - return t.ctime() + weekday = self.toordinal() % 7 or 7 + return "%s %s %2d %02d:%02d:%02d %04d" % ( + _DAYNAMES[weekday], + _MONTHNAMES[self._month], + self._day, + self._hour, self._minute, self._second, + self._year) def isoformat(self, sep='T'): """Return the time formatted according to ISO. From noreply at buildbot.pypy.org Tue Mar 5 06:31:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 06:31:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130305053151.46D431C0512@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62056:668230184059 Date: 2013-03-05 00:31 -0500 http://bitbucket.org/pypy/pypy/changeset/668230184059/ Log: merge default 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 @@ -68,15 +68,24 @@ def test_connection_del(tmpdir): """For issue1325.""" import gc + try: + import resource + except ImportError: + pytest.skip("needs resource module") - def open_many(cleanup): - con = [] - for i in range(1024): - con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) - if cleanup: - con[i] = None - gc.collect(); gc.collect() + limit = resource.getrlimit(resource.RLIMIT_NOFILE) + try: + resource.setrlimit(resource.RLIMIT_NOFILE, (min(10, limit[0]), limit[1])) + def open_many(cleanup): + con = [] + for i in range(20): + con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) + if cleanup: + con[i] = None + gc.collect(); gc.collect() - pytest.raises(_sqlite3.OperationalError, open_many, False) - gc.collect(); gc.collect() - open_many(True) + pytest.raises(_sqlite3.OperationalError, open_many, False) + gc.collect(); gc.collect() + open_many(True) + finally: + resource.setrlimit(resource.RLIMIT_NOFILE, limit) From noreply at buildbot.pypy.org Tue Mar 5 06:40:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 06:40:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: typos Message-ID: <20130305054034.110DB1C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62057:3cf5ccae78bf Date: 2013-03-05 00:40 -0500 http://bitbucket.org/pypy/pypy/changeset/3cf5ccae78bf/ Log: typos diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -3676,7 +3676,7 @@ self.assertEqual(as_datetime, datetime_sc) self.assertEqual(datetime_sc, as_datetime) - def test_attributes(): + def test_attributes(self): a = datetime.date.today() with self.assertRaises(AttributeError): a.abc = 1 a = datetime.time() @@ -3688,7 +3688,7 @@ a = datetime.timedelta() with self.assertRaises(AttributeError): a.abc = 1 - def test_check_arg_types(): + def test_check_arg_types(self): import decimal class Number: def __init__(self, value): From noreply at buildbot.pypy.org Tue Mar 5 07:51:22 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 07:51:22 +0100 (CET) Subject: [pypy-commit] pypy py3k: sneakier Message-ID: <20130305065122.51DC91C104B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62058:022c349efb36 Date: 2013-03-04 21:52 -0800 http://bitbucket.org/pypy/pypy/changeset/022c349efb36/ Log: sneakier diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -485,6 +485,7 @@ def exec_(src, dic): exec(src, dic) + at hidden_applevel def run_command_line(interactive, inspect, run_command, @@ -713,6 +714,7 @@ # This is important for py3k sys.executable = executable + at hidden_applevel def entry_point(executable, argv): # note that before calling setup_bootstrap_path, we are limited because we # cannot import stdlib modules. In particular, we cannot use unicode From noreply at buildbot.pypy.org Tue Mar 5 07:51:23 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 07:51:23 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix 73738029fbf6 Message-ID: <20130305065123.8646A1C104B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62059:cf8585694389 Date: 2013-03-04 22:49 -0800 http://bitbucket.org/pypy/pypy/changeset/cf8585694389/ Log: fix 73738029fbf6 diff --git a/lib-python/3/test/string_tests.py b/lib-python/3/test/string_tests.py --- a/lib-python/3/test/string_tests.py +++ b/lib-python/3/test/string_tests.py @@ -1060,7 +1060,7 @@ self.checkequal('abc', 'abc', '__mul__', 1) self.checkequal('abcabcabc', 'abc', '__mul__', 3) self.checkraises(TypeError, 'abc', '__mul__') - self.checkraises(TypeError, operator.mul, 'abc', '') + self.assertRaises(TypeError, operator.mul, 'abc', '') # XXX: on a 64-bit system, this doesn't raise an overflow error, # but either raises a MemoryError, or succeeds (if you have 54TiB) #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) From noreply at buildbot.pypy.org Tue Mar 5 07:59:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 07:59:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: improve test for timedelta microsecond rounding Message-ID: <20130305065933.2E12B1C104B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62060:ee1134152f8a Date: 2013-03-05 01:29 -0500 http://bitbucket.org/pypy/pypy/changeset/ee1134152f8a/ Log: improve test for timedelta microsecond rounding diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -603,6 +603,8 @@ # Single-field rounding. eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0 eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0 + eq(td(milliseconds=0.5/1000), td(microseconds=1)) + eq(td(milliseconds=-0.5/1000), td(microseconds=-1)) eq(td(milliseconds=0.6/1000), td(microseconds=1)) eq(td(milliseconds=-0.6/1000), td(microseconds=-1)) From noreply at buildbot.pypy.org Tue Mar 5 07:59:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 07:59:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix datetime after rounding optimizations Message-ID: <20130305065934.85F351C104B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62061:8d6f0f4e168b Date: 2013-03-05 01:41 -0500 http://bitbucket.org/pypy/pypy/changeset/8d6f0f4e168b/ Log: fix datetime after rounding optimizations diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -568,10 +568,10 @@ if isinstance(other, timedelta): return usec / other._to_microseconds() if isinstance(other, int): - return timedelta(0, 0, usec / other) + return timedelta(0, 0, round(usec / other)) if isinstance(other, float): a, b = other.as_integer_ratio() - return timedelta(0, 0, b * usec / a) + return timedelta(0, 0, round(b * usec / a)) def __mod__(self, other): if isinstance(other, timedelta): From noreply at buildbot.pypy.org Tue Mar 5 07:59:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 07:59:35 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130305065935.C569E1C104B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62062:b9b453ec29c9 Date: 2013-03-05 01:59 -0500 http://bitbucket.org/pypy/pypy/changeset/b9b453ec29c9/ Log: merge heads diff --git a/lib-python/3/test/string_tests.py b/lib-python/3/test/string_tests.py --- a/lib-python/3/test/string_tests.py +++ b/lib-python/3/test/string_tests.py @@ -1060,7 +1060,7 @@ self.checkequal('abc', 'abc', '__mul__', 1) self.checkequal('abcabcabc', 'abc', '__mul__', 3) self.checkraises(TypeError, 'abc', '__mul__') - self.checkraises(TypeError, operator.mul, 'abc', '') + self.assertRaises(TypeError, operator.mul, 'abc', '') # XXX: on a 64-bit system, this doesn't raise an overflow error, # but either raises a MemoryError, or succeeds (if you have 54TiB) #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -485,6 +485,7 @@ def exec_(src, dic): exec(src, dic) + at hidden_applevel def run_command_line(interactive, inspect, run_command, @@ -713,6 +714,7 @@ # This is important for py3k sys.executable = executable + at hidden_applevel def entry_point(executable, argv): # note that before calling setup_bootstrap_path, we are limited because we # cannot import stdlib modules. In particular, we cannot use unicode From noreply at buildbot.pypy.org Tue Mar 5 08:19:07 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 08:19:07 +0100 (CET) Subject: [pypy-commit] pypy py3k: another datetime microsecond rounding test that was failing before Message-ID: <20130305071907.7F73A1C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62063:f8a41f7f92f9 Date: 2013-03-05 02:18 -0500 http://bitbucket.org/pypy/pypy/changeset/f8a41f7f92f9/ Log: another datetime microsecond rounding test that was failing before diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -1738,6 +1738,8 @@ self.theclass.utcfromtimestamp]: self.assertEqual(fts(0.9999999), fts(1)) self.assertEqual(fts(0.99999949).microsecond, 999999) + self.assertEqual(fts(0.0000005).microsecond, 1) + self.assertEqual(fts(0.0000015).microsecond, 2) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, From noreply at buildbot.pypy.org Tue Mar 5 09:29:08 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 09:29:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: backout 022c349efb36 Message-ID: <20130305082908.470891C1028@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62064:6d98509bfcd1 Date: 2013-03-05 00:28 -0800 http://bitbucket.org/pypy/pypy/changeset/6d98509bfcd1/ Log: backout 022c349efb36 diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -485,7 +485,6 @@ def exec_(src, dic): exec(src, dic) - at hidden_applevel def run_command_line(interactive, inspect, run_command, @@ -714,7 +713,6 @@ # This is important for py3k sys.executable = executable - at hidden_applevel def entry_point(executable, argv): # note that before calling setup_bootstrap_path, we are limited because we # cannot import stdlib modules. In particular, we cannot use unicode From noreply at buildbot.pypy.org Tue Mar 5 09:34:07 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 09:34:07 +0100 (CET) Subject: [pypy-commit] pypy default: more fixes for this test Message-ID: <20130305083407.D92191C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62065:c2c7a22badee Date: 2013-03-05 03:33 -0500 http://bitbucket.org/pypy/pypy/changeset/c2c7a22badee/ Log: more fixes for this test 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 @@ -67,6 +67,7 @@ @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): """For issue1325.""" + import os import gc try: import resource @@ -75,10 +76,19 @@ limit = resource.getrlimit(resource.RLIMIT_NOFILE) try: - resource.setrlimit(resource.RLIMIT_NOFILE, (min(10, limit[0]), limit[1])) + fds = 0 + while True: + fds += 1 + resource.setrlimit(resource.RLIMIT_NOFILE, (fds, limit[1])) + try: + for p in os.pipe(): os.close(p) + except OSError: + assert fds < 100 + else: + break def open_many(cleanup): con = [] - for i in range(20): + for i in range(3): con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) if cleanup: con[i] = None From noreply at buildbot.pypy.org Tue Mar 5 10:20:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 10:20:16 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix datetime tests Message-ID: <20130305092016.64F8A1C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62066:cca91938bae1 Date: 2013-03-05 04:19 -0500 http://bitbucket.org/pypy/pypy/changeset/cca91938bae1/ Log: fix datetime tests diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -3681,15 +3681,17 @@ self.assertEqual(datetime_sc, as_datetime) def test_attributes(self): - a = datetime.date.today() + a = date.today() with self.assertRaises(AttributeError): a.abc = 1 - a = datetime.time() + a = time() with self.assertRaises(AttributeError): a.abc = 1 - a = datetime.tzinfo() + a = tzinfo() with self.assertRaises(AttributeError): a.abc = 1 - a = datetime.datetime.utcnow() + a = datetime.utcnow() with self.assertRaises(AttributeError): a.abc = 1 - a = datetime.timedelta() + a = timedelta() + with self.assertRaises(AttributeError): a.abc = 1 + a = timezone(timedelta()) with self.assertRaises(AttributeError): a.abc = 1 def test_check_arg_types(self): @@ -3703,38 +3705,38 @@ d10 = decimal.Decimal(10) d11 = decimal.Decimal('10.9') c10 = Number(10) - assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ - datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ - datetime.datetime(d11, d11, d11, d11, d11, d11, d11) == \ - datetime.datetime(c10, c10, c10, c10, c10, c10, c10) + assert datetime(i10, i10, i10, i10, i10, i10, i10) == \ + datetime(d10, d10, d10, d10, d10, d10, d10) == \ + datetime(d11, d11, d11, d11, d11, d11, d11) == \ + datetime(c10, c10, c10, c10, c10, c10, c10) with self.assertRaises(TypeError): - datetime.datetime(10, 10, '10') + datetime(10, 10, '10') f10 = Number(10.9) with self.assertRaises(TypeError): - datetime.datetime(10, 10, f10) + datetime(10, 10, f10) class Float(float): pass s10 = Float(10.9) with self.assertRaises(TypeError): - datetime.datetime(10, 10, s10) + datetime(10, 10, s10) with self.assertRaises(TypeError): - datetime.datetime(10., 10, 10) + datetime(10., 10, 10) with self.assertRaises(TypeError): - datetime.datetime(10, 10., 10) + datetime(10, 10., 10) with self.assertRaises(TypeError): - datetime.datetime(10, 10, 10.) + datetime(10, 10, 10.) with self.assertRaises(TypeError): - datetime.datetime(10, 10, 10, 10.) + datetime(10, 10, 10, 10.) with self.assertRaises(TypeError): - datetime.datetime(10, 10, 10, 10, 10.) + datetime(10, 10, 10, 10, 10.) with self.assertRaises(TypeError): - datetime.datetime(10, 10, 10, 10, 10, 10.) + datetime(10, 10, 10, 10, 10, 10.) with self.assertRaises(TypeError): - datetime.datetime(10, 10, 10, 10, 10, 10, 10.) + datetime(10, 10, 10, 10, 10, 10, 10.) def test_main(): support.run_unittest(__name__) From noreply at buildbot.pypy.org Tue Mar 5 12:35:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 12:35:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: improve datetime error messages, test Message-ID: <20130305113557.1E21C1C105B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62067:2171355e07eb Date: 2013-03-05 06:24 -0500 http://bitbucket.org/pypy/pypy/changeset/2171355e07eb/ Log: improve datetime error messages, test diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -278,7 +278,9 @@ else: if isinstance(value, int): return value - raise TypeError('an integer is required') + raise TypeError('nb_int should return int object') + raise TypeError('an integer is required') + raise TypeError('integer argument expected, got float') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -740,12 +742,12 @@ self._year, self._month, self._day) + # XXX These shouldn't depend on time.localtime(), because that # clips the usable dates to [1970 .. 2038). At least ctime() is # easily done without using strftime() -- that's better too because # strftime("%c", ...) is locale specific. - def ctime(self): "Return ctime() style string." weekday = self.toordinal() % 7 or 7 diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -3680,19 +3680,11 @@ self.assertEqual(as_datetime, datetime_sc) self.assertEqual(datetime_sc, as_datetime) - def test_attributes(self): - a = date.today() - with self.assertRaises(AttributeError): a.abc = 1 - a = time() - with self.assertRaises(AttributeError): a.abc = 1 - a = tzinfo() - with self.assertRaises(AttributeError): a.abc = 1 - a = datetime.utcnow() - with self.assertRaises(AttributeError): a.abc = 1 - a = timedelta() - with self.assertRaises(AttributeError): a.abc = 1 - a = timezone(timedelta()) - with self.assertRaises(AttributeError): a.abc = 1 + def test_extra_attributes(self): + for x in [date.today(), time(), datetime.utcnow(), timedelta(), + tzinfo(), timezone(timedelta())]: + with self.assertRaises(AttributeError): + x.abc = 1 def test_check_arg_types(self): import decimal @@ -3701,26 +3693,22 @@ self.value = value def __int__(self): return self.value - i10 = 10 - d10 = decimal.Decimal(10) - d11 = decimal.Decimal('10.9') - c10 = Number(10) - assert datetime(i10, i10, i10, i10, i10, i10, i10) == \ - datetime(d10, d10, d10, d10, d10, d10, d10) == \ - datetime(d11, d11, d11, d11, d11, d11, d11) == \ - datetime(c10, c10, c10, c10, c10, c10, c10) - - with self.assertRaises(TypeError): + + for xx in [decimal.Decimal(10), decimal.Decimal('10.9'), Number(10)]: + self.assertEqual(datetime(10, 10, 10, 10, 10, 10, 10), + datetime(xx, xx, xx, xx, xx, xx, xx)) + + with self.assertRaisesRegex(TypeError, '^an integer is required$'): datetime(10, 10, '10') f10 = Number(10.9) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, '^nb_int should return int object$'): datetime(10, 10, f10) class Float(float): pass s10 = Float(10.9) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, '^integer argument expected, got float$'): datetime(10, 10, s10) with self.assertRaises(TypeError): From noreply at buildbot.pypy.org Tue Mar 5 12:44:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 12:44:55 +0100 (CET) Subject: [pypy-commit] pypy default: port improved datetime error messages and tests in 2171355e07eb Message-ID: <20130305114456.0075C1C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62068:e9dd39c354da Date: 2013-03-05 06:44 -0500 http://bitbucket.org/pypy/pypy/changeset/e9dd39c354da/ Log: port improved datetime error messages and tests in 2171355e07eb diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -278,7 +278,9 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('an integer is required') + raise TypeError('__int__ method should return an integer') + raise TypeError('an integer is required') + raise TypeError('integer argument expected, got float') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -801,12 +803,12 @@ self._year, self._month, self._day) + # XXX These shouldn't depend on time.localtime(), because that # clips the usable dates to [1970 .. 2038). At least ctime() is # easily done without using strftime() -- that's better too because # strftime("%c", ...) is locale specific. - def ctime(self): "Return ctime() style string." weekday = self.toordinal() % 7 or 7 diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -10,16 +10,12 @@ assert repr(datetime.datetime(1,2,3)) == expected def test_attributes(): - a = datetime.date.today() - raises(AttributeError, 'a.abc = 1') - a = datetime.time() - raises(AttributeError, 'a.abc = 1') - a = datetime.tzinfo() - raises(AttributeError, 'a.abc = 1') - a = datetime.datetime.utcnow() - raises(AttributeError, 'a.abc = 1') - a = datetime.timedelta() - raises(AttributeError, 'a.abc = 1') + for x in [datetime.date.today(), + datetime.time(), + datetime.datetime.utcnow(), + datetime.timedelta(), + datetime.tzinfo()]: + raises(AttributeError, 'x.abc = 1') def test_unpickle(): e = raises(TypeError, datetime.date, '123') @@ -124,31 +120,27 @@ self.value = value def __int__(self): return self.value - i10 = 10 - l10 = 10L - d10 = decimal.Decimal(10) - d11 = decimal.Decimal('10.9') - c10 = Number(10) - o10 = Number(10L) - assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ - datetime.datetime(l10, l10, l10, l10, l10, l10, l10) == \ - datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ - datetime.datetime(d11, d11, d11, d11, d11, d11, d11) == \ - datetime.datetime(c10, c10, c10, c10, c10, c10, c10) == \ - datetime.datetime(o10, o10, o10, o10, o10, o10, o10) - with py.test.raises(TypeError): + for xx in [10L, decimal.Decimal(10), decimal.Decimal('10.9'), + Number(10), Number(10L)]: + assert datetime.datetime(10, 10, 10, 10, 10, 10, 10) == \ + datetime.datetime(xx, xx, xx, xx, xx, xx, xx) + + with py.test.raises(TypeError) as e: datetime.datetime(10, 10, '10') + assert str(e.value) == 'an integer is required' f10 = Number(10.9) - with py.test.raises(TypeError): + with py.test.raises(TypeError) as e: datetime.datetime(10, 10, f10) + assert str(e.value) == '__int__ method should return an integer' class Float(float): pass s10 = Float(10.9) - with py.test.raises(TypeError): + with py.test.raises(TypeError) as e: datetime.datetime(10, 10, s10) + assert str(e.value) == 'integer argument expected, got float' with py.test.raises(TypeError): datetime.datetime(10., 10, 10) From noreply at buildbot.pypy.org Tue Mar 5 12:48:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 12:48:22 +0100 (CET) Subject: [pypy-commit] pypy py3k: spacing for readability Message-ID: <20130305114822.A5DC91C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62069:4ed015cbc18d Date: 2013-03-05 06:48 -0500 http://bitbucket.org/pypy/pypy/changeset/4ed015cbc18d/ Log: spacing for readability diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -3681,8 +3681,12 @@ self.assertEqual(datetime_sc, as_datetime) def test_extra_attributes(self): - for x in [date.today(), time(), datetime.utcnow(), timedelta(), - tzinfo(), timezone(timedelta())]: + for x in [date.today(), + time(), + datetime.utcnow(), + timedelta(), + tzinfo(), + timezone(timedelta())]: with self.assertRaises(AttributeError): x.abc = 1 @@ -3694,7 +3698,9 @@ def __int__(self): return self.value - for xx in [decimal.Decimal(10), decimal.Decimal('10.9'), Number(10)]: + for xx in [decimal.Decimal(10), + decimal.Decimal('10.9'), + Number(10)]: self.assertEqual(datetime(10, 10, 10, 10, 10, 10, 10), datetime(xx, xx, xx, xx, xx, xx, xx)) From noreply at buildbot.pypy.org Tue Mar 5 12:48:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 12:48:49 +0100 (CET) Subject: [pypy-commit] pypy default: spacing for readability Message-ID: <20130305114849.1476C1C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62070:366bed7a8e6e Date: 2013-03-05 06:47 -0500 http://bitbucket.org/pypy/pypy/changeset/366bed7a8e6e/ Log: spacing for readability diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -121,8 +121,11 @@ def __int__(self): return self.value - for xx in [10L, decimal.Decimal(10), decimal.Decimal('10.9'), - Number(10), Number(10L)]: + for xx in [10L, + decimal.Decimal(10), + decimal.Decimal('10.9'), + Number(10), + Number(10L)]: assert datetime.datetime(10, 10, 10, 10, 10, 10, 10) == \ datetime.datetime(xx, xx, xx, xx, xx, xx, xx) From noreply at buildbot.pypy.org Tue Mar 5 13:49:29 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 13:49:29 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Move RPython-relevant parts out of getting-started-dev. Message-ID: <20130305124929.89AB81C1017@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62071:7b4be8b19f32 Date: 2013-03-05 13:34 +0100 http://bitbucket.org/pypy/pypy/changeset/7b4be8b19f32/ Log: Move RPython-relevant parts out of getting-started-dev. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -1,148 +1,10 @@ -=============================================================================== -Getting Started with the Translation Toolchain and Development Process -=============================================================================== +=============================================== +Getting Started with PyPy's Development Process +=============================================== .. contents:: -.. _`try out the translator`: - -Trying out the translator -------------------------- - -The translator is a tool based on the PyPy interpreter which can translate -sufficiently static RPython programs into low-level code (in particular it can -be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: - - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ - -To start the interactive translator shell do:: - - cd rpython - python bin/translatorshell.py - -Test snippets of translatable code are provided in the file -``rpython/translator/test/snippet.py``, which is imported under the name -``snippet``. For example:: - - >>> t = Translation(snippet.is_perfect_number, [int]) - >>> t.view() - -After that, the graph viewer pops up, that lets you interactively inspect the -flow graph. To move around, click on something that you want to inspect. -To get help about how to use it, press 'H'. To close it again, press 'Q'. - -Trying out the type annotator -+++++++++++++++++++++++++++++ - -We have a type annotator that can completely infer types for functions like -``is_perfect_number`` (as well as for much larger examples):: - - >>> t.annotate() - >>> t.view() - -Move the mouse over variable names (in red) to see their inferred types. - - -Translating the flow graph to C code -++++++++++++++++++++++++++++++++++++ - -The graph can be turned into C code:: - - >>> t.rtype() - >>> lib = t.compile_c() - -The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). The compiled -version is now in a ``.so`` library. You can run it say using ctypes: - - >>> f = get_c_function(lib, snippet.is_perfect_number) - >>> f(5) - 0 - >>> f(6) - 1 - -Translating the flow graph to CLI or JVM code -+++++++++++++++++++++++++++++++++++++++++++++ - -PyPy also contains a `CLI backend`_ and JVM backend which -can translate flow graphs into .NET executables or a JVM jar -file respectively. Both are able to translate the entire -interpreter. You can try out the CLI and JVM backends -from the interactive translator shells as follows:: - - >>> def myfunc(a, b): return a+b - ... - >>> t = Translation(myfunc, [int, int]) - >>> t.annotate() - >>> f = t.compile_cli() # or compile_jvm() - >>> f(4, 5) - 9 - -The object returned by ``compile_cli`` or ``compile_jvm`` -is a wrapper around the real -executable: the parameters are passed as command line arguments, and -the returned value is read from the standard output. - -Once you have compiled the snippet, you can also try to launch the -executable directly from the shell. You will find the -executable in one of the ``/tmp/usession-*`` directories:: - - # For CLI: - $ mono /tmp/usession-trunk-/main.exe 4 5 - 9 - - # For JVM: - $ java -cp /tmp/usession-trunk-/pypy pypy.Main 4 5 - 9 - -To translate and run for the CLI you must have the SDK installed: Windows -users need the `.NET Framework SDK`_, while Linux and Mac users -can use Mono_. To translate and run for the JVM you must have a JDK -installed (at least version 6) and ``java``/``javac`` on your path. - -A slightly larger example -+++++++++++++++++++++++++ - -There is a small-to-medium demo showing the translator and the annotator:: - - cd demo - ../rpython/translator/goal/translate.py --view --annotate bpnn.py - -This causes ``bpnn.py`` to display itself as a call graph and class -hierarchy. Clicking on functions shows the flow graph of the particular -function. Clicking on a class shows the attributes of its instances. All -this information (call graph, local variables' types, attributes of -instances) is computed by the annotator. - -To turn this example to C code (compiled to the executable ``bpnn-c``), -type simply:: - - ../rpython/translator/goal/translate.py bpnn.py - - -Translating Full Programs -+++++++++++++++++++++++++ - -To translate full RPython programs, there is the script ``translate.py`` in -``rpython/translator/goal``. Examples for this are a slightly changed version of -Pystone:: - - cd rpython/translator/goal - python translate.py targetrpystonedalone - -This will produce the executable "targetrpystonedalone-c". - -The largest example of this process is to translate the `full Python -interpreter`_. There is also an FAQ about how to set up this process for `your -own interpreters`_. - -.. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters - .. _`start reading sources`: - Where to start reading the sources ---------------------------------- @@ -172,27 +34,6 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `rpython/translator`_ contains the code analysis and generation stuff. - Start reading from translator.py, from which it should be easy to follow - the pieces of code involved in the various translation phases. - -* `rpython/annotator`_ contains the data model for the type annotation that - can be inferred about a graph. The graph "walker" that uses this is in - `rpython/annotator/annrpython.py`_. - -* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms - annotated flow graphs in a way that makes them very similar to C code so - that they can be easy translated. The graph transformations are controlled - by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can - be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type - there is a file rxxxx.py that contains the low level functions needed for - this type. - -* `rpython/rlib`_ contains the `RPython standard library`_, things that you can - use from rpython. - -.. _`RPython standard library`: rlib.html - .. _optionaltool: diff --git a/rpython/doc/getting-started.rst b/rpython/doc/getting-started.rst new file mode 100644 --- /dev/null +++ b/rpython/doc/getting-started.rst @@ -0,0 +1,165 @@ +============================================== +Getting Started with the Translation Toolchain +============================================== + +.. contents:: + +.. _`try out the translator`: +Trying out the translator +------------------------- + +The translator is a tool based on the PyPy interpreter which can translate +sufficiently static RPython programs into low-level code (in particular it can +be used to translate the `full Python interpreter`_). To be able to experiment with it +you need to: + + * Download and install Pygame_. + + * Download and install `Dot Graphviz`_ + +To start the interactive translator shell do:: + + cd rpython + python bin/translatorshell.py + +Test snippets of translatable code are provided in the file +``rpython/translator/test/snippet.py``, which is imported under the name +``snippet``. For example:: + + >>> t = Translation(snippet.is_perfect_number, [int]) + >>> t.view() + +After that, the graph viewer pops up, that lets you interactively inspect the +flow graph. To move around, click on something that you want to inspect. +To get help about how to use it, press 'H'. To close it again, press 'Q'. + +Trying out the type annotator ++++++++++++++++++++++++++++++ + +We have a type annotator that can completely infer types for functions like +``is_perfect_number`` (as well as for much larger examples):: + + >>> t.annotate() + >>> t.view() + +Move the mouse over variable names (in red) to see their inferred types. + + +Translating the flow graph to C code +++++++++++++++++++++++++++++++++++++ + +The graph can be turned into C code:: + + >>> t.rtype() + >>> lib = t.compile_c() + +The first command replaces the operations with other low level versions that +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + + >>> f = get_c_function(lib, snippet.is_perfect_number) + >>> f(5) + 0 + >>> f(6) + 1 + +Translating the flow graph to CLI or JVM code ++++++++++++++++++++++++++++++++++++++++++++++ + +PyPy also contains a `CLI backend`_ and JVM backend which +can translate flow graphs into .NET executables or a JVM jar +file respectively. Both are able to translate the entire +interpreter. You can try out the CLI and JVM backends +from the interactive translator shells as follows:: + + >>> def myfunc(a, b): return a+b + ... + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() + >>> f = t.compile_cli() # or compile_jvm() + >>> f(4, 5) + 9 + +The object returned by ``compile_cli`` or ``compile_jvm`` +is a wrapper around the real +executable: the parameters are passed as command line arguments, and +the returned value is read from the standard output. + +Once you have compiled the snippet, you can also try to launch the +executable directly from the shell. You will find the +executable in one of the ``/tmp/usession-*`` directories:: + + # For CLI: + $ mono /tmp/usession-trunk-/main.exe 4 5 + 9 + + # For JVM: + $ java -cp /tmp/usession-trunk-/pypy pypy.Main 4 5 + 9 + +To translate and run for the CLI you must have the SDK installed: Windows +users need the `.NET Framework SDK`_, while Linux and Mac users +can use Mono_. To translate and run for the JVM you must have a JDK +installed (at least version 6) and ``java``/``javac`` on your path. + +A slightly larger example ++++++++++++++++++++++++++ + +There is a small-to-medium demo showing the translator and the annotator:: + + cd demo + ../rpython/translator/goal/translate.py --view --annotate bpnn.py + +This causes ``bpnn.py`` to display itself as a call graph and class +hierarchy. Clicking on functions shows the flow graph of the particular +function. Clicking on a class shows the attributes of its instances. All +this information (call graph, local variables' types, attributes of +instances) is computed by the annotator. + +To turn this example to C code (compiled to the executable ``bpnn-c``), +type simply:: + + ../rpython/translator/goal/translate.py bpnn.py + + +Translating Full Programs ++++++++++++++++++++++++++ + +To translate full RPython programs, there is the script ``translate.py`` in +``rpython/translator/goal``. Examples for this are a slightly changed version of +Pystone:: + + cd rpython/translator/goal + python translate.py targetrpystonedalone + +This will produce the executable "targetrpystonedalone-c". + +The largest example of this process is to translate the `full Python +interpreter`_. There is also an FAQ about how to set up this process for `your +own interpreters`_. + +.. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters + +Sources +------- + +* `rpython/translator`_ contains the code analysis and generation stuff. + Start reading from translator.py, from which it should be easy to follow + the pieces of code involved in the various translation phases. + +* `rpython/annotator`_ contains the data model for the type annotation that + can be inferred about a graph. The graph "walker" that uses this is in + `rpython/annotator/annrpython.py`_. + +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms + annotated flow graphs in a way that makes them very similar to C code so + that they can be easy translated. The graph transformations are controlled + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type + there is a file rxxxx.py that contains the low level functions needed for + this type. + +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can + use from rpython. + +.. _`RPython standard library`: rlib.html From noreply at buildbot.pypy.org Tue Mar 5 14:51:27 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:27 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Add some entries to the content toctree. Message-ID: <20130305135127.950AB1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62072:89a9efa7f316 Date: 2013-03-05 13:58 +0100 http://bitbucket.org/pypy/pypy/changeset/89a9efa7f316/ Log: Add some entries to the content toctree. diff --git a/rpython/doc/index.rst b/rpython/doc/index.rst --- a/rpython/doc/index.rst +++ b/rpython/doc/index.rst @@ -1,8 +1,3 @@ -.. RPython documentation master file, created by - sphinx-quickstart on Sat Feb 23 12:41:19 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - Welcome to RPython's documentation! =================================== @@ -10,7 +5,17 @@ .. toctree:: :maxdepth: 2 - + + getting-started + faq + rpython + rlib + rffi + translation + rtyper + garbage_collection + cli-backend + windows Indices and tables From noreply at buildbot.pypy.org Tue Mar 5 14:51:28 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:28 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Move FAQ entries one level up. Message-ID: <20130305135128.EA74B1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62073:75b5fc1870b8 Date: 2013-03-05 13:59 +0100 http://bitbucket.org/pypy/pypy/changeset/75b5fc1870b8/ Log: Move FAQ entries one level up. diff --git a/rpython/doc/faq.rst b/rpython/doc/faq.rst --- a/rpython/doc/faq.rst +++ b/rpython/doc/faq.rst @@ -4,10 +4,6 @@ .. contents:: - -The RPython translation tool chain -================================== - ------------------------------------------------ Can RPython compile normal Python programs to C? ------------------------------------------------ From noreply at buildbot.pypy.org Tue Mar 5 14:51:30 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:30 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Don't show these headings as bold. Message-ID: <20130305135130.31AB91C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62074:851c2c4a0c8d Date: 2013-03-05 14:04 +0100 http://bitbucket.org/pypy/pypy/changeset/851c2c4a0c8d/ Log: Don't show these headings as bold. diff --git a/rpython/doc/rlib.rst b/rpython/doc/rlib.rst --- a/rpython/doc/rlib.rst +++ b/rpython/doc/rlib.rst @@ -15,8 +15,8 @@ :source:`rpython/rlib/test` to get an impression of how to use a module. -``listsort`` -============ +listsort +======== The :source:`rpython/rlib/listsort.py` module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the @@ -27,8 +27,8 @@ be sorted using the ``listsort`` module in one program, otherwise the annotator will be confused. -``nonconst`` -============ +nonconst +======== The :source:`rpython/rlib/nonconst.py` module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired @@ -41,8 +41,8 @@ .. _`annotator`: translation.html#the-annotation-pass -``objectmodel`` -=============== +objectmodel +=========== The :source:`rpython/rlib/objectmodel.py` module is a mixed bag of various functionality. Some of the more useful ones are: @@ -91,8 +91,8 @@ that have the lowest bit set. -``rarithmetic`` -=============== +rarithmetic +=========== The :source:`rpython/rlib/rarithmetic.py` module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of @@ -101,8 +101,8 @@ .. _`coding guide`: coding-guide.html -``rbigint`` -=========== +rbigint +======= The :source:`rpython/rlib/rbigint.py` module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains @@ -115,16 +115,16 @@ to add two rbigint instances). -``rrandom`` -=========== +rrandom +======= The :source:`rpython/rlib/rrandom.py` module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. -``rsocket`` -=========== +rsocket +======= The :source:`rpython/rlib/rsocket.py` module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The @@ -134,8 +134,8 @@ a hierarchy of Address classes, in a typical static-OO-programming style. -``streamio`` -============ +streamio +======== The :source:`rpython/rlib/streamio.py` contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the @@ -143,16 +143,16 @@ .. _`sio.py`: http://svn.python.org/view/sandbox/trunk/sio/sio.py -``unroll`` -========== +unroll +====== The :source:`rpython/rlib/unroll.py` module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. -``parsing`` -=========== +parsing +======= The :source:`rpython/rlib/parsing/` module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the From noreply at buildbot.pypy.org Tue Mar 5 14:51:31 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:31 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Remove empty pypy/doc/jit/_ref.txt. Message-ID: <20130305135131.A3EF91C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62075:8733ad6f16d4 Date: 2013-03-05 14:15 +0100 http://bitbucket.org/pypy/pypy/changeset/8733ad6f16d4/ Log: Remove empty pypy/doc/jit/_ref.txt. diff --git a/pypy/doc/jit/_ref.txt b/pypy/doc/jit/_ref.txt deleted file mode 100644 From noreply at buildbot.pypy.org Tue Mar 5 14:51:32 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:32 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Remove python files from pypy/doc/jit. Message-ID: <20130305135132.E66C91C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62076:f56db6a5d30f Date: 2013-03-05 14:15 +0100 http://bitbucket.org/pypy/pypy/changeset/f56db6a5d30f/ Log: Remove python files from pypy/doc/jit. diff --git a/pypy/doc/jit/__init__.py b/pypy/doc/jit/__init__.py deleted file mode 100644 diff --git a/pypy/doc/jit/confrest.py b/pypy/doc/jit/confrest.py deleted file mode 100644 --- a/pypy/doc/jit/confrest.py +++ /dev/null @@ -1,17 +0,0 @@ -from pypy.doc.confrest import * - -class PyPyPage(PyPyPage): - def fill(self): - super(PyPyPage, self).fill() - self.menubar[:] = html.div( - html.a("general documentation", href="../index.html", - class_="menu"), py.xml.raw(" " * 3), - html.a("JIT documentation", href="index.html", - class_="menu"), " ", - " ", id="menubar") - -class Project(Project): - stylesheet = "../style.css" - title = "PyPy JIT" - prefix_title = "PyPy JIT" - Page = PyPyPage From noreply at buildbot.pypy.org Tue Mar 5 14:51:34 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:34 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Move pypy/doc/jit to rpython/doc/jit. Message-ID: <20130305135134.36A1F1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62077:aa6ed93b3353 Date: 2013-03-05 14:16 +0100 http://bitbucket.org/pypy/pypy/changeset/aa6ed93b3353/ Log: Move pypy/doc/jit to rpython/doc/jit. diff --git a/pypy/doc/jit/index.rst b/rpython/doc/jit/index.rst rename from pypy/doc/jit/index.rst rename to rpython/doc/jit/index.rst diff --git a/pypy/doc/jit/overview.rst b/rpython/doc/jit/overview.rst rename from pypy/doc/jit/overview.rst rename to rpython/doc/jit/overview.rst diff --git a/pypy/doc/jit/pyjitpl5.rst b/rpython/doc/jit/pyjitpl5.rst rename from pypy/doc/jit/pyjitpl5.rst rename to rpython/doc/jit/pyjitpl5.rst From noreply at buildbot.pypy.org Tue Mar 5 14:51:35 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:35 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Be more general in rpython/doc/jit/. Message-ID: <20130305135135.81BFE1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62078:8753a754df24 Date: 2013-03-05 14:35 +0100 http://bitbucket.org/pypy/pypy/changeset/8753a754df24/ Log: Be more general in rpython/doc/jit/. In some passages it's not obvious because they are historical notes or examples from the PyPy interpreter. diff --git a/rpython/doc/jit/index.rst b/rpython/doc/jit/index.rst --- a/rpython/doc/jit/index.rst +++ b/rpython/doc/jit/index.rst @@ -4,7 +4,7 @@ :abstract: - When PyPy is translated into an executable such as ``pypy-c``, the + When a interpreter written in RPython is translated into an executable, the executable contains a full virtual machine that can optionally include a Just-In-Time compiler. This JIT compiler is **generated automatically from the interpreter** that we wrote in RPython. @@ -26,4 +26,5 @@ .. _Overview: overview.html .. _Notes: pyjitpl5.html +.. TODO: Update link .. _Hooks: ../jit-hooks.html diff --git a/rpython/doc/jit/overview.rst b/rpython/doc/jit/overview.rst --- a/rpython/doc/jit/overview.rst +++ b/rpython/doc/jit/overview.rst @@ -4,7 +4,7 @@ .. contents:: -This is a non-technical introduction and motivation for PyPy's approach +This is a non-technical introduction and motivation for RPython's approach to Just-In-Time compiler generation. @@ -65,7 +65,7 @@ The closest comparison to our current JIT is Tamarin's TraceMonkey. However, this JIT compiler is written manually, which is quite some -effort. In PyPy, we write a JIT generator at the level of RPython, +effort. Instead, we write a JIT generator at the level of RPython, which means that our final JIT does not have to -- indeed, cannot -- be written to encode all the details of the full Python language. These details are automatically supplied by the fact that we have an @@ -187,7 +187,7 @@ Further reading ======================================================================== -The description of the current PyPy JIT generator is given in PyJitPl5_ +The description of the current RPython JIT generator is given in PyJitPl5_ (draft). .. _`JSR 292`: http://jcp.org/en/jsr/detail?id=292 diff --git a/rpython/doc/jit/pyjitpl5.rst b/rpython/doc/jit/pyjitpl5.rst --- a/rpython/doc/jit/pyjitpl5.rst +++ b/rpython/doc/jit/pyjitpl5.rst @@ -2,18 +2,18 @@ PyJitPl5 ========== -This document describes the fifth generation of PyPy's JIT. +This document describes the fifth generation of the RPython JIT generator. Implementation of the JIT ========================= The JIT's `theory`_ is great in principle, but the actual code is a different -story. This section tries to give a high level overview of how PyPy's JIT is +story. This section tries to give a high level overview of how RPython's JIT is implemented. It's helpful to have an understanding of how the `RPython translation toolchain`_ works before digging into the sources. -Almost all JIT specific code is found in pypy/jit subdirectories. Translation +Almost all JIT specific code is found in rpython subdirectories. Translation time code is in the codewriter directory. The metainterp directory holds platform independent code including the the tracer and the optimizer. Code in the backend directory is responsible for generating machine code. @@ -25,7 +25,7 @@ JIT hints --------- -To add a JIT to an interpreter, PyPy only requires that two hints be added to +To add a JIT to an interpreter, RPython only requires two hints to be added to the target interpreter. These are jit_merge_point and can_enter_jit. jit_merge_point is supposed to go at the start of opcode dispatch. It allows the JIT to bail back to the interpreter in case running machine code is no @@ -34,7 +34,7 @@ interpreter defines its hints in pypy/module/pypyjit/interp_jit.py in a few overridden methods of the default interpreter loop. -An interpreter wishing to use the PyPy's JIT must define a list of *green* +An interpreter wishing to use the RPython JIT generator must define a list of *green* variables and a list of *red* variables. The *green* variables are loop constants. They are used to identify the current loop. Red variables are for everything else used in the execution loop. For example, the Python interpreter @@ -152,7 +152,7 @@ loop. Since it is only used by the JIT, it can be "optimized out"; the value doesn't have to be allocated at all and its fields can be stored as first class values instead of deferencing them in memory. Virtuals allow temporary objects -in the interpreter to be unwrapped. For example, a W_IntObject in the PyPy can +in the interpreter to be unwrapped. For example, a W_IntObject in the PyPy interpreter can be unwrapped to just be its integer value as long as the object is known not to escape the machine code. From noreply at buildbot.pypy.org Tue Mar 5 14:51:36 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:36 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: After splitting the docs it should be obvious that the translation toolchain can be used for other interpreters. Message-ID: <20130305135136.C03AE1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62079:6dfb5312fed7 Date: 2013-03-05 14:44 +0100 http://bitbucket.org/pypy/pypy/changeset/6dfb5312fed7/ Log: After splitting the docs it should be obvious that the translation toolchain can be used for other interpreters. diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -139,31 +139,6 @@ (now-dead) object are still true about the new object. -.. _`prolog and javascript`: - --------------------------------------------------------------------------- -Can I use PyPy's translation toolchain for other languages besides Python? --------------------------------------------------------------------------- - -Yes. The toolsuite that translates the PyPy interpreter is quite -general and can be used to create optimized versions of interpreters -for any language, not just Python. Of course, these interpreters -can make use of the same features that PyPy brings to Python: -translation to various languages, stackless features, -garbage collection, implementation of various things like arbitrarily long -integers, etc. - -Currently, we have preliminary versions of a JavaScript interpreter -(Leonardo Santagada as his Summer of PyPy project), a `Prolog interpreter`_ -(Carl Friedrich Bolz as his Bachelor thesis), and a `SmallTalk interpreter`_ -(produced during a sprint). On the `PyPy bitbucket page`_ there is also a -Scheme and an Io implementation; both of these are unfinished at the moment. - -.. _`Prolog interpreter`: https://bitbucket.org/cfbolz/pyrolog/ -.. _`SmallTalk interpreter`: http://dx.doi.org/10.1007/978-3-540-89275-5_7 -.. _`PyPy bitbucket page`: https://bitbucket.org/pypy/ - - Development =========== From noreply at buildbot.pypy.org Tue Mar 5 14:51:37 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:37 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Split FAQ entry 'What is PyPy?'. Message-ID: <20130305135137.E46A41C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62080:dc2d75ffad9d Date: 2013-03-05 14:48 +0100 http://bitbucket.org/pypy/pypy/changeset/dc2d75ffad9d/ Log: Split FAQ entry 'What is PyPy?'. diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -12,12 +12,8 @@ What is PyPy? ------------- -PyPy is both: - - - a reimplementation of Python in Python, and - - - a framework for implementing interpreters and virtual machines for - programming languages, especially dynamic languages. +PyPy is a reimplementation of Python in Python, using the RPython translation +toolchain. PyPy tries to find new answers about ease of creation, flexibility, maintainability and speed trade-offs for language implementations. diff --git a/rpython/doc/faq.rst b/rpython/doc/faq.rst --- a/rpython/doc/faq.rst +++ b/rpython/doc/faq.rst @@ -4,6 +4,13 @@ .. contents:: +---------------- +What is RPython? +---------------- + +RPython is a framework for implementing interpreters and virtual machines for +programming languages, especially dynamic languages. + ------------------------------------------------ Can RPython compile normal Python programs to C? ------------------------------------------------ From noreply at buildbot.pypy.org Tue Mar 5 14:51:39 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 14:51:39 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Move PyPy FAQ entries to top-level. Message-ID: <20130305135139.23DED1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62081:b27bc64a8887 Date: 2013-03-05 14:50 +0100 http://bitbucket.org/pypy/pypy/changeset/b27bc64a8887/ Log: Move PyPy FAQ entries to top-level. diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -4,10 +4,6 @@ .. contents:: - -General -======= - ------------- What is PyPy? ------------- @@ -134,10 +130,6 @@ process, including checking that all the previous assumptions about the (now-dead) object are still true about the new object. - -Development -=========== - ----------------------------------------------------------- How do I get into PyPy development? Can I come to sprints? ----------------------------------------------------------- From noreply at buildbot.pypy.org Tue Mar 5 15:03:29 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:03:29 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Remove unused file. Message-ID: <20130305140329.42D3B1C029E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62082:4a2c5919ed46 Date: 2013-03-05 14:59 +0100 http://bitbucket.org/pypy/pypy/changeset/4a2c5919ed46/ Log: Remove unused file. diff --git a/pypy/doc/throwaway.txt b/pypy/doc/throwaway.txt deleted file mode 100644 --- a/pypy/doc/throwaway.txt +++ /dev/null @@ -1,3 +0,0 @@ -.. warning:: - - This documentation should be removed (as discussed during the Gothenburg sprint in 2011) From noreply at buildbot.pypy.org Tue Mar 5 15:44:55 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:44:55 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Be more more general in rpython/doc/windows.rst. There is still potential to improve but at least it makes sense ('[...] how to translate a interpreter written in RPython, using PyPy as an example'). Message-ID: <20130305144455.4966F1C1043@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62083:ed0aa19a2ab5 Date: 2013-03-05 15:19 +0100 http://bitbucket.org/pypy/pypy/changeset/ed0aa19a2ab5/ Log: Be more more general in rpython/doc/windows.rst. There is still potential to improve but at least it makes sense ('[...] how to translate a interpreter written in RPython, using PyPy as an example'). diff --git a/rpython/doc/windows.rst b/rpython/doc/windows.rst --- a/rpython/doc/windows.rst +++ b/rpython/doc/windows.rst @@ -1,13 +1,13 @@ -=============== -PyPy on Windows -=============== +================== +RPython on Windows +================== -Pypy is supported on Windows platforms, starting with Windows 2000. -The following text gives some hints about how to translate the PyPy -interpreter. +RPython is supported on Windows platforms, starting with Windows 2000. +The following text gives some hints about how to translate a interpreter +written in RPython, using PyPy as an example. -To build pypy-c you need a C compiler. Microsoft Visual Studio is -preferred, but can also use the mingw32 port of gcc. +To build an interpreter written in RPython you need a C compiler. +Microsoft Visual Studio is preferred, but can also use the mingw32 port of gcc. Translating PyPy with Visual Studio @@ -24,18 +24,18 @@ translation. Failing that, they will pick the most recent Visual Studio compiler they can find. In addition, the target architecture (32 bits, 64 bits) is automatically selected. A 32 bit build can only be built -using a 32 bit Python and vice versa. By default pypy is built using the -Multi-threaded DLL (/MD) runtime environment. +using a 32 bit Python and vice versa. By default the interpreter is built using +the Multi-threaded DLL (/MD) runtime environment. -**Note:** PyPy is currently not supported for 64 bit Windows, and translation -will fail in this case. +**Note:** The RPython translator does currently not support 64 bit Windows, and +translation will fail in this case. The compiler is all you need to build pypy-c, but it will miss some modules that relies on third-party libraries. See below how to get and build them. -Preping Windows for the Large Build ------------------------------------ +Preparing Windows for the large build +------------------------------------- Normally 32bit programs are limited to 2GB of memory on Windows. It is possible to raise this limit, to 3GB on Windows 32bit, and almost 4GB @@ -85,7 +85,7 @@ http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-7.1.tar.gz Versions 7.0 and 7.1 are known to work; the 6.x series won't work with -pypy. Unpack this folder in the base directory. Then open a command +RPython. Unpack this folder in the base directory. Then open a command prompt:: cd gc-7.1 @@ -121,7 +121,7 @@ Studio; follow the instruction for converting the project files, switch to the "Release" configuration, reconfigure the runtime for Multi-threaded DLL (/MD) and build the solution (the ``expat`` project -is actually enough for pypy). +is actually enough for PyPy). Then, copy the file ``win32\bin\release\libexpat.dll`` somewhere in your PATH. @@ -143,14 +143,14 @@ Using the mingw compiler ------------------------ -You can compile pypy with the mingw compiler, using the --cc=mingw32 option; -gcc.exe must be on the PATH. If the -cc flag does not begin with "ming", it should be -the name of a valid gcc-derivative compiler, i.e. x86_64-w64-mingw32-gcc for the 64 bit -compiler creating a 64 bit target. +You can compile an RPython program with the mingw compiler, using the +--cc=mingw32 option; gcc.exe must be on the PATH. If the -cc flag does not +begin with "ming", it should be the name of a valid gcc-derivative compiler, +i.e. x86_64-w64-mingw32-gcc for the 64 bit compiler creating a 64 bit target. -You probably want to set the CPATH, LIBRARY_PATH, and PATH environment variable to -the header files, lib or dlls, and dlls respectively of the locally installed packages -if they are not in the mingw directory heirarchy. +You probably want to set the CPATH, LIBRARY_PATH, and PATH environment +variables to the header files, lib or dlls, and dlls respectively of the +locally installed packages if they are not in the mingw directory heirarchy. libffi for the mingw compiler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From noreply at buildbot.pypy.org Tue Mar 5 15:44:56 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:44:56 +0100 (CET) Subject: [pypy-commit] pypy improve-docs: Rename 'rpython-doc' to 'improve-docs'. Message-ID: <20130305144456.772FD1C1043@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: improve-docs Changeset: r62084:5242c9e843a1 Date: 2013-03-05 15:29 +0100 http://bitbucket.org/pypy/pypy/changeset/5242c9e843a1/ Log: Rename 'rpython-doc' to 'improve-docs'. From noreply at buildbot.pypy.org Tue Mar 5 15:44:57 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:44:57 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Close branch. Message-ID: <20130305144457.971A21C1043@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r62085:b0014e380e2a Date: 2013-03-05 15:30 +0100 http://bitbucket.org/pypy/pypy/changeset/b0014e380e2a/ Log: Close branch. From noreply at buildbot.pypy.org Tue Mar 5 15:44:58 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:44:58 +0100 (CET) Subject: [pypy-commit] pypy improve-docs: Move release announcements into folder pypy/doc/releases. Message-ID: <20130305144458.E77FC1C1043@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: improve-docs Changeset: r62086:0586acbc2dfe Date: 2013-03-05 15:44 +0100 http://bitbucket.org/pypy/pypy/changeset/0586acbc2dfe/ Log: Move release announcements into folder pypy/doc/releases. diff --git a/pypy/doc/release-0.6.rst b/pypy/doc/releases/0.6.rst rename from pypy/doc/release-0.6.rst rename to pypy/doc/releases/0.6.rst diff --git a/pypy/doc/release-0.7.0.rst b/pypy/doc/releases/0.7.0.rst rename from pypy/doc/release-0.7.0.rst rename to pypy/doc/releases/0.7.0.rst diff --git a/pypy/doc/release-0.8.0.rst b/pypy/doc/releases/0.8.0.rst rename from pypy/doc/release-0.8.0.rst rename to pypy/doc/releases/0.8.0.rst diff --git a/pypy/doc/release-0.9.0.rst b/pypy/doc/releases/0.9.0.rst rename from pypy/doc/release-0.9.0.rst rename to pypy/doc/releases/0.9.0.rst diff --git a/pypy/doc/release-0.99.0.rst b/pypy/doc/releases/0.99.0.rst rename from pypy/doc/release-0.99.0.rst rename to pypy/doc/releases/0.99.0.rst diff --git a/pypy/doc/release-1.0.0.rst b/pypy/doc/releases/1.0.0.rst rename from pypy/doc/release-1.0.0.rst rename to pypy/doc/releases/1.0.0.rst diff --git a/pypy/doc/release-1.1.0.rst b/pypy/doc/releases/1.1.0.rst rename from pypy/doc/release-1.1.0.rst rename to pypy/doc/releases/1.1.0.rst diff --git a/pypy/doc/release-1.2.0.rst b/pypy/doc/releases/1.2.0.rst rename from pypy/doc/release-1.2.0.rst rename to pypy/doc/releases/1.2.0.rst diff --git a/pypy/doc/release-1.3.0.rst b/pypy/doc/releases/1.3.0.rst rename from pypy/doc/release-1.3.0.rst rename to pypy/doc/releases/1.3.0.rst diff --git a/pypy/doc/release-1.4.0.rst b/pypy/doc/releases/1.4.0.rst rename from pypy/doc/release-1.4.0.rst rename to pypy/doc/releases/1.4.0.rst diff --git a/pypy/doc/release-1.4.0beta.rst b/pypy/doc/releases/1.4.0beta.rst rename from pypy/doc/release-1.4.0beta.rst rename to pypy/doc/releases/1.4.0beta.rst diff --git a/pypy/doc/release-1.4.1.rst b/pypy/doc/releases/1.4.1.rst rename from pypy/doc/release-1.4.1.rst rename to pypy/doc/releases/1.4.1.rst diff --git a/pypy/doc/release-1.5.0.rst b/pypy/doc/releases/1.5.0.rst rename from pypy/doc/release-1.5.0.rst rename to pypy/doc/releases/1.5.0.rst diff --git a/pypy/doc/release-1.6.0.rst b/pypy/doc/releases/1.6.0.rst rename from pypy/doc/release-1.6.0.rst rename to pypy/doc/releases/1.6.0.rst diff --git a/pypy/doc/release-1.7.0.rst b/pypy/doc/releases/1.7.0.rst rename from pypy/doc/release-1.7.0.rst rename to pypy/doc/releases/1.7.0.rst diff --git a/pypy/doc/release-1.8.0.rst b/pypy/doc/releases/1.8.0.rst rename from pypy/doc/release-1.8.0.rst rename to pypy/doc/releases/1.8.0.rst diff --git a/pypy/doc/release-1.9.0.rst b/pypy/doc/releases/1.9.0.rst rename from pypy/doc/release-1.9.0.rst rename to pypy/doc/releases/1.9.0.rst diff --git a/pypy/doc/release-2.0.0-beta1.rst b/pypy/doc/releases/2.0.0-beta1.rst rename from pypy/doc/release-2.0.0-beta1.rst rename to pypy/doc/releases/2.0.0-beta1.rst diff --git a/pypy/doc/releases/index.rst b/pypy/doc/releases/index.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/releases/index.rst @@ -0,0 +1,23 @@ +Release Announcements +===================== + +.. toctree:: + + 2.0.0-beta1 + 1.9.0 + 1.8.0 + 1.7.0 + 1.6.0 + 1.5.0 + 1.4.1 + 1.4.0beta + 1.4.0 + 1.3.0 + 1.2.0 + 1.1.0 + 1.0.0 + 0.99.0 + 0.9.0 + 0.8.0 + 0.7.0 + 0.6 From noreply at buildbot.pypy.org Tue Mar 5 15:51:30 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 5 Mar 2013 15:51:30 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: renamed interpreter.stack_depth to interpreter.remaining_stack_depth Message-ID: <20130305145130.09E9A1C1028@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r119:b7957355fd79 Date: 2013-03-04 17:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/b7957355fd79/ Log: renamed interpreter.stack_depth to interpreter.remaining_stack_depth diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -38,7 +38,7 @@ self.image = image self.image_name = image_name self.max_stack_depth = max_stack_depth - self.stack_depth = max_stack_depth + self.remaining_stack_depth = max_stack_depth self._loop = False def interpret_with_w_frame(self, w_frame): @@ -62,7 +62,7 @@ try: w_new_context = self.c_loop(w_new_context) except StackOverflow, e: - self.stack_depth = self.max_stack_depth + self.remaining_stack_depth = self.max_stack_depth w_new_context = e.w_context def c_loop(self, w_active_context): @@ -85,12 +85,12 @@ if not self._loop: return w_new_frame # this test is done to not loop in test, # but rather step just once where wanted - if self.stack_depth == 1: + if self.remaining_stack_depth == 1: raise StackOverflow(w_new_frame) - self.stack_depth = self.stack_depth - 1 + self.remaining_stack_depth -= 1 retval = self.c_loop(w_new_frame) - self.stack_depth = self.stack_depth + 1 + self.remaining_stack_depth += 1 return retval def perform(self, w_receiver, selector, *arguments_w): diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -994,7 +994,7 @@ class StackTestInterpreter(interpreter.Interpreter): def stack_frame(self, w_frame): import sys - stack_depth = self.max_stack_depth - self.stack_depth + stack_depth = self.max_stack_depth - self.remaining_stack_depth for i in range(stack_depth + 1): assert sys._getframe(4 + i * 6).f_code.co_name == 'c_loop' assert sys._getframe(5 + stack_depth * 6).f_code.co_name == 'loop' From noreply at buildbot.pypy.org Tue Mar 5 15:51:31 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 5 Mar 2013 15:51:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: changed from a mixed stack of w_PointerObjects and MethodContextShadows to only MethodContextShadows Message-ID: <20130305145131.33C6D1C1028@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r120:d939a6f9d3d7 Date: 2013-03-05 15:50 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d939a6f9d3d7/ Log: changed from a mixed stack of w_PointerObjects and MethodContextShadows to only MethodContextShadows renamed ContextPart>>method() to s_method() diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -28,7 +28,7 @@ _last_indent = "" jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], - reds=['s_active_context', 'w_active_context'], + reds=['s_active_context'], #virtualizables=['s_active_context'], get_printable_location=get_printable_location ) @@ -57,39 +57,38 @@ def loop(self, w_active_context): # just a trampoline for the actual loop implemented in c_loop self._loop = True - w_new_context = w_active_context + s_new_context = w_active_context.as_context_get_shadow(self.space) while True: try: - w_new_context = self.c_loop(w_new_context) + s_new_context = self.c_loop(s_new_context) except StackOverflow, e: self.remaining_stack_depth = self.max_stack_depth - w_new_context = e.w_context + s_new_context = e.s_context - def c_loop(self, w_active_context): - s_active_context = w_active_context.as_context_get_shadow(self.space) + def c_loop(self, s_context): + s_active_context = s_context while True: pc = s_active_context._pc - method = s_active_context.method() + method = s_active_context.s_method() self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, - s_active_context=s_active_context, - w_active_context=w_active_context) - w_return_to_context = self.step(s_active_context) - if (w_return_to_context is not None - and not w_return_to_context.is_same_object(w_active_context)): - w_active_context.as_context_get_shadow(self.space).mark_returned() - return w_return_to_context + s_active_context=s_active_context) + s_return_to_context = self.step(s_active_context) + if (s_return_to_context is not None + and s_return_to_context is not s_context): + s_active_context.mark_returned() + return s_return_to_context - def stack_frame(self, w_new_frame): + def stack_frame(self, s_new_frame): if not self._loop: - return w_new_frame # this test is done to not loop in test, + return s_new_frame # this test is done to not loop in test, # but rather step just once where wanted if self.remaining_stack_depth == 1: - raise StackOverflow(w_new_frame) + raise StackOverflow(s_new_frame) self.remaining_stack_depth -= 1 - retval = self.c_loop(w_new_frame) + retval = self.c_loop(s_new_frame) self.remaining_stack_depth += 1 return retval @@ -106,16 +105,16 @@ w_method.setbytes([chr(124)]) #returnTopFromMethod s_method = w_method.as_compiledmethod_get_shadow(self.space) s_frame = MethodContextShadow.make_context( - self.space, s_method, w_receiver, [], None).get_shadow(self.space) + self.space, s_method, w_receiver, [], None) s_frame.push(w_receiver) s_frame.push_all(list(arguments_w)) try: - w_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self) - if w_new_frame == None: + s_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self) + if s_new_frame == None: # which means that we tried to call a primitive method return s_frame.pop() else: - self.loop(w_new_frame) + self.loop(s_new_frame.w_self()) except ReturnFromTopLevel, e: return e.object @@ -124,8 +123,8 @@ self.object = object class StackOverflow(Exception): - def __init__(self, w_top_context): - self.w_context = w_top_context + def __init__(self, s_top_context): + self.s_context = s_top_context def make_call_primitive_bytecode(primitive, selector, argcount): def callPrimitive(self, interp, current_bytecode): @@ -179,14 +178,14 @@ def pushLiteralConstantBytecode(self, interp, current_bytecode): index = current_bytecode & 31 - self.push(self.method().getliteral(index)) + self.push(self.s_method().getliteral(index)) def pushLiteralVariableBytecode(self, interp, current_bytecode): # this bytecode assumes that literals[index] is an Association # which is an object with two named vars, and fetches the second # named var (the value). index = current_bytecode & 31 - w_association = self.method().getliteral(index) + w_association = self.s_method().getliteral(index) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) @@ -231,7 +230,7 @@ # send, return bytecodes def sendLiteralSelectorBytecode(self, interp, current_bytecode): - w_selector = self.method().getliteral(current_bytecode & 15) + w_selector = self.s_method().getliteral(current_bytecode & 15) argcount = ((current_bytecode >> 4) & 3) - 1 return self._sendSelfSelector(w_selector, argcount, interp) @@ -241,7 +240,7 @@ receiver, receiver.shadow_of_my_class(self.space)) def _sendSuperSelector(self, w_selector, argcount, interp): - w_compiledin = self.method().w_compiledin + w_compiledin = self.s_method().w_compiledin assert isinstance(w_compiledin, model.W_PointersObject) s_compiledin = w_compiledin.as_class_get_shadow(self.space) return self._sendSelector(w_selector, argcount, interp, self.w_receiver(), @@ -271,39 +270,41 @@ print "PRIMITIVE FAILED: %d %s" % (s_method.primitive, w_selector.as_string(),) pass # ignore this error and fall back to the Smalltalk version arguments = self.pop_and_return_n(argcount) - w_frame = s_method.create_frame(self.space, receiver, arguments, - self.w_self()) + s_frame = s_method.create_frame(self.space, receiver, arguments, self) self.pop() - return interp.stack_frame(w_frame) + return interp.stack_frame(s_frame) - def _return(self, return_value, interp, w_return_to): + def _return(self, return_value, interp, s_return_to): # for tests, when returning from the top-level context - if w_return_to.is_same_object(self.space.w_nil): + if s_return_to is None: raise ReturnFromTopLevel(return_value) + # unfortunately, the assert below is not true for some tests + # assert self._stack_ptr == self.tempsize() + # make this context a returned one self.mark_returned() - w_return_to.as_context_get_shadow(self.space).push(return_value) - return w_return_to + s_return_to.push(return_value) + return s_return_to def returnReceiver(self, interp, current_bytecode): - return self._return(self.w_receiver(), interp, self.s_home().w_sender()) + return self._return(self.w_receiver(), interp, self.s_home().s_sender()) def returnTrue(self, interp, current_bytecode): - return self._return(interp.space.w_true, interp, self.s_home().w_sender()) + return self._return(interp.space.w_true, interp, self.s_home().s_sender()) def returnFalse(self, interp, current_bytecode): - return self._return(interp.space.w_false, interp, self.s_home().w_sender()) + return self._return(interp.space.w_false, interp, self.s_home().s_sender()) def returnNil(self, interp, current_bytecode): - return self._return(interp.space.w_nil, interp, self.s_home().w_sender()) + return self._return(interp.space.w_nil, interp, self.s_home().s_sender()) def returnTopFromMethod(self, interp, current_bytecode): # overwritten in MethodContextShadow - return self._return(self.top(), interp, self.s_home().w_sender()) + return self._return(self.pop(), interp, self.s_home().s_sender()) def returnTopFromBlock(self, interp, current_bytecode): - return self._return(self.top(), interp, self.w_sender()) + return self._return(self.pop(), interp, self.s_sender()) def unknownBytecode(self, interp, current_bytecode): raise MissingBytecode("unknownBytecode") @@ -320,9 +321,9 @@ elif variableType == 1: self.push(self.gettemp(variableIndex)) elif variableType == 2: - self.push(self.method().getliteral(variableIndex)) + self.push(self.s_method().getliteral(variableIndex)) elif variableType == 3: - w_association = self.method().getliteral(variableIndex) + w_association = self.s_method().getliteral(variableIndex) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) else: @@ -337,7 +338,7 @@ elif variableType == 2: raise IllegalStoreError elif variableType == 3: - w_association = self.method().getliteral(variableIndex) + w_association = self.s_method().getliteral(variableIndex) association = wrapper.AssociationWrapper(self.space, w_association) association.store_value(self.top()) @@ -347,7 +348,7 @@ def getExtendedSelectorArgcount(self): descriptor = self.getbytecode() - return ((self.method().getliteral(descriptor & 31)), + return ((self.s_method().getliteral(descriptor & 31)), (descriptor >> 5)) def singleExtendedSendBytecode(self, interp, current_bytecode): @@ -360,21 +361,21 @@ opType = second >> 5 if opType == 0: # selfsend - return self._sendSelfSelector(self.method().getliteral(third), + return self._sendSelfSelector(self.s_method().getliteral(third), second & 31, interp) elif opType == 1: # supersend - return self._sendSuperSelector(self.method().getliteral(third), + return self._sendSuperSelector(self.s_method().getliteral(third), second & 31, interp) elif opType == 2: # pushReceiver self.push(self.w_receiver().fetch(self.space, third)) elif opType == 3: # pushLiteralConstant - self.push(self.method().getliteral(third)) + self.push(self.s_method().getliteral(third)) elif opType == 4: # pushLiteralVariable - w_association = self.method().getliteral(third) + w_association = self.s_method().getliteral(third) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) elif opType == 5: @@ -382,7 +383,7 @@ elif opType == 6: self.w_receiver().store(self.space, third, self.pop()) elif opType == 7: - w_association = self.method().getliteral(third) + w_association = self.s_method().getliteral(third) association = wrapper.AssociationWrapper(self.space, w_association) association.store_value(self.top()) @@ -392,7 +393,7 @@ def secondExtendedSendBytecode(self, interp, current_bytecode): descriptor = self.getbytecode() - w_selector = self.method().getliteral(descriptor & 63) + w_selector = self.s_method().getliteral(descriptor & 63) argcount = descriptor >> 6 return self._sendSelfSelector(w_selector, argcount, interp) @@ -457,7 +458,7 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - w_closure = space.newClosure(self._w_self, self.pc(), numArgs, + w_closure = space.newClosure(self.w_self(), self.pc(), numArgs, self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -105,15 +105,21 @@ else: raise NotImplementedError( "unknown unwrap_spec %s" % (spec, )) - w_result = func(interp, s_frame, *args) - # After calling primitive, reload context-shadow in case it - # needs to be updated - s_frame.pop_n(len_unwrap_spec) # only if no exception occurs! if result_is_new_frame: - return interp.stack_frame(w_result) - elif not no_result: - assert w_result is not None - s_frame.push(w_result) + s_new_frame = func(interp, s_frame, *args) + # After calling primitive, reload context-shadow in case it + # needs to be updated + s_frame.pop_n(len_unwrap_spec) # only if no exception occurs! + return interp.stack_frame(s_new_frame) + else: + w_result = func(interp, s_frame, *args) + # After calling primitive, reload context-shadow in case it + # needs to be updated + s_frame.pop_n(len_unwrap_spec) # only if no exception occurs! + if not no_result: + assert w_result is not None + assert isinstance(w_result, model.W_Object) + s_frame.push(w_result) wrapped.func_name = "wrap_prim_" + name prim_table[code] = wrapped prim_table_implemented_only.append((code, wrapped)) @@ -849,16 +855,16 @@ # The block bytecodes are stored inline: so we skip past the # byteodes to invoke this primitive to find them (hence +2) initialip = s_frame.pc() + 2 - w_new_context = shadow.BlockContextShadow.make_context( + s_new_context = shadow.BlockContextShadow.make_context( interp.space, w_method_context, interp.space.w_nil, argcnt, initialip) - return w_new_context + return s_new_context.w_self() -def finalize_block_ctx(interp, s_block_ctx, w_frame): +def finalize_block_ctx(interp, s_block_ctx, s_frame): # Set some fields s_block_ctx.store_pc(s_block_ctx.initialip()) - s_block_ctx.store_w_sender(w_frame) - return s_block_ctx.w_self() + s_block_ctx.store_s_sender(s_frame) + return s_block_ctx @expose_primitive(VALUE, result_is_new_frame=True) def func(interp, s_frame, argument_count): @@ -893,7 +899,7 @@ s_block_ctx.push_all(block_args) s_frame.pop() - return finalize_block_ctx(interp, s_block_ctx, s_frame.w_self()) + return finalize_block_ctx(interp, s_block_ctx, s_frame) @expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], result_is_new_frame=True) @@ -912,7 +918,7 @@ # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation - return finalize_block_ctx(interp, s_block_ctx, s_frame.w_self()) + return finalize_block_ctx(interp, s_block_ctx, s_frame) @expose_primitive(PERFORM) def func(interp, s_frame, argcount): @@ -925,12 +931,12 @@ s_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) assert s_method - w_frame = s_method.create_frame( + s_new_frame = s_method.create_frame( interp.space, w_rcvr, [w_args.fetch(interp.space, i) for i in range(w_args.size())]) - w_frame.as_context_get_shadow(interp.space).store_w_sender(s_frame.w_self()) - return w_frame + s_new_frame.store_w_sender(s_frame.w_self()) + return s_new_frame @expose_primitive(SIGNAL, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): @@ -957,7 +963,7 @@ interp.space.w_Process): raise PrimitiveFailedError() s_frame.push(w_rcvr) # w_rcvr is the result in the old frame - return wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self()) + return wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self()).as_context_get_shadow(interp.space) @expose_primitive(SUSPEND, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr, result_is_new_frame=True): @@ -966,7 +972,7 @@ interp.space.w_Process): raise PrimitiveFailedError() s_frame.push(w_rcvr) # w_rcvr is the result in the old frame - return wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self()) + return wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self()).as_context_get_shadow(interp.space) @expose_primitive(FLUSH_CACHE, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): @@ -1010,14 +1016,13 @@ # additionally to the smalltalk implementation, this also pushes # args and copiedValues - w_new_frame = block.asContextWithSender( - s_frame.w_self(), args_w) - w_closureMethod = w_new_frame.get_shadow(space).w_method() + s_new_frame = block.asContextWithSender(s_frame.w_self(), args_w) + w_closureMethod = s_new_frame.w_method() assert isinstance(w_closureMethod, model.W_CompiledMethod) assert w_block is not block.outerContext() - return w_new_frame + return s_new_frame @expose_primitive(CLOSURE_VALUE, unwrap_spec=[object], result_is_new_frame=True) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -284,7 +284,11 @@ class AbstractRedirectingShadow(AbstractShadow): def __init__(self, space, w_self): AbstractShadow.__init__(self, space, w_self) - self._w_self_size = self.w_self().size() + if w_self is not None: + self._w_self_size = w_self.size() + else: + self._w_self_size = 0 + def fetch(self, n0): raise NotImplementedError() def store(self, n0, w_value): @@ -313,14 +317,13 @@ __metaclass__ = extendabletype # _virtualizable2_ = [ - # "_w_sender", "_pc", "_w_sender", + # "_s_sender", "_pc", # "_temps_and_stack[*]", "_stack_ptr", # "_w_self", "_w_self_size" # ] def __init__(self, space, w_self): - - self._w_sender = space.w_nil + self._s_sender = None AbstractRedirectingShadow.__init__(self, space, w_self) @staticmethod @@ -403,32 +406,37 @@ " Return self of the method, or the method that contains the block " return self.s_home().w_receiver() + def store_s_sender(self, s_sender): + assert s_sender is None or isinstance(s_sender, ContextPartShadow) + self._s_sender = s_sender + def store_w_sender(self, w_sender): assert isinstance(w_sender, model.W_PointersObject) - self._w_sender = w_sender + if w_sender.is_same_object(self.space.w_nil): + self._s_sender = None + else: + self._s_sender = w_sender.as_context_get_shadow(self.space) def w_sender(self): - return self._w_sender + if self._s_sender is None: + return self.space.w_nil + return self._s_sender.w_self() def s_sender(self): - w_sender = self.w_sender() - if w_sender.is_same_object(self.space.w_nil): - return None - else: - return w_sender.as_context_get_shadow(self.space) + return self._s_sender def store_unwrap_pc(self, w_pc): if w_pc.is_same_object(self.space.w_nil): return pc = self.space.unwrap_int(w_pc) - pc -= self.method().bytecodeoffset + pc -= self.s_method().bytecodeoffset pc -= 1 self.store_pc(pc) def wrap_pc(self): pc = self.pc() pc += 1 - pc += self.method().bytecodeoffset + pc += self.s_method().bytecodeoffset return self.space.wrap_int(pc) def pc(self): @@ -442,7 +450,7 @@ def mark_returned(self): self.store_pc(-1) - self.store_w_sender(self.space.w_nil) + self.store_s_sender(None) def is_returned(self): return self.pc() == -1 and self.w_sender is self.space.w_nil @@ -453,7 +461,7 @@ def w_method(self): return self.s_home().w_method() - def method(self): + def s_method(self): w_method = jit.promote(self.w_method()) return jit.promote( w_method.as_compiledmethod_get_shadow(self.space) @@ -462,7 +470,7 @@ def getbytecode(self): jit.promote(self._pc) assert self._pc >= 0 - bytecode = self.method().bytecode[self._pc] + bytecode = self.s_method().bytecode[self._pc] currentBytecode = ord(bytecode) self._pc += 1 return currentBytecode @@ -489,11 +497,13 @@ # ______________________________________________________________________ # Stack Manipulation + def stack(self): """NOT_RPYTHON""" # purely for testing return self._temps_and_stack[self.tempsize():self._stack_ptr] def pop(self): + #assert self._stack_ptr > self.tempsize() ptr = jit.promote(self._stack_ptr) - 1 ret = self._temps_and_stack[ptr] # you get OverflowError if the stack is empty self._temps_and_stack[ptr] = None @@ -501,6 +511,8 @@ return ret def push(self, w_v): + #assert self._stack_ptr >= self.tempsize() + #assert self._stack_ptr < self.stackend() - self.stackstart() + self.tempsize() ptr = jit.promote(self._stack_ptr) self._temps_and_stack[ptr] = w_v self._stack_ptr = ptr + 1 @@ -522,6 +534,7 @@ @jit.unroll_safe def pop_n(self, n): + #assert n == 0 or self._stack_ptr - n >= self.tempsize() jit.promote(self._stack_ptr) while n > 0: n -= 1 @@ -543,6 +556,20 @@ def tempsize(self): raise NotImplementedError() + # ______________________________________________________________________ + # Marriage of Context Shadows with PointerObjects only when required + + def w_self(self): + if self._w_self is not None: + return self._w_self + else: + size = self.size() - self.space.w_MethodContext.as_class_get_shadow(self.space).instance_size + space = self.space + w_self = space.w_MethodContext.as_class_get_shadow(space).new(size) + w_self.store_shadow(self) + self._w_self = w_self + self._w_self_size = w_self.size() + return w_self def store_instances_array(self, list_w): # used for primitives 77 & 78 @@ -551,10 +578,11 @@ def instances_array(self): return self.instances_w + class BlockContextShadow(ContextPartShadow): @staticmethod - def make_context(space, w_home, w_sender, argcnt, initialip): + def make_context(space, w_home, s_sender, argcnt, initialip): # create and attach a shadow manually, to not have to carefully put things # into the right places in the W_PointersObject # XXX could hack some more to never have to create the _vars of w_result @@ -568,7 +596,7 @@ s_result.store_w_home(w_home) s_result.store_pc(initialip) s_result.init_stack_and_temps() - return w_result + return s_result def fetch(self, n0): if n0 == constants.BLKCTX_HOME_INDEX: @@ -599,12 +627,12 @@ def unwrap_store_initialip(self, w_value): initialip = self.space.unwrap_int(w_value) - initialip -= 1 + self.method().literalsize + initialip -= 1 + self.s_method().literalsize self.store_initialip(initialip) def wrap_initialip(self): initialip = self.initialip() - initialip += 1 + self.method().literalsize + initialip += 1 + self.s_method().literalsize return self.space.wrap_int(initialip) def unwrap_store_eargc(self, w_value): @@ -656,36 +684,34 @@ @staticmethod @jit.unroll_safe def make_context(space, s_method, w_receiver, - arguments, w_sender=None, closure=None, pc=0): + arguments, s_sender=None, closure=None, pc=0): # From blue book: normal mc have place for 12 temps+maxstack # mc for methods with islarge flag turned on 32 - size = 12 + s_method.islarge * 20 + s_method.argsize - w_result = space.w_MethodContext.as_class_get_shadow(space).new(size) - assert isinstance(w_result, model.W_PointersObject) - # create and attach a shadow manually, to not have to carefully put things - # into the right places in the W_PointersObject - # XXX could hack some more to never have to create the _vars of w_result - s_result = MethodContextShadow(space, w_result) - s_result = jit.hint(s_result, access_directly=True, fresh_virtualizable=True) + size = (12 + s_method.islarge * 20 + s_method.argsize + + space.w_MethodContext.as_class_get_shadow(space).instance_size) + # The last summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self. + + s_new_context = MethodContextShadow(space, None) + s_new_context._w_self_size = size + s_new_context = jit.hint(s_new_context, access_directly=True, fresh_virtualizable=True) - w_result.store_shadow(s_result) if closure is not None: - s_result.w_closure_or_nil = closure._w_self + s_new_context.w_closure_or_nil = closure._w_self - s_result.store_w_method(s_method.w_self()) - if w_sender: - s_result.store_w_sender(w_sender) - s_result.store_w_receiver(w_receiver) - s_result.store_pc(pc) - s_result.init_stack_and_temps() + s_new_context.store_w_method(s_method.w_self()) + if s_sender: + s_new_context.store_s_sender(s_sender) + s_new_context.store_w_receiver(w_receiver) + s_new_context.store_pc(pc) + s_new_context.init_stack_and_temps() argc = len(arguments) for i0 in range(argc): - s_result.settemp(i0, arguments[i0]) + s_new_context.settemp(i0, arguments[i0]) if closure is not None: for i0 in range(closure.size()): - s_result.settemp(i0+argc, closure.at0(i0)) - return w_result + s_new_context.settemp(i0+argc, closure.at0(i0)) + return s_new_context def fetch(self, n0): if n0 == constants.MTHDCTX_METHOD: @@ -724,7 +750,7 @@ def tempsize(self): if not self.is_closure_context(): - return self.method().tempsize + return self.s_method().tempsize else: return wrapper.BlockClosureWrapper(self.space, self.w_closure_or_nil).tempsize() @@ -772,10 +798,10 @@ # XXX check whether we can actually return from that context if s_outerContext.pc() == -1: raise error.BlockCannotReturnError() - return_to_context = s_outerContext.s_home().w_sender() + return_to_context = s_outerContext.s_home().s_sender() else: - return_to_context = self.s_home().w_sender() - return self._return(self.top(), interp, return_to_context) + return_to_context = self.s_home().s_sender() + return self._return(self.pop(), interp, return_to_context) def is_closure_context(self): return self.w_closure_or_nil is not self.space.w_nil @@ -783,7 +809,7 @@ def __str__(self): retval = '\nMethodContext of:' retval += self.w_method().as_string(markBytecode=self.pc() + 1) - retval += "Stackptr: %i" % self._stack_ptr + retval += "Stackptr: %i (this is an empty ascending stack)" % (self._stack_ptr - self.tempsize()) retval += "\nStack : " + str(self.stack()) return retval @@ -831,6 +857,6 @@ def create_frame(self, space, receiver, arguments, sender = None): assert len(arguments) == self.argsize - w_new = MethodContextShadow.make_context( + s_new = MethodContextShadow.make_context( space, self, receiver, arguments, sender) - return w_new + return s_new diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -64,9 +64,9 @@ w_object = model.W_SmallInteger(0) s_class = w_object.shadow_of_my_class(space) s_method = s_class.lookup(w_selector) - w_frame = s_method.create_frame(space, w_object, []) + s_frame = s_method.create_frame(space, w_object, []) def interp_w(): - interp.loop(w_frame) + interp.loop(s_frame.w_self()) self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True, inline=True) diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -17,14 +17,16 @@ w_class.shadow_of_my_class(tools.space)) perform(w_class, initialize_symbol) -#initialize String class, because equality testing requires a class var set. -initialize_class(w("string").getclass(tools.space)) +def test_initialize_string_class(): + #initialize String class, because equality testing requires a class var set. + initialize_class(w("string").getclass(tools.space)) def test_symbol_asSymbol(): w_result = perform(tools.image.w_asSymbol, "asSymbol") assert w_result is tools.image.w_asSymbol def test_create_new_symbol(): + py.test.skip("This test takes quite long and is actually included in test_retrieve_symbol.") w_result = perform(w("someString"), "asSymbol") assert w_result is not None assert w_result.as_string() == "someString" diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -8,7 +8,10 @@ interp = interpreter.Interpreter(space) def step_in_interp(ctxt): # due to missing resets in between tests interp._loop = False - return interp.step(ctxt) + return_value = interp.step(ctxt) + if return_value is not None: + return return_value.w_self() + return None # expose the bytecode's values as global constants. # Bytecodes that have a whole range are exposed as global functions: @@ -88,8 +91,8 @@ w_method.argsize=2 w_method.tempsize=8 w_method.setliterals([model.W_PointersObject(None, 2)]) - w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, receiver, ["foo", "bar"]) - return w_frame, w_frame.as_context_get_shadow(space) + s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, receiver, ["foo", "bar"]) + return s_frame.w_self(), s_frame def test_create_frame(): w_method = model.W_CompiledMethod(len("hello")) @@ -97,8 +100,8 @@ w_method.islarge = 1 w_method.argsize=2 w_method.tempsize=8 - w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, "receiver", ["foo", "bar"]) - s_frame = w_frame.as_context_get_shadow(space) + s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, "receiver", ["foo", "bar"]) + w_frame = s_frame.w_self() assert s_frame.w_receiver() == "receiver" assert s_frame.gettemp(0) == "foo" assert s_frame.gettemp(1) == "bar" @@ -976,7 +979,7 @@ w_method.setliterals([space.wrap_int(11)]) #create a frame for that method - w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []) + w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []).w_self() try: interp.loop(w_frame) except interpreter.ReturnFromTopLevel, e: @@ -1023,7 +1026,7 @@ w_method.setliterals([space.wrap_int(11)]) #create a frame for that method - w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []) + w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []).w_self() try: interp.loop(w_frame) except interpreter.ReturnFromTopLevel, e: diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -190,8 +190,9 @@ def test_at(): w_obj = mockclass(space, 0, varsized=True).as_class_get_shadow(space).new(1) - w_obj.store(space, 0, "foo") - assert prim(primitives.AT, [w_obj, 1]) == "foo" + foo = wrap("foo") + w_obj.store(space, 0, foo) + assert prim(primitives.AT, [w_obj, 1]) is foo def test_invalid_at(): w_obj = mockclass(space, 0).as_class_get_shadow(space).new() @@ -480,8 +481,8 @@ size_arguments, copiedValues) s_initial_context.push_all([closure] + args) interp = interpreter.Interpreter(space) - w_active_context = prim_table[primitives.CLOSURE_VALUE + size_arguments](interp, s_initial_context, size_arguments) - return s_initial_context, closure, w_active_context.as_context_get_shadow(space) + s_active_context = prim_table[primitives.CLOSURE_VALUE + size_arguments](interp, s_initial_context, size_arguments) + return s_initial_context, closure, s_active_context def test_primitive_closure_value(): s_initial_context, closure, s_new_context = build_up_closure_environment([]) diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -230,7 +230,8 @@ s_method = s_outerContext.w_method().as_compiledmethod_get_shadow(self.space) w_receiver = s_outerContext.w_receiver() w_new_frame = shadow.MethodContextShadow.make_context(self.space, s_method, w_receiver, - arguments, w_sender=w_aContext, pc=self.startpc(), closure=self) + arguments, s_sender=w_aContext.get_shadow(self.space), + pc=self.startpc(), closure=self) return w_new_frame def tempsize(self): From noreply at buildbot.pypy.org Tue Mar 5 15:54:44 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 5 Mar 2013 15:54:44 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix for _call_assembler_check_descr, the value we are comparing against might not fit into an ARM imm Message-ID: <20130305145444.C0D2F1C1043@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62087:e84f26cdbe51 Date: 2013-03-05 15:46 +0100 http://bitbucket.org/pypy/pypy/changeset/e84f26cdbe51/ Log: fix for _call_assembler_check_descr, the value we are comparing against might not fit into an ARM imm diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1124,7 +1124,11 @@ def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs) - self.mc.CMP_ri(r.ip.value, imm=value) + if check_imm_arg(value): + self.mc.CMP_ri(r.ip.value, imm=value) + else: + self.mc.gen_load_int(r.lr.value, value) + self.mc.CMP_rr(r.ip.value, r.lr.value) pos = self.mc.currpos() self.mc.BKPT() return pos From noreply at buildbot.pypy.org Tue Mar 5 15:54:46 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 5 Mar 2013 15:54:46 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130305145446.927661C1043@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62088:283351509284 Date: 2013-03-05 15:53 +0100 http://bitbucket.org/pypy/pypy/changeset/283351509284/ Log: merge heads diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -19,11 +19,6 @@ # - normal: self.sthread != None, not is_empty_handle(self.h) # - finished: self.sthread != None, is_empty_handle(self.h) - def __del__(self): - sthread = self.sthread - if sthread is not None and not sthread.is_empty_handle(self.h): - sthread.destroy(self.h) - def check_sthread(self): ec = self.space.getexecutioncontext() if ec.stacklet_thread is not self.sthread: diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -598,7 +598,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.set_frame_depth(0, 0) # for now + clt.frame_info.update_frame_depth(0, 0) # for now if False and log: operations = self._inject_debugging_code(looptoken, operations, @@ -854,7 +854,7 @@ def update_frame_depth(self, frame_depth): baseofs = self.cpu.get_baseofs_of_frame_field() - self.current_clt.frame_info.set_frame_depth(baseofs, frame_depth) + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) def write_pending_failure_recoveries(self): for tok in self.pending_guards: diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -15,9 +15,10 @@ NULLGCMAP = lltype.nullptr(GCMAP) @enforceargs(None, int, int) -def jitframeinfo_set_depth(jfi, base_ofs, new_depth): - jfi.jfi_frame_depth = new_depth - jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED +def jitframeinfo_update_depth(jfi, base_ofs, new_depth): + if new_depth > jfi.jfi_frame_depth: + jfi.jfi_frame_depth = new_depth + jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED JITFRAMEINFO_SIZE = 2 * SIZEOFSIGNED # make sure this stays correct @@ -28,7 +29,7 @@ # the total size of the frame, in bytes ('jfi_frame_size', lltype.Signed), adtmeths = { - 'set_frame_depth': jitframeinfo_set_depth, + 'update_frame_depth': jitframeinfo_update_depth, }, ) @@ -113,6 +114,9 @@ elif fld == -3: (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -4 return obj_addr + getofs('jf_guard_exc') + elif fld == -4: + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -5 + return obj_addr + getofs('jf_forward') else: if not (obj_addr + getofs('jf_gcmap')).address[0]: return llmemory.NULL # done diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -86,12 +86,13 @@ if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date - frame.jf_frame_info.set_frame_depth(base_ofs, size) + frame.jf_frame_info.update_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] + frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -296,20 +296,20 @@ assert all_addrs[counter] == frame_adr + jitframe.getofs(name) counter += 1 # gcpattern - assert all_addrs[4] == indexof(0) - assert all_addrs[5] == indexof(1) - assert all_addrs[6] == indexof(3) - assert all_addrs[7] == indexof(5) - assert all_addrs[8] == indexof(7) + assert all_addrs[5] == indexof(0) + assert all_addrs[6] == indexof(1) + assert all_addrs[7] == indexof(3) + assert all_addrs[8] == indexof(5) + assert all_addrs[9] == indexof(7) if sys.maxint == 2**31 - 1: - assert all_addrs[9] == indexof(31) - assert all_addrs[10] == indexof(33 + 32) + assert all_addrs[10] == indexof(31) + assert all_addrs[11] == indexof(33 + 32) else: - assert all_addrs[9] == indexof(63) - assert all_addrs[10] == indexof(65 + 64) + assert all_addrs[10] == indexof(63) + assert all_addrs[11] == indexof(65 + 64) - assert len(all_addrs) == 4 + 6 + 4 - # 4 static fields, 4 addresses from gcmap, 2 from gcpattern + assert len(all_addrs) == 5 + 6 + 4 + # 5 static fields, 4 addresses from gcmap, 2 from gcpattern lltype.free(frame_info, flavor='raw') lltype.free(frame.jf_gcmap, flavor='raw') 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 @@ -315,10 +315,11 @@ for ref in oldlooptoken.looptokens_redirected_to: looptoken = ref() if looptoken: - looptoken.frame_info.set_frame_depth(baseofs, + looptoken.frame_info.update_frame_depth(baseofs, new_fi.jfi_frame_depth) new_loop_tokens.append(ref) - oldlooptoken.frame_info.set_frame_depth(baseofs, new_fi.jfi_frame_depth) + oldlooptoken.frame_info.update_frame_depth(baseofs, + new_fi.jfi_frame_depth) assert oldlooptoken is not None new_loop_tokens.append(weakref.ref(oldlooptoken)) self.looptokens_redirected_to = new_loop_tokens diff --git a/rpython/jit/backend/test/test_model.py b/rpython/jit/backend/test/test_model.py --- a/rpython/jit/backend/test/test_model.py +++ b/rpython/jit/backend/test/test_model.py @@ -13,7 +13,7 @@ def __init__(self, depth): self.jfi_frame_depth = depth - def set_frame_depth(self, baseofs, newdepth): + def update_frame_depth(self, baseofs, newdepth): self.jfi_frame_depth = newdepth def test_redirect_loop_token(): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -471,7 +471,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.set_frame_depth(0, 0) # for now + clt.frame_info.update_frame_depth(0, 0) # for now if log: operations = self._inject_debugging_code(looptoken, operations, @@ -622,7 +622,7 @@ def update_frame_depth(self, frame_depth): baseofs = self.cpu.get_baseofs_of_frame_field() - self.current_clt.frame_info.set_frame_depth(baseofs, frame_depth) + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. @@ -2392,18 +2392,6 @@ not_implemented("not implemented operation (guard): %s" % op.getopname()) - def check_frame_before_jump(self, target_token): - if target_token in self.target_tokens_currently_compiling: - return - if target_token._x86_clt is self.current_clt: - return - # We can have a frame coming from god knows where that's - # passed to a jump to another loop. Make sure it has the - # correct depth - expected_size = target_token._x86_clt.frame_info.jfi_frame_depth - self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), - expected_size=expected_size) - def closing_jump(self, target_token): target = target_token._ll_loop_code if target_token in self.target_tokens_currently_compiling: 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 @@ -1238,7 +1238,6 @@ tmpreg = None xmmtmp = None # Do the remapping - assembler.check_frame_before_jump(self.jump_target_descr) remap_frame_layout_mixed(assembler, src_locations1, dst_locations1, tmpreg, src_locations2, dst_locations2, xmmtmp) diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -341,7 +341,7 @@ break obj = self.run_finalizers.popleft() finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj, llmemory.NULL) + finalizer(obj) finally: self.finalizer_lock_count -= 1 diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -940,6 +940,11 @@ def get_forwarding_address(self, obj): return llmemory.cast_adr_to_ptr(obj, FORWARDSTUBPTR).forw + def get_possibly_forwarded_type_id(self, obj): + if self.is_in_nursery(obj) and self.is_forwarded(obj): + obj = self.get_forwarding_address(obj) + return self.get_type_id(obj) + def get_total_memory_used(self): """Return the total memory used, not counting any object in the nursery: only objects in the ArenaCollection or raw-malloced. @@ -1890,7 +1895,7 @@ if not self.is_forwarded(obj): finalizer = self.getlightfinalizer(self.get_type_id(obj)) ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + finalizer(obj) else: obj = self.get_forwarding_address(obj) self.old_objects_with_light_finalizers.append(obj) @@ -1911,7 +1916,7 @@ # dying finalizer = self.getlightfinalizer(self.get_type_id(obj)) ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) + finalizer(obj) self.old_objects_with_light_finalizers.delete() self.old_objects_with_light_finalizers = new_objects diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py --- a/rpython/memory/gc/semispace.py +++ b/rpython/memory/gc/semispace.py @@ -438,6 +438,12 @@ def visit_external_object(self, obj): pass # hook for the HybridGC + def get_possibly_forwarded_type_id(self, obj): + tid = self.header(obj).tid + if self.is_forwarded(obj) and not (tid & GCFLAG_EXTERNAL): + obj = self.get_forwarding_address(obj) + return self.get_type_id(obj) + def set_forwarding_address(self, obj, newobj, objsize): # To mark an object as forwarded, we set the GCFLAG_FORWARDED and # overwrite the object with a FORWARDSTUB. Doing so is a bit @@ -494,7 +500,7 @@ new_objects.append(self.get_forwarding_address(obj)) else: finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj, llmemory.NULL) + finalizer(obj) self.objects_with_light_finalizers.delete() self.objects_with_light_finalizers = new_objects 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 @@ -139,11 +139,13 @@ if self._with_jit: jit2gc = gctransformer.translator._jit2gc self.frame_tid = jit2gc['frame_tid'] + self.gctransformer = gctransformer def need_stacklet_support(self, gctransformer, getfn): # stacklet support: BIG HACK for rlib.rstacklet from rpython.rlib import _stacklet_asmgcc _stacklet_asmgcc._asmstackrootwalker = self # as a global! argh + _stacklet_asmgcc.complete_destrptr(gctransformer) def need_thread_support(self, gctransformer, getfn): # Threads supported "out of the box" by the rest of the code. @@ -411,7 +413,7 @@ # to a JITFRAME object. from rpython.jit.backend.llsupport.jitframe import STACK_DEPTH_OFS - tid = self.gc.get_type_id(ebp_in_caller) + tid = self.gc.get_possibly_forwarded_type_id(ebp_in_caller) ll_assert(rffi.cast(lltype.Signed, tid) == rffi.cast(lltype.Signed, self.frame_tid), "found a stack frame that does not belong " diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -645,11 +645,9 @@ c_type_id = rmodel.inputconst(TYPE_ID, type_id) info = self.layoutbuilder.get_info(type_id) c_size = rmodel.inputconst(lltype.Signed, info.fixedsize) - kind_and_fptr = self.special_funcptr_for_type(TYPE) - has_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "finalizer") - has_light_finalizer = (kind_and_fptr is not None and - kind_and_fptr[0] == "light_finalizer") + fptrs = self.special_funcptr_for_type(TYPE) + has_finalizer = "finalizer" in fptrs + has_light_finalizer = "light_finalizer" in fptrs if has_light_finalizer: has_finalizer = True c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer) @@ -798,11 +796,6 @@ [self.root_walker.gc_shadowstackref_context_ptr, op.args[0]], resultvar=op.result) - def gct_gc_shadowstackref_destroy(self, hop): - op = hop.spaceop - hop.genop("direct_call", - [self.root_walker.gc_shadowstackref_destroy_ptr, op.args[0]]) - def gct_gc_save_current_state_away(self, hop): op = hop.spaceop hop.genop("direct_call", @@ -1213,8 +1206,8 @@ None) def has_light_finalizer(self, TYPE): - special = self.special_funcptr_for_type(TYPE) - return special is not None and special[0] == 'light_finalizer' + fptrs = self.special_funcptr_for_type(TYPE) + return "light_finalizer" in fptrs def has_custom_trace(self, TYPE): rtti = get_rtti(TYPE) @@ -1228,14 +1221,16 @@ destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] typename = TYPE.__name__ - def ll_finalizer(addr, ignored): + def ll_finalizer(addr): v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) - return llmemory.NULL fptr = self.transformer.annotate_finalizer(ll_finalizer, - [llmemory.Address, llmemory.Address], llmemory.Address) - g = destrptr._obj.graph - light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) + [llmemory.Address], lltype.Void) + try: + g = destrptr._obj.graph + light = not FinalizerAnalyzer(self.translator).analyze_light_finalizer(g) + except lltype.DelayedPointer: + light = False # XXX bah, too bad return fptr, light def make_custom_trace_funcptr_for_type(self, TYPE): diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -1,6 +1,7 @@ from rpython.annotator import model as annmodel from rpython.rlib.debug import ll_assert from rpython.rlib.nonconst import NonConstant +from rpython.rlib import rgc from rpython.rtyper import rmodel from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, llmemory @@ -226,10 +227,6 @@ ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) return ssref.context - def gc_shadowstackref_destroy(gcref): - ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) - shadow_stack_pool.destroy(ssref) - def gc_save_current_state_away(gcref, ncontext): ssref = lltype.cast_opaque_ptr(lltype.Ptr(SHADOWSTACKREF), gcref) shadow_stack_pool.save_current_state_away(ssref, ncontext) @@ -252,9 +249,6 @@ self.gc_shadowstackref_context_ptr = getfn(gc_shadowstackref_context, [s_gcref], s_addr, inline=True) - self.gc_shadowstackref_destroy_ptr = getfn(gc_shadowstackref_destroy, - [s_gcref], annmodel.s_None, - inline=True) self.gc_save_current_state_away_ptr = getfn(gc_save_current_state_away, [s_gcref, s_addr], annmodel.s_None, @@ -340,10 +334,6 @@ self.gcdata.root_stack_top = self.unused_full_stack self.unused_full_stack = llmemory.NULL - def destroy(self, shadowstackref): - llmemory.raw_free(shadowstackref.base) - self._cleanup(shadowstackref) - def _cleanup(self, shadowstackref): shadowstackref.base = llmemory.NULL shadowstackref.top = llmemory.NULL @@ -402,7 +392,20 @@ CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) - lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr) + + def shadowstack_destructor(shadowstackref): + from rpython.rlib import _rffi_stacklet as _c + h = shadowstackref.context + h = llmemory.cast_adr_to_ptr(h, _c.handle) + llmemory.raw_free(shadowstackref.base) + if h: + _c.destroy(h) + + destrptr = gctransformer.annotate_helper(shadowstack_destructor, + [SHADOWSTACKREFPTR], lltype.Void) + + lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr, + destrptr=destrptr) gctransformer._SHADOWSTACKREF = SHADOWSTACKREF return SHADOWSTACKREF diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -17,20 +17,22 @@ OFFSETS_TO_GC_PTR = lltype.Array(lltype.Signed) - # When used as a finalizer, the following functions only take one - # address and ignore the second, and return NULL. When used as a - # custom tracer (CT), it enumerates the addresses that contain GCREFs. + # A custom tracer (CT), enumerates the addresses that contain GCREFs. # It is called with the object as first argument, and the previous # returned address (or NULL the first time) as the second argument. - FINALIZER_OR_CT_FUNC = lltype.FuncType([llmemory.Address, - llmemory.Address], - llmemory.Address) - FINALIZER_OR_CT = lltype.Ptr(FINALIZER_OR_CT_FUNC) + FINALIZER_FUNC = lltype.FuncType([llmemory.Address], lltype.Void) + CUSTOMTRACER_FUNC = lltype.FuncType([llmemory.Address, llmemory.Address], + llmemory.Address) + FINALIZER = lltype.Ptr(FINALIZER_FUNC) + CUSTOMTRACER = lltype.Ptr(CUSTOMTRACER_FUNC) + EXTRA = lltype.Struct("type_info_extra", + ('finalizer', FINALIZER), + ('customtracer', CUSTOMTRACER)) # structure describing the layout of a typeid TYPE_INFO = lltype.Struct("type_info", ("infobits", lltype.Signed), # combination of the T_xxx consts - ("finalizer_or_customtrace", FINALIZER_OR_CT), + ("extra", lltype.Ptr(EXTRA)), ("fixedsize", lltype.Signed), ("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)), hints={'immutable': True}, @@ -80,16 +82,16 @@ def q_finalizer(self, typeid): typeinfo = self.get(typeid) if typeinfo.infobits & T_HAS_FINALIZER: - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.finalizer else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.FINALIZER_FUNC) def q_light_finalizer(self, typeid): typeinfo = self.get(typeid) if typeinfo.infobits & T_HAS_LIGHTWEIGHT_FINALIZER: - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.finalizer else: - return lltype.nullptr(GCData.FINALIZER_OR_CT_FUNC) + return lltype.nullptr(GCData.FINALIZER_FUNC) def q_offsets_to_gc_pointers(self, typeid): return self.get(typeid).ofstoptrs @@ -131,7 +133,7 @@ ll_assert(self.q_has_custom_trace(typeid), "T_HAS_CUSTOM_TRACE missing") typeinfo = self.get(typeid) - return typeinfo.finalizer_or_customtrace + return typeinfo.extra.customtracer def q_fast_path_tracing(self, typeid): # return True if none of the flags T_HAS_GCPTR_IN_VARSIZE, @@ -196,18 +198,20 @@ infobits = index info.ofstoptrs = builder.offsets2table(offsets, TYPE) # - kind_and_fptr = builder.special_funcptr_for_type(TYPE) - if kind_and_fptr is not None: - kind, fptr = kind_and_fptr - info.finalizer_or_customtrace = fptr - if kind == "finalizer": + fptrs = builder.special_funcptr_for_type(TYPE) + if fptrs: + extra = lltype.malloc(GCData.EXTRA, zero=True, immortal=True, + flavor='raw') + if "finalizer" in fptrs: + extra.finalizer = fptrs["finalizer"] infobits |= T_HAS_FINALIZER - elif kind == 'light_finalizer': + if "light_finalizer" in fptrs: + extra.finalizer = fptrs["light_finalizer"] infobits |= T_HAS_FINALIZER | T_HAS_LIGHTWEIGHT_FINALIZER - elif kind == "custom_trace": + if "custom_trace" in fptrs: + extra.customtracer = fptrs["custom_trace"] infobits |= T_HAS_CUSTOM_TRACE - else: - assert 0, kind + info.extra = extra # if not TYPE._is_varsize(): info.fixedsize = llarena.round_up_for_allocation( @@ -379,19 +383,16 @@ return self._special_funcptrs[TYPE] fptr1, is_lightweight = self.make_finalizer_funcptr_for_type(TYPE) fptr2 = self.make_custom_trace_funcptr_for_type(TYPE) - assert not (fptr1 and fptr2), ( - "type %r needs both a finalizer and a custom tracer" % (TYPE,)) + result = {} if fptr1: if is_lightweight: - kind_and_fptr = "light_finalizer", fptr1 + result["light_finalizer"] = fptr1 else: - kind_and_fptr = "finalizer", fptr1 - elif fptr2: - kind_and_fptr = "custom_trace", fptr2 - else: - kind_and_fptr = None - self._special_funcptrs[TYPE] = kind_and_fptr - return kind_and_fptr + result["finalizer"] = fptr1 + if fptr2: + result["custom_trace"] = fptr2 + self._special_funcptrs[TYPE] = result + return result def make_finalizer_funcptr_for_type(self, TYPE): # must be overridden for proper finalizer support diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -216,16 +216,14 @@ t = self.llinterp.typer.annotator.translator light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) - def ll_finalizer(addr, dummy): - assert dummy == llmemory.NULL + def ll_finalizer(addr): try: v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) self.llinterp.eval_graph(destrgraph, [v], recursive=True) except llinterp.LLException: raise RuntimeError( "a finalizer raised an exception, shouldn't happen") - return llmemory.NULL - return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light + return llhelper(gctypelayout.GCData.FINALIZER, ll_finalizer), light def make_custom_trace_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti diff --git a/rpython/rlib/_rffi_stacklet.py b/rpython/rlib/_rffi_stacklet.py --- a/rpython/rlib/_rffi_stacklet.py +++ b/rpython/rlib/_rffi_stacklet.py @@ -56,9 +56,9 @@ new = llexternal('stacklet_new', [thread_handle, run_fn, llmemory.Address], handle, random_effects_on_gcobjs=True) -switch = llexternal('stacklet_switch', [thread_handle, handle], handle, +switch = llexternal('stacklet_switch', [handle], handle, random_effects_on_gcobjs=True) -destroy = llexternal('stacklet_destroy', [thread_handle, handle], lltype.Void) +destroy = llexternal('stacklet_destroy', [handle], lltype.Void) _translate_pointer = llexternal("_stacklet_translate_pointer", [llmemory.Address, llmemory.Address], diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -1,8 +1,9 @@ -from rpython.rlib import _rffi_stacklet as _c from rpython.rlib.debug import ll_assert from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.annlowlevel import llhelper +from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator +from rpython.annotator import model as annmodel +from rpython.rlib import _rffi_stacklet as _c _asmstackrootwalker = None # BIG HACK: monkey-patched by asmgcroot.py @@ -129,11 +130,26 @@ return _stackletrootwalker get_stackletrootwalker._annspecialcase_ = 'specialize:memo' +def complete_destrptr(gctransformer): + translator = gctransformer.translator + mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) + args_s = [annmodel.lltype_to_annotation(lltype.Ptr(SUSPSTACK))] + s_result = annmodel.s_None + destrptr = mixlevelannotator.delayedfunction(suspstack_destructor, + args_s, s_result) + mixlevelannotator.finish() + lltype.attachRuntimeTypeInfo(SUSPSTACK, destrptr=destrptr) + def customtrace(obj, prev): stackletrootwalker = get_stackletrootwalker() return stackletrootwalker.next(obj, prev) +def suspstack_destructor(suspstack): + h = suspstack.handle + if h: + _c.destroy(h) + SUSPSTACK = lltype.GcStruct('SuspStack', ('handle', _c.handle), @@ -169,7 +185,7 @@ # stacklet with stacklet_new(). If this call fails, then we # are just returning NULL. _stack_just_closed() - return _c.new(gcrootfinder.thrd, llhelper(_c.run_fn, _new_runfn), + return _c.new(gcrootfinder.newthrd, llhelper(_c.run_fn, _new_runfn), llmemory.NULL) def _stack_just_closed(): @@ -216,7 +232,7 @@ # # gcrootfinder.suspstack.anchor is left with the anchor of the # previous place (i.e. before the call to switch()). - h2 = _c.switch(gcrootfinder.thrd, h) + h2 = _c.switch(h) # if not h2: # MemoryError: restore gcrootfinder.suspstack.anchor = oldanchor @@ -228,7 +244,7 @@ suspstack = NULL_SUSPSTACK def new(self, thrd, callback, arg): - self.thrd = thrd._thrd + self.newthrd = thrd._thrd self.runfn = callback self.arg = arg # make a fresh new clean SUSPSTACK @@ -240,8 +256,7 @@ alternateanchor) return self.get_result_suspstack(h) - def switch(self, thrd, suspstack): - self.thrd = thrd._thrd + def switch(self, suspstack): self.suspstack = suspstack h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _switch_callback), alternateanchor) @@ -267,11 +282,6 @@ # This is a return that gave us a real handle. Store it. return self.attach_handle_on_suspstack(h) - def destroy(self, thrd, suspstack): - h = suspstack.handle - suspstack.handle = _c.null_handle - _c.destroy(thrd._thrd, h) - def is_empty_handle(self, suspstack): return not suspstack diff --git a/rpython/rlib/_stacklet_shadowstack.py b/rpython/rlib/_stacklet_shadowstack.py --- a/rpython/rlib/_stacklet_shadowstack.py +++ b/rpython/rlib/_stacklet_shadowstack.py @@ -79,25 +79,18 @@ return get_result_suspstack(h) new._dont_inline_ = True - def switch(thrd, suspstack): + def switch(suspstack): # suspstack has a handle to target, i.e. where to switch to ll_assert(suspstack != gcrootfinder.oldsuspstack, "stacklet: invalid use") gcrootfinder.newsuspstack = suspstack - thread_handle = thrd._thrd h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) h = llmemory.cast_adr_to_ptr(h, _c.handle) prepare_old_suspstack() - h = _c.switch(thread_handle, h) + h = _c.switch(h) return get_result_suspstack(h) switch._dont_inline_ = True - def destroy(thrd, suspstack): - h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) - h = llmemory.cast_adr_to_ptr(h, _c.handle) - llop.gc_shadowstackref_destroy(lltype.Void, suspstack) - _c.destroy(thrd._thrd, h) - def is_empty_handle(suspstack): return not suspstack diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py --- a/rpython/rlib/rstacklet.py +++ b/rpython/rlib/rstacklet.py @@ -34,17 +34,11 @@ def switch(self, stacklet): if DEBUG: debug.remove(stacklet) - h = self._gcrootfinder.switch(self, stacklet) + h = self._gcrootfinder.switch(stacklet) if DEBUG: debug.add(h) return h - @jit.dont_look_inside - def destroy(self, stacklet): - if DEBUG: - debug.remove(stacklet) - self._gcrootfinder.destroy(self, stacklet) - def is_empty_handle(self, stacklet): # note that "being an empty handle" and being equal to # "get_null_handle()" may be the same, or not; don't rely on it diff --git a/rpython/rlib/test/test_rstacklet.py b/rpython/rlib/test/test_rstacklet.py --- a/rpython/rlib/test/test_rstacklet.py +++ b/rpython/rlib/test/test_rstacklet.py @@ -6,7 +6,7 @@ except CompilationError, e: py.test.skip("cannot import rstacklet: %s" % e) -from rpython.rlib import rrandom +from rpython.rlib import rrandom, rgc from rpython.rlib.rarithmetic import intmask from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.c.test.test_standalone import StandaloneTests @@ -72,7 +72,9 @@ self.status = 0 h = self.sthread.new(switchbackonce_callback, rffi.cast(llmemory.Address, 321)) - self.sthread.destroy(h) + # 'h' ignored + if (i % 5000) == 2500: + rgc.collect() def any_alive(self): for task in self.tasks: diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -890,8 +890,6 @@ raise NotImplementedError("gc_shadowstackref_new") def op_gc_shadowstackref_context(self): raise NotImplementedError("gc_shadowstackref_context") - def op_gc_shadowstackref_destroy(self): - raise NotImplementedError("gc_shadowstackref_destroy") def op_gc_save_current_state_away(self): raise NotImplementedError("gc_save_current_state_away") def op_gc_forget_current_state(self): diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -518,7 +518,6 @@ # for stacklet+shadowstack support 'gc_shadowstackref_new': LLOp(canmallocgc=True), 'gc_shadowstackref_context': LLOp(), - 'gc_shadowstackref_destroy': LLOp(), 'gc_save_current_state_away': LLOp(), 'gc_forget_current_state': LLOp(), 'gc_restore_state_from': LLOp(), diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py --- a/rpython/translator/c/gc.py +++ b/rpython/translator/c/gc.py @@ -313,19 +313,19 @@ def struct_setup(self, structdefnode, rtti): if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): - destrptr = rtti._obj.destructor_funcptr + gctransf = self.db.gctransformer + TYPE = structdefnode.STRUCT + fptrs = gctransf.special_funcptr_for_type(TYPE) # make sure this is seen by the database early, i.e. before # finish_helpers() on the gctransformer + destrptr = rtti._obj.destructor_funcptr self.db.get(destrptr) # the following, on the other hand, will only discover ll_finalizer # helpers. The get() sees and records a delayed pointer. It is # still important to see it so that it can be followed as soon as # the mixlevelannotator resolves it. - gctransf = self.db.gctransformer - TYPE = structdefnode.STRUCT - kind_and_fptr = gctransf.special_funcptr_for_type(TYPE) - if kind_and_fptr: - self.db.get(kind_and_fptr[1]) + for fptr in fptrs.values(): + self.db.get(fptr) def array_setup(self, arraydefnode): pass diff --git a/rpython/translator/c/src/stacklet/stacklet.c b/rpython/translator/c/src/stacklet/stacklet.c --- a/rpython/translator/c/src/stacklet/stacklet.c +++ b/rpython/translator/c/src/stacklet/stacklet.c @@ -52,6 +52,8 @@ * main stack. */ struct stacklet_s *stack_prev; + + stacklet_thread_handle stack_thrd; /* the thread where the stacklet is */ }; void *(*_stacklet_switchstack)(void*(*)(void*, void*), @@ -132,6 +134,7 @@ stacklet->stack_stop = thrd->g_current_stack_stop; stacklet->stack_saved = 0; stacklet->stack_prev = thrd->g_stack_chain_head; + stacklet->stack_thrd = thrd; thrd->g_stack_chain_head = stacklet; return 0; } @@ -293,10 +296,10 @@ return thrd->g_source; } -stacklet_handle stacklet_switch(stacklet_thread_handle thrd, - stacklet_handle target) +stacklet_handle stacklet_switch(stacklet_handle target) { long stackmarker; + stacklet_thread_handle thrd = target->stack_thrd; if (thrd->g_current_stack_stop <= (char *)&stackmarker) thrd->g_current_stack_stop = ((char *)&stackmarker) + 1; @@ -305,15 +308,23 @@ return thrd->g_source; } -void stacklet_destroy(stacklet_thread_handle thrd, stacklet_handle target) +void stacklet_destroy(stacklet_handle target) { - /* remove 'target' from the chained list 'unsaved_stack', if it is there */ - struct stacklet_s **pp = &thrd->g_stack_chain_head; - for (; *pp != NULL; pp = &(*pp)->stack_prev) - if (*pp == target) { - *pp = target->stack_prev; - break; - } + if (target->stack_prev != NULL) { + /* 'target' appears to be in the chained list 'unsaved_stack', + so remove it from there. Note that if 'thrd' was already + deleted, it means that we left the thread and all stacklets + still in the thread should be fully copied away from the + stack --- so should have stack_prev == NULL. In this case + we don't even read 'stack_thrd', already deallocated. */ + stacklet_thread_handle thrd = target->stack_thrd; + struct stacklet_s **pp = &thrd->g_stack_chain_head; + for (; *pp != NULL; pp = &(*pp)->stack_prev) + if (*pp == target) { + *pp = target->stack_prev; + break; + } + } free(target); } diff --git a/rpython/translator/c/src/stacklet/stacklet.h b/rpython/translator/c/src/stacklet/stacklet.h --- a/rpython/translator/c/src/stacklet/stacklet.h +++ b/rpython/translator/c/src/stacklet/stacklet.h @@ -44,13 +44,12 @@ * Don't call this with an already-used target, with EMPTY_STACKLET_HANDLE, * or with a stack handle from another thread (in multithreaded apps). */ -stacklet_handle stacklet_switch(stacklet_thread_handle thrd, - stacklet_handle target); +stacklet_handle stacklet_switch(stacklet_handle target); /* Delete a stack handle without resuming it at all. * (This works even if the stack handle is of a different thread) */ -void stacklet_destroy(stacklet_thread_handle thrd, stacklet_handle target); +void stacklet_destroy(stacklet_handle target); /* stacklet_handle _stacklet_switch_to_copy(stacklet_handle) --- later */ From noreply at buildbot.pypy.org Tue Mar 5 15:55:15 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:55:15 +0100 (CET) Subject: [pypy-commit] pypy improve-docs: Remove index-of-release-notes.rst. Message-ID: <20130305145515.DF07F1C1043@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: improve-docs Changeset: r62089:5b033c639ac9 Date: 2013-03-05 15:52 +0100 http://bitbucket.org/pypy/pypy/changeset/5b033c639ac9/ Log: Remove index-of-release-notes.rst. diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst deleted file mode 100644 --- a/pypy/doc/index-of-release-notes.rst +++ /dev/null @@ -1,19 +0,0 @@ -Historical release notes ------------------------- - -.. toctree:: - - release-0.6 - release-0.7.0.rst - release-0.8.0.rst - release-0.9.0.rst - release-0.99.0.rst - release-1.0.0.rst - release-1.1.0.rst - release-1.2.0.rst - release-1.3.0.rst - release-1.4.0.rst - release-1.4.0beta.rst - release-1.4.1.rst - release-1.5.0.rst - release-1.6.0.rst diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -401,7 +401,7 @@ jit/overview.rst jit/pyjitpl5.rst - index-of-release-notes.rst + releases/index.rst ctypes-implementation.rst From noreply at buildbot.pypy.org Tue Mar 5 15:55:17 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Tue, 5 Mar 2013 15:55:17 +0100 (CET) Subject: [pypy-commit] pypy improve-docs: Make the header a header. Message-ID: <20130305145517.11C531C1043@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: improve-docs Changeset: r62090:a491db813f8b Date: 2013-03-05 15:54 +0100 http://bitbucket.org/pypy/pypy/changeset/a491db813f8b/ Log: Make the header a header. diff --git a/pypy/doc/releases/0.6.rst b/pypy/doc/releases/0.6.rst --- a/pypy/doc/releases/0.6.rst +++ b/pypy/doc/releases/0.6.rst @@ -1,5 +1,5 @@ The PyPy 0.6 release --------------------- +==================== *The PyPy Development Team is happy to announce the first public release of PyPy after two years of spare-time and From noreply at buildbot.pypy.org Tue Mar 5 16:19:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 5 Mar 2013 16:19:49 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a bit more consistent debug checking of frame depth Message-ID: <20130305151949.7DFA61C1017@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62091:8186fc9d56d0 Date: 2013-03-05 17:18 +0200 http://bitbucket.org/pypy/pypy/changeset/8186fc9d56d0/ Log: a bit more consistent debug checking of frame depth diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -103,6 +103,9 @@ print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO) + def realloc_frame_crash(frame, size): + print "frame", frame, "size", size + if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) else: @@ -115,6 +118,18 @@ mixlevelann.finish() self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + if not translate_support_code: + fptr = llhelper(FUNC_TP, realloc_frame_crash) + else: + FUNC = FUNC_TP.TO + args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] + s_result = annmodel.lltype_to_annotation(FUNC.RESULT) + mixlevelann = MixLevelHelperAnnotator(self.rtyper) + graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) + fptr = mixlevelann.graph2delayed(graph, FUNC) + mixlevelann.finish() + self.realloc_frame_crash = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + def _setup_exception_handling_untranslated(self): # for running un-translated only, all exceptions occurring in the # llinterpreter are stored in '_exception_emulator', which is then diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -51,6 +51,8 @@ _output_loop_log = None _second_tmp_reg = ecx + DEBUG_FRAME_DEPTH = True + def __init__(self, cpu, translate_support_code=False): BaseAssembler.__init__(self, cpu, translate_support_code) self.verbose = False @@ -92,6 +94,7 @@ self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) self.target_tokens_currently_compiling = {} + self.frame_depth_to_patch = [] def teardown(self): self.pending_guard_tokens = None @@ -480,6 +483,7 @@ regalloc = RegAlloc(self, self.cpu.translate_support_code) # self._call_header_with_stack_check() + self._check_frame_depth_debug(self.mc) operations = regalloc.prepare_loop(inputargs, operations, looptoken, clt.allgcrefs) looppos = self.mc.get_relative_pos() @@ -492,6 +496,8 @@ full_size = self.mc.get_relative_pos() # rawstart = self.materialize_loop(looptoken) + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, + rawstart) looptoken._ll_loop_code = looppos + rawstart debug_start("jit-backend-addr") debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( @@ -539,14 +545,15 @@ operations, self.current_clt.allgcrefs, self.current_clt.frame_info) - stack_check_patch_ofs, ofs2 = self._check_frame_depth(self.mc, - regalloc.get_gcmap()) + self._check_frame_depth(self.mc, regalloc.get_gcmap()) frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() self.write_pending_failure_recoveries() fullsize = self.mc.get_relative_pos() # rawstart = self.materialize_loop(original_loop_token) + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, + rawstart) debug_start("jit-backend-addr") debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % (r_uint(descr_number), r_uint(rawstart), @@ -558,8 +565,6 @@ ops_offset = self.mc.ops_offset frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) - self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth) - self._patch_stackadjust(ofs2 + rawstart, frame_depth) self.fixup_target_tokens(rawstart) self.update_frame_depth(frame_depth) self.teardown() @@ -624,6 +629,10 @@ baseofs = self.cpu.get_baseofs_of_frame_field() self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) + def patch_stack_checks(self, framedepth, rawstart): + for ofs in self.frame_depth_to_patch: + self._patch_frame_depth(ofs + rawstart, framedepth) + def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. @@ -650,9 +659,33 @@ offset = mc.get_relative_pos() - jg_location assert 0 < offset <= 127 mc.overwrite(jg_location-1, chr(offset)) - return stack_check_cmp_ofs, ofs2 + self.frame_depth_to_patch.append(stack_check_cmp_ofs) + self.frame_depth_to_patch.append(ofs2) - def _patch_stackadjust(self, adr, allocated_depth): + def _check_frame_depth_debug(self, mc): + """ double check the depth size. It prints the error (and potentially + segfaults later) + """ + if not self.DEBUG_FRAME_DEPTH: + return + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + mc.CMP_bi(ofs, 0xffffff) + stack_check_cmp_ofs = mc.get_relative_pos() - 4 + mc.J_il8(rx86.Conditions['GE'], 0) + jg_location = mc.get_relative_pos() + mc.MOV_rr(edi.value, ebp.value) + mc.MOV_ri(esi.value, 0xffffff) + ofs2 = mc.get_relative_pos() - 4 + mc.CALL(imm(self.cpu.realloc_frame_crash)) + # patch the JG above + offset = mc.get_relative_pos() - jg_location + assert 0 < offset <= 127 + mc.overwrite(jg_location-1, chr(offset)) + self.frame_depth_to_patch.append(stack_check_cmp_ofs) + self.frame_depth_to_patch.append(ofs2) + + def _patch_frame_depth(self, adr, allocated_depth): mc = codebuf.MachineCodeBlockWrapper() mc.writeimm32(allocated_depth) mc.copy_to_raw_memory(adr) @@ -2401,7 +2434,7 @@ self.mc.JMP(imm(target)) def label(self): - pass + self._check_frame_depth_debug(self.mc) def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): assert size & (WORD-1) == 0 # must be correctly aligned From noreply at buildbot.pypy.org Tue Mar 5 16:19:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 5 Mar 2013 16:19:50 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130305151950.A6A581C1028@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62092:df11e8a3cf82 Date: 2013-03-05 17:19 +0200 http://bitbucket.org/pypy/pypy/changeset/df11e8a3cf82/ Log: merge diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1124,7 +1124,11 @@ def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs) - self.mc.CMP_ri(r.ip.value, imm=value) + if check_imm_arg(value): + self.mc.CMP_ri(r.ip.value, imm=value) + else: + self.mc.gen_load_int(r.lr.value, value) + self.mc.CMP_rr(r.ip.value, r.lr.value) pos = self.mc.currpos() self.mc.BKPT() return pos From noreply at buildbot.pypy.org Tue Mar 5 16:21:18 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 5 Mar 2013 16:21:18 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix this test file Message-ID: <20130305152118.3CAFF1C1017@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62093:228109535a0e Date: 2013-03-05 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/228109535a0e/ Log: fix this test file diff --git a/rpython/jit/backend/x86/tool/test/test_viewcode.py b/rpython/jit/backend/x86/tool/test/test_viewcode.py --- a/rpython/jit/backend/x86/tool/test/test_viewcode.py +++ b/rpython/jit/backend/x86/tool/test/test_viewcode.py @@ -1,6 +1,6 @@ from cStringIO import StringIO -from rpython.jit.backend.x86.tool.viewcode import format_code_dump_with_labels -from rpython.jit.backend.x86.tool.viewcode import find_objdump +from rpython.jit.backend.tool.viewcode import format_code_dump_with_labels +from rpython.jit.backend.tool.viewcode import find_objdump import os import py import tempfile From noreply at buildbot.pypy.org Tue Mar 5 16:44:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 5 Mar 2013 16:44:35 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the annotation Message-ID: <20130305154435.B705D1C029E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62094:e92223a62bde Date: 2013-03-05 17:44 +0200 http://bitbucket.org/pypy/pypy/changeset/e92223a62bde/ Log: fix the annotation diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -105,6 +105,7 @@ def realloc_frame_crash(frame, size): print "frame", frame, "size", size + return lltype.nullptr(llmemory.GCREF.TO) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) From noreply at buildbot.pypy.org Tue Mar 5 16:48:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 5 Mar 2013 16:48:41 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: raw malloc is not zeroed Message-ID: <20130305154841.7EBB51C101B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62095:157864d68fa3 Date: 2013-03-05 17:48 +0200 http://bitbucket.org/pypy/pypy/changeset/157864d68fa3/ Log: raw malloc is not zeroed diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -598,7 +598,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.update_frame_depth(0, 0) # for now + clt.frame_info.clear() # for now if False and log: operations = self._inject_debugging_code(looptoken, operations, diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -20,6 +20,10 @@ jfi.jfi_frame_depth = new_depth jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED +def jitframeinfo_clear(jfi): + jfi.jfi_frame_size = 0 + jfi.jfi_frame_depth = 0 + JITFRAMEINFO_SIZE = 2 * SIZEOFSIGNED # make sure this stays correct JITFRAMEINFO = lltype.Struct( @@ -30,6 +34,7 @@ ('jfi_frame_size', lltype.Signed), adtmeths = { 'update_frame_depth': jitframeinfo_update_depth, + 'clear': jitframeinfo_clear, }, ) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -474,7 +474,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.update_frame_depth(0, 0) # for now + clt.frame_info.clear() # for now if log: operations = self._inject_debugging_code(looptoken, operations, From noreply at buildbot.pypy.org Tue Mar 5 19:34:33 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 5 Mar 2013 19:34:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: update get_gcmap Message-ID: <20130305183433.0F1031C104B@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62096:eaa83da7cec2 Date: 2013-03-05 19:27 +0100 http://bitbucket.org/pypy/pypy/changeset/eaa83da7cec2/ Log: update get_gcmap diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -32,6 +32,7 @@ from rpython.jit.backend.llsupport.descr import unpack_arraydescr from rpython.jit.backend.llsupport.descr import unpack_fielddescr from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr +from rpython.rlib.rarithmetic import r_longlong, r_uint # xxx hack: set a default value for TargetToken._ll_loop_code. If 0, we know @@ -341,14 +342,14 @@ for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: continue - if box.type == REF and self.fm.stays_alive(box): + if box.type == REF and self.rm.is_still_alive(box): assert not noregs - assert isinstance(loc, RegLoc) - val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] + assert loc.is_reg() + val = loc.value gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): - if box.type == REF and self.fm.stays_alive(box): - assert isinstance(loc, StackLoc) + if box.type == REF and self.rm.is_still_alive(box): + assert loc.is_stack() val = loc.value // WORD gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for i in range(len(gcmap)): From noreply at buildbot.pypy.org Tue Mar 5 19:34:34 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 5 Mar 2013 19:34:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130305183434.6C6281C104B@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62097:2f6787b0601f Date: 2013-03-05 19:32 +0100 http://bitbucket.org/pypy/pypy/changeset/2f6787b0601f/ Log: merge heads diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -598,7 +598,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.update_frame_depth(0, 0) # for now + clt.frame_info.clear() # for now if False and log: operations = self._inject_debugging_code(looptoken, operations, diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -20,6 +20,10 @@ jfi.jfi_frame_depth = new_depth jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED +def jitframeinfo_clear(jfi): + jfi.jfi_frame_size = 0 + jfi.jfi_frame_depth = 0 + JITFRAMEINFO_SIZE = 2 * SIZEOFSIGNED # make sure this stays correct JITFRAMEINFO = lltype.Struct( @@ -30,6 +34,7 @@ ('jfi_frame_size', lltype.Signed), adtmeths = { 'update_frame_depth': jitframeinfo_update_depth, + 'clear': jitframeinfo_clear, }, ) diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -103,6 +103,10 @@ print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO) + def realloc_frame_crash(frame, size): + print "frame", frame, "size", size + return lltype.nullptr(llmemory.GCREF.TO) + if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) else: @@ -115,6 +119,18 @@ mixlevelann.finish() self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + if not translate_support_code: + fptr = llhelper(FUNC_TP, realloc_frame_crash) + else: + FUNC = FUNC_TP.TO + args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] + s_result = annmodel.lltype_to_annotation(FUNC.RESULT) + mixlevelann = MixLevelHelperAnnotator(self.rtyper) + graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) + fptr = mixlevelann.graph2delayed(graph, FUNC) + mixlevelann.finish() + self.realloc_frame_crash = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + def _setup_exception_handling_untranslated(self): # for running un-translated only, all exceptions occurring in the # llinterpreter are stored in '_exception_emulator', which is then diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -51,6 +51,8 @@ _output_loop_log = None _second_tmp_reg = ecx + DEBUG_FRAME_DEPTH = True + def __init__(self, cpu, translate_support_code=False): BaseAssembler.__init__(self, cpu, translate_support_code) self.verbose = False @@ -92,6 +94,7 @@ self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) self.target_tokens_currently_compiling = {} + self.frame_depth_to_patch = [] def teardown(self): self.pending_guard_tokens = None @@ -471,7 +474,7 @@ jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) clt.allgcrefs = [] - clt.frame_info.update_frame_depth(0, 0) # for now + clt.frame_info.clear() # for now if log: operations = self._inject_debugging_code(looptoken, operations, @@ -480,6 +483,7 @@ regalloc = RegAlloc(self, self.cpu.translate_support_code) # self._call_header_with_stack_check() + self._check_frame_depth_debug(self.mc) operations = regalloc.prepare_loop(inputargs, operations, looptoken, clt.allgcrefs) looppos = self.mc.get_relative_pos() @@ -492,6 +496,8 @@ full_size = self.mc.get_relative_pos() # rawstart = self.materialize_loop(looptoken) + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, + rawstart) looptoken._ll_loop_code = looppos + rawstart debug_start("jit-backend-addr") debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( @@ -539,14 +545,15 @@ operations, self.current_clt.allgcrefs, self.current_clt.frame_info) - stack_check_patch_ofs, ofs2 = self._check_frame_depth(self.mc, - regalloc.get_gcmap()) + self._check_frame_depth(self.mc, regalloc.get_gcmap()) frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() self.write_pending_failure_recoveries() fullsize = self.mc.get_relative_pos() # rawstart = self.materialize_loop(original_loop_token) + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, + rawstart) debug_start("jit-backend-addr") debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % (r_uint(descr_number), r_uint(rawstart), @@ -558,8 +565,6 @@ ops_offset = self.mc.ops_offset frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) - self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth) - self._patch_stackadjust(ofs2 + rawstart, frame_depth) self.fixup_target_tokens(rawstart) self.update_frame_depth(frame_depth) self.teardown() @@ -624,6 +629,10 @@ baseofs = self.cpu.get_baseofs_of_frame_field() self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) + def patch_stack_checks(self, framedepth, rawstart): + for ofs in self.frame_depth_to_patch: + self._patch_frame_depth(ofs + rawstart, framedepth) + def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. @@ -650,9 +659,33 @@ offset = mc.get_relative_pos() - jg_location assert 0 < offset <= 127 mc.overwrite(jg_location-1, chr(offset)) - return stack_check_cmp_ofs, ofs2 + self.frame_depth_to_patch.append(stack_check_cmp_ofs) + self.frame_depth_to_patch.append(ofs2) - def _patch_stackadjust(self, adr, allocated_depth): + def _check_frame_depth_debug(self, mc): + """ double check the depth size. It prints the error (and potentially + segfaults later) + """ + if not self.DEBUG_FRAME_DEPTH: + return + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + mc.CMP_bi(ofs, 0xffffff) + stack_check_cmp_ofs = mc.get_relative_pos() - 4 + mc.J_il8(rx86.Conditions['GE'], 0) + jg_location = mc.get_relative_pos() + mc.MOV_rr(edi.value, ebp.value) + mc.MOV_ri(esi.value, 0xffffff) + ofs2 = mc.get_relative_pos() - 4 + mc.CALL(imm(self.cpu.realloc_frame_crash)) + # patch the JG above + offset = mc.get_relative_pos() - jg_location + assert 0 < offset <= 127 + mc.overwrite(jg_location-1, chr(offset)) + self.frame_depth_to_patch.append(stack_check_cmp_ofs) + self.frame_depth_to_patch.append(ofs2) + + def _patch_frame_depth(self, adr, allocated_depth): mc = codebuf.MachineCodeBlockWrapper() mc.writeimm32(allocated_depth) mc.copy_to_raw_memory(adr) @@ -2401,7 +2434,7 @@ self.mc.JMP(imm(target)) def label(self): - pass + self._check_frame_depth_debug(self.mc) def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): assert size & (WORD-1) == 0 # must be correctly aligned diff --git a/rpython/jit/backend/x86/tool/test/test_viewcode.py b/rpython/jit/backend/x86/tool/test/test_viewcode.py --- a/rpython/jit/backend/x86/tool/test/test_viewcode.py +++ b/rpython/jit/backend/x86/tool/test/test_viewcode.py @@ -1,6 +1,6 @@ from cStringIO import StringIO -from rpython.jit.backend.x86.tool.viewcode import format_code_dump_with_labels -from rpython.jit.backend.x86.tool.viewcode import find_objdump +from rpython.jit.backend.tool.viewcode import format_code_dump_with_labels +from rpython.jit.backend.tool.viewcode import find_objdump import os import py import tempfile From noreply at buildbot.pypy.org Tue Mar 5 20:54:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 20:54:13 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: py3k status update #10 Message-ID: <20130305195413.B9F761C1028@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: extradoc Changeset: r4950:7d6dec5e6567 Date: 2013-03-05 11:51 -0800 http://bitbucket.org/pypy/extradoc/changeset/7d6dec5e6567/ Log: py3k status update #10 diff --git a/blog/draft/py3k-status-update-10.rst b/blog/draft/py3k-status-update-10.rst new file mode 100644 --- /dev/null +++ b/blog/draft/py3k-status-update-10.rst @@ -0,0 +1,97 @@ +Py3k status update #10 +---------------------- + +This is the tenth status update about our work on the `py3k branch`_, which we +can work on thanks to all of the people who donated_ to the `py3k proposal`_. + +There's been significant progress since the last update: the `linux x86-32 +buildbot`_ now passes 289 out of approximately 354 modules (with 39 skips) of +CPython's regression test suite. + +That means there's only 26 test module failures left! The list of major items +remaining for 3.2 compatibility are now short enough to list here, with their +related tests: + +* Tokenizer support for non-ascii identifiers + + - test_importlib + - test_pep263 + +* memoryview (Manuel Jacob's tackling this on the `py3k-memoryview branch`_) + + - test_memoryview + +* multiprocessing module currently deadlocks + + - test_multiprocessing + +* Buggy handling of the new extended unpacking syntax by the compiler: + + - test_unpack_ex + +* The new Global Interpreter Lock and new thread signal handling + + - test_threading + - test_threadsignals + - test_sys + +* Upgrade unicodedata to 6.0.0 (requires updates to the actual unicodedata + generation script) + + - test_ucn + - test_unicode + - test_unicodedata + +* `CPyExt`_ + + - test_capi (currently crashes) + +* Update int's hash code to match to CPython (float's is already updated on the + `py3k-newhash branch`_. note that PyPy 2.x doesn't even totally match + CPython's hashing) + + - test_decimal + - test_fractions + - test_numeric_tower + +* Miscellaneous: + + - test_complex + - test_float + - test_peepholer + - test_range + - test_sqlite (a new cffi based version seems to be coming) + - test_ssl + - test_struct + - test_subprocess + - test_sys_settrace + - test_time + +Additionally there are still a number of failures in PyPy's internal test +suite. These tests are usually ran against untranslated versions of PyPy during +development. However we've now began running them against a fully translated +version of PyPy on the buildbot too (thanks to Amaury for setting this +up). This further ensures that our tests and implementation are sane. + +We're getting closer to producing an initial alpha release. Before that happens +we'd like to see: + +* further test fixes +* the results of test runs on other major platforms (e.g. linux x86-64 and osx + seem to have some additional failures as of now) +* some basic real world testing + +Finally I'd like to thank Manuel Jacob for his various contributions over the +past month, including fixing the array and ctypes modules among other things, +and also Amaury Forgeot d'Arc for his ongoing excellent contributions. + +cheers, +Phil + +.. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html +.. _`py3k proposal`: http://pypy.org/py3donate.html +.. _`py3k branch`: https://bitbucket.org/pypy/pypy/commits/all/tip/branch%28%22py3k%22%29 +.. _`CPyExt`: http://morepypy.blogspot.com/2010/04/using-cpython-extension-modules-with.html +.. _`linux x86-32 buildbot`: http://buildbot.pypy.org/summary?branch=py3k +.. _`py3k-memoryview branch`: https://bitbucket.org/pypy/pypy/compare/py3k-memoryview..py3k +.. _`py3k-newhash branch`: https://bitbucket.org/pypy/pypy/compare/py3k-newhash..py3k From noreply at buildbot.pypy.org Tue Mar 5 22:08:24 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Mar 2013 22:08:24 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup Message-ID: <20130305210824.6DCE21C029E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62098:29351d829411 Date: 2013-03-05 13:06 -0800 http://bitbucket.org/pypy/pypy/changeset/29351d829411/ Log: cleanup diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -216,10 +216,7 @@ # app-level, very different from rpython.rlib.objectmodel.we_are_translated return hasattr(sys, 'pypy_translation_info') -if 'nt' in sys.builtin_module_names: - IS_WINDOWS = True -else: - IS_WINDOWS = False +IS_WINDOWS = 'nt' in sys.builtin_module_names def setup_and_fix_paths(ignore_environment=False, **extra): import os @@ -473,7 +470,7 @@ unbuffered, ignore_environment, **ignored): - # with PyPy in top of CPython we can only have around 100 + # with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler package if '__pypy__' not in sys.builtin_module_names: sys.setrecursionlimit(5000) From noreply at buildbot.pypy.org Tue Mar 5 22:17:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 5 Mar 2013 22:17:08 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: rework numpypy status report, add a mention of bdk's work Message-ID: <20130305211708.0BF5C1C029E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: extradoc Changeset: r4951:b4d02bc86843 Date: 2013-03-05 23:16 +0200 http://bitbucket.org/pypy/extradoc/changeset/b4d02bc86843/ Log: rework numpypy status report, add a mention of bdk's work diff --git a/blog/draft/numpy-status-update-6.rst b/blog/draft/numpy-status-update-6.rst --- a/blog/draft/numpy-status-update-6.rst +++ b/blog/draft/numpy-status-update-6.rst @@ -1,12 +1,13 @@ NumPy status update #6 ---------------------- -This is status report on PyPy's NumPyPy project. +An update, and some good news First the update: -* **dtype support** - NumPy on PyPy now supports all the numeric dtypes in numpy, - including non-native storage formats, longdouble, clongdouble and friends. +* **dtype support** - NumPy on PyPy now supports non-native storage formats. + Due to a lack of true support for longdoubles in rpython, we decided to back + out the support of longdouble-as-double which was misleading. * **missing ndarray attributes** - work has been made toward supporting the complete set of attributes @@ -18,14 +19,16 @@ * There has been some work on exposing FFI routines in numpypy. -More importantly, we're closing on being able to run the pure-python part of -numpy without modifications. This is not getting us close to passing all -the tests, but it's a good start. +* Brian Kearns has made progress in mapping translated _numpypy submodules to + the numpy core c-based submodules, furthering the goal of being able to install + numpy as a pure-python module with few modifications. -The most important part is the funding. While we managed to get a significant -amount of money in donations, we only managed to spend around $10 000 from it -so far. We have issued a call for additional developers, and hope to be able to -report on speedier progress soon. +And now the good news: + +While our funding drive over 2012 did not reach our goal, we still managed to +raise a fair amount of money in donations. So far we only managed to spend around $10 000 of it. +We issued a call for additional developers, and are glad to welcome ___________ +to the numpypy team. Hopefully we will be able to report on speedier progress soon. Cheers, Matti Picus, Maciej Fijalkowski From noreply at buildbot.pypy.org Tue Mar 5 23:21:00 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 23:21:00 +0100 (CET) Subject: [pypy-commit] pypy default: pep8 Message-ID: <20130305222100.D180D1C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62099:91e0e964585a Date: 2013-03-05 16:11 -0500 http://bitbucket.org/pypy/pypy/changeset/91e0e964585a/ Log: pep8 diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -570,8 +570,8 @@ def total_seconds(self): """Total seconds in the duration.""" - return ((self.days * 86400 + self.seconds) * 10**6 - + self.microseconds) / 1e6 + return ((self.days * 86400 + self.seconds) * 10**6 + + self.microseconds) / 1e6 # Read-only field accessors @property From noreply at buildbot.pypy.org Tue Mar 5 23:21:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Mar 2013 23:21:02 +0100 (CET) Subject: [pypy-commit] pypy default: improve generated min/max code by improving hints to jitdriver Message-ID: <20130305222102.15A591C1043@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62100:b730d41cd8ab Date: 2013-03-05 17:19 -0500 http://bitbucket.org/pypy/pypy/changeset/b730d41cd8ab/ Log: improve generated min/max code by improving hints to jitdriver diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -134,9 +134,9 @@ return space.newlist(res_w) min_jitdriver = jit.JitDriver(name='min', - greens=['w_type'], reds='auto') + greens=['has_key', 'has_item', 'w_type'], reds='auto') max_jitdriver = jit.JitDriver(name='max', - greens=['w_type'], reds='auto') + greens=['has_key', 'has_item', 'w_type'], reds='auto') def make_min_max(unroll): @specialize.arg(2) @@ -166,23 +166,26 @@ w_iter = space.iter(w_sequence) w_type = space.type(w_iter) + has_key = w_key is not None + has_item = False w_max_item = None w_max_val = None while True: if not unroll: - jitdriver.jit_merge_point(w_type=w_type) + jitdriver.jit_merge_point(has_key=has_key, has_item=has_item, w_type=w_type) try: w_item = space.next(w_iter) except OperationError, e: if not e.match(space, space.w_StopIteration): raise break - if w_key is not None: + if has_key: w_compare_with = space.call_function(w_key, w_item) else: w_compare_with = w_item - if w_max_item is None or \ + if not has_item or \ space.is_true(compare(w_compare_with, w_max_val)): + has_item = True w_max_item = w_item w_max_val = w_compare_with if w_max_item is None: From noreply at buildbot.pypy.org Wed Mar 6 01:42:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:42:22 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for behavior of _sqlite3.Connection._check_{thread, closed} Message-ID: <20130306004222.8AFC41C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62101:df9670b5d959 Date: 2013-03-05 18:49 -0500 http://bitbucket.org/pypy/pypy/changeset/df9670b5d959/ Log: test and fix for behavior of _sqlite3.Connection._check_{thread,closed} diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -27,6 +27,7 @@ from ctypes import POINTER, byref, string_at, CFUNCTYPE, cast from ctypes import sizeof, c_ssize_t from collections import OrderedDict +from functools import wraps import datetime import sys import weakref @@ -392,6 +393,20 @@ "The object was created in thread id %d and this is thread id %d", self.thread_ident, thread_get_ident()) + def _check_thread_wrap(func): + @wraps(func) + def _check_thread_func(self, *args, **kwargs): + self._check_thread() + return func(self, *args, **kwargs) + return _check_thread_func + + def _check_closed_wrap(func): + @wraps(func) + def _check_closed_func(self, *args, **kwargs): + self._check_closed() + return func(self, *args, **kwargs) + return _check_closed_func + def _reset_cursors(self): for cursor_ref in self.cursors: cursor = cursor_ref() @@ -429,8 +444,8 @@ cur.row_factory = self.row_factory return cur.executescript(*args) + @_check_closed_wrap def __call__(self, sql): - self._check_closed() if not isinstance(sql, (str, unicode)): raise Warning("SQL is of wrong type. Must be string or unicode.") statement = self.statement_cache.get(sql, self.row_factory) @@ -548,9 +563,9 @@ raise self._get_exception(ret) self.db.value = 0 + @_check_thread_wrap + @_check_closed_wrap def create_collation(self, name, callback): - self._check_thread() - self._check_closed() name = name.upper() if not name.replace('_', '').isalnum(): raise ProgrammingError("invalid character in collation name") @@ -578,9 +593,9 @@ if ret != SQLITE_OK: raise self._get_exception(ret) + @_check_thread_wrap + @_check_closed_wrap def set_progress_handler(self, callable, nsteps): - self._check_thread() - self._check_closed() if callable is None: c_progress_handler = cast(None, PROGRESS) else: @@ -603,10 +618,9 @@ if ret != SQLITE_OK: raise self._get_exception(ret) + @_check_thread_wrap + @_check_closed_wrap def set_authorizer(self, callback): - self._check_thread() - self._check_closed() - try: c_authorizer, _ = self.func_cache[callback] except KeyError: @@ -625,9 +639,9 @@ if ret != SQLITE_OK: raise self._get_exception(ret) + @_check_thread_wrap + @_check_closed_wrap def create_function(self, name, num_args, callback): - self._check_thread() - self._check_closed() try: c_closure, _ = self.func_cache[callback] except KeyError: @@ -643,10 +657,9 @@ if ret != SQLITE_OK: raise self.OperationalError("Error creating function") + @_check_thread_wrap + @_check_closed_wrap def create_aggregate(self, name, num_args, cls): - self._check_thread() - self._check_closed() - try: c_step_callback, c_final_callback, _, _ = self._aggregates[cls] except KeyError: @@ -718,10 +731,9 @@ return _iterdump(self) if HAS_LOAD_EXTENSION: + @_check_thread_wrap + @_check_closed_wrap def enable_load_extension(self, enabled): - self._check_thread() - self._check_closed() - rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled)) if rc != SQLITE_OK: raise OperationalError("Error enabling load extension") 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 @@ -45,6 +45,13 @@ e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')") assert '__init__' in e.value.message +def test_connection_after_close(): + con = _sqlite3.connect(':memory:') + pytest.raises(TypeError, "con()") + con.close() + # raises ProgrammingError because should check closed before check args + pytest.raises(_sqlite3.ProgrammingError, "con()") + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') From noreply at buildbot.pypy.org Wed Mar 6 01:42:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:42:23 +0100 (CET) Subject: [pypy-commit] pypy default: simplify these functions Message-ID: <20130306004223.CE0751C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62102:5e9db69947ee Date: 2013-03-05 18:58 -0500 http://bitbucket.org/pypy/pypy/changeset/5e9db69947ee/ Log: simplify these functions diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -424,24 +424,15 @@ return cur def executemany(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.executemany(*args) def execute(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.execute(*args) def executescript(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.executescript(*args) @_check_closed_wrap From noreply at buildbot.pypy.org Wed Mar 6 01:42:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:42:25 +0100 (CET) Subject: [pypy-commit] pypy default: improve layout of _sqlite3.Connection Message-ID: <20130306004225.02DFE1C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62103:10fab7978541 Date: 2013-03-05 19:32 -0500 http://bitbucket.org/pypy/pypy/changeset/10fab7978541/ Log: improve layout of _sqlite3.Connection diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -50,6 +50,7 @@ PARSE_COLNAMES = 1 PARSE_DECLTYPES = 2 +DML, DQL, DDL = range(3) ########################################## # BEGIN Wrapped SQLite C API and constants @@ -348,6 +349,49 @@ if self.db: sqlite.sqlite3_close(self.db) + def close(self): + self._check_thread() + + for statement in self.statements: + obj = statement() + if obj is not None: + obj.finalize() + + if self.db: + ret = sqlite.sqlite3_close(self.db) + if ret != SQLITE_OK: + raise self._get_exception(ret) + self.db.value = 0 + + def _check_closed(self): + if self.db is None: + raise ProgrammingError("Base Connection.__init__ not called.") + if not self.db: + raise ProgrammingError("Cannot operate on a closed database.") + + def _check_closed_wrap(func): + @wraps(func) + def _check_closed_func(self, *args, **kwargs): + self._check_closed() + return func(self, *args, **kwargs) + return _check_closed_func + + def _check_thread(self): + if not hasattr(self, 'thread_ident'): + return + if self.thread_ident != thread_get_ident(): + raise ProgrammingError( + "SQLite objects created in a thread can only be used in that same thread." + "The object was created in thread id %d and this is thread id %d", + self.thread_ident, thread_get_ident()) + + def _check_thread_wrap(func): + @wraps(func) + def _check_thread_func(self, *args, **kwargs): + self._check_thread() + return func(self, *args, **kwargs) + return _check_thread_func + def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self.db) @@ -384,34 +428,12 @@ if self.statement_counter % 100 == 0: self.statements = [ref for ref in self.statements if ref() is not None] - def _check_thread(self): - if not hasattr(self, 'thread_ident'): - return - if self.thread_ident != thread_get_ident(): - raise ProgrammingError( - "SQLite objects created in a thread can only be used in that same thread." - "The object was created in thread id %d and this is thread id %d", - self.thread_ident, thread_get_ident()) - - def _check_thread_wrap(func): - @wraps(func) - def _check_thread_func(self, *args, **kwargs): - self._check_thread() - return func(self, *args, **kwargs) - return _check_thread_func - - def _check_closed_wrap(func): - @wraps(func) - def _check_closed_func(self, *args, **kwargs): - self._check_closed() - return func(self, *args, **kwargs) - return _check_closed_func - - def _reset_cursors(self): - for cursor_ref in self.cursors: - cursor = cursor_ref() - if cursor: - cursor.reset = True + @_check_closed_wrap + def __call__(self, sql): + if not isinstance(sql, (str, unicode)): + raise Warning("SQL is of wrong type. Must be string or unicode.") + statement = self.statement_cache.get(sql, self.row_factory) + return statement def cursor(self, factory=None): self._check_thread() @@ -423,35 +445,21 @@ cur.row_factory = self.row_factory return cur + def execute(self, *args): + cur = self.cursor() + return cur.execute(*args) + def executemany(self, *args): cur = self.cursor() return cur.executemany(*args) - def execute(self, *args): - cur = self.cursor() - return cur.execute(*args) - def executescript(self, *args): cur = self.cursor() return cur.executescript(*args) - @_check_closed_wrap - def __call__(self, sql): - if not isinstance(sql, (str, unicode)): - raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self.statement_cache.get(sql, self.row_factory) - return statement - - def _get_isolation_level(self): - return self._isolation_level - - def _set_isolation_level(self, val): - if val is None: - self.commit() - if isinstance(val, unicode): - val = str(val) - self._isolation_level = val - isolation_level = property(_get_isolation_level, _set_isolation_level) + def iterdump(self): + from sqlite3.dump import _iterdump + return _iterdump(self) def _begin(self): self._check_closed() @@ -506,6 +514,11 @@ if obj is not None: obj.reset() + for cursor_ref in self.cursors: + cursor = cursor_ref() + if cursor: + cursor.reset = True + try: sql = "ROLLBACK" statement = c_void_p() @@ -518,13 +531,6 @@ raise self._get_exception(ret) finally: sqlite.sqlite3_finalize(statement) - self._reset_cursors() - - def _check_closed(self): - if self.db is None: - raise ProgrammingError("Base Connection.__init__ not called.") - if not self.db: - raise ProgrammingError("Cannot operate on a closed database.") def __enter__(self): return self @@ -535,101 +541,6 @@ else: self.rollback() - def _get_total_changes(self): - self._check_closed() - return sqlite.sqlite3_total_changes(self.db) - total_changes = property(_get_total_changes) - - def close(self): - self._check_thread() - - for statement in self.statements: - obj = statement() - if obj is not None: - obj.finalize() - - if self.db: - ret = sqlite.sqlite3_close(self.db) - if ret != SQLITE_OK: - raise self._get_exception(ret) - self.db.value = 0 - - @_check_thread_wrap - @_check_closed_wrap - def create_collation(self, name, callback): - name = name.upper() - if not name.replace('_', '').isalnum(): - raise ProgrammingError("invalid character in collation name") - - if callback is None: - del self._collations[name] - c_collation_callback = cast(None, COLLATION) - else: - if not callable(callback): - raise TypeError("parameter must be callable") - - def collation_callback(context, len1, str1, len2, str2): - text1 = string_at(str1, len1) - text2 = string_at(str2, len2) - - return callback(text1, text2) - - c_collation_callback = COLLATION(collation_callback) - self._collations[name] = c_collation_callback - - ret = sqlite.sqlite3_create_collation(self.db, name, - SQLITE_UTF8, - None, - c_collation_callback) - if ret != SQLITE_OK: - raise self._get_exception(ret) - - @_check_thread_wrap - @_check_closed_wrap - def set_progress_handler(self, callable, nsteps): - if callable is None: - c_progress_handler = cast(None, PROGRESS) - else: - try: - c_progress_handler, _ = self.func_cache[callable] - except KeyError: - def progress_handler(userdata): - try: - ret = callable() - return bool(ret) - except Exception: - # abort query if error occurred - return 1 - c_progress_handler = PROGRESS(progress_handler) - - self.func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self.db, nsteps, - c_progress_handler, - None) - if ret != SQLITE_OK: - raise self._get_exception(ret) - - @_check_thread_wrap - @_check_closed_wrap - def set_authorizer(self, callback): - try: - c_authorizer, _ = self.func_cache[callback] - except KeyError: - def authorizer(userdata, action, arg1, arg2, dbname, source): - try: - return int(callback(action, arg1, arg2, dbname, source)) - except Exception: - return SQLITE_DENY - c_authorizer = AUTHORIZER(authorizer) - - self.func_cache[callback] = c_authorizer, authorizer - - ret = sqlite.sqlite3_set_authorizer(self.db, - c_authorizer, - None) - if ret != SQLITE_OK: - raise self._get_exception(ret) - @_check_thread_wrap @_check_closed_wrap def create_function(self, name, num_args, callback): @@ -717,9 +628,97 @@ if ret != SQLITE_OK: raise self._get_exception(ret) - def iterdump(self): - from sqlite3.dump import _iterdump - return _iterdump(self) + @_check_thread_wrap + @_check_closed_wrap + def create_collation(self, name, callback): + name = name.upper() + if not name.replace('_', '').isalnum(): + raise ProgrammingError("invalid character in collation name") + + if callback is None: + del self._collations[name] + c_collation_callback = cast(None, COLLATION) + else: + if not callable(callback): + raise TypeError("parameter must be callable") + + def collation_callback(context, len1, str1, len2, str2): + text1 = string_at(str1, len1) + text2 = string_at(str2, len2) + + return callback(text1, text2) + + c_collation_callback = COLLATION(collation_callback) + self._collations[name] = c_collation_callback + + ret = sqlite.sqlite3_create_collation(self.db, name, + SQLITE_UTF8, + None, + c_collation_callback) + if ret != SQLITE_OK: + raise self._get_exception(ret) + + @_check_thread_wrap + @_check_closed_wrap + def set_authorizer(self, callback): + try: + c_authorizer, _ = self.func_cache[callback] + except KeyError: + def authorizer(userdata, action, arg1, arg2, dbname, source): + try: + return int(callback(action, arg1, arg2, dbname, source)) + except Exception: + return SQLITE_DENY + c_authorizer = AUTHORIZER(authorizer) + + self.func_cache[callback] = c_authorizer, authorizer + + ret = sqlite.sqlite3_set_authorizer(self.db, + c_authorizer, + None) + if ret != SQLITE_OK: + raise self._get_exception(ret) + + @_check_thread_wrap + @_check_closed_wrap + def set_progress_handler(self, callable, nsteps): + if callable is None: + c_progress_handler = cast(None, PROGRESS) + else: + try: + c_progress_handler, _ = self.func_cache[callable] + except KeyError: + def progress_handler(userdata): + try: + ret = callable() + return bool(ret) + except Exception: + # abort query if error occurred + return 1 + c_progress_handler = PROGRESS(progress_handler) + + self.func_cache[callable] = c_progress_handler, progress_handler + ret = sqlite.sqlite3_progress_handler(self.db, nsteps, + c_progress_handler, + None) + if ret != SQLITE_OK: + raise self._get_exception(ret) + + def _get_isolation_level(self): + return self._isolation_level + + def _get_total_changes(self): + self._check_closed() + return sqlite.sqlite3_total_changes(self.db) + total_changes = property(_get_total_changes) + + def _set_isolation_level(self, val): + if val is None: + self.commit() + if isinstance(val, unicode): + val = str(val) + self._isolation_level = val + isolation_level = property(_get_isolation_level, _set_isolation_level) if HAS_LOAD_EXTENSION: @_check_thread_wrap @@ -729,8 +728,6 @@ if rc != SQLITE_OK: raise OperationalError("Error enabling load extension") -DML, DQL, DDL = range(3) - class CursorLock(object): def __init__(self, cursor): From noreply at buildbot.pypy.org Wed Mar 6 01:42:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:42:26 +0100 (CET) Subject: [pypy-commit] pypy default: missing/extra checks Message-ID: <20130306004226.27FC91C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62104:8f3d8c5f9a11 Date: 2013-03-05 19:36 -0500 http://bitbucket.org/pypy/pypy/changeset/8f3d8c5f9a11/ Log: missing/extra checks diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -428,6 +428,7 @@ if self.statement_counter % 100 == 0: self.statements = [ref for ref in self.statements if ref() is not None] + @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): if not isinstance(sql, (str, unicode)): @@ -462,7 +463,6 @@ return _iterdump(self) def _begin(self): - self._check_closed() if self._isolation_level is None: return if sqlite.sqlite3_get_autocommit(self.db): From noreply at buildbot.pypy.org Wed Mar 6 01:42:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:42:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130306004227.57F821C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62105:a54b01b91c81 Date: 2013-03-05 19:40 -0500 http://bitbucket.org/pypy/pypy/changeset/a54b01b91c81/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -27,6 +27,7 @@ from ctypes import POINTER, byref, string_at, CFUNCTYPE, cast from ctypes import sizeof, c_ssize_t from collections import OrderedDict +from functools import wraps import datetime import sys import weakref @@ -49,6 +50,7 @@ PARSE_COLNAMES = 1 PARSE_DECLTYPES = 2 +DML, DQL, DDL = range(3) ########################################## # BEGIN Wrapped SQLite C API and constants @@ -354,6 +356,49 @@ if self.db: sqlite.sqlite3_close(self.db) + def close(self): + self._check_thread() + + for statement in self.statements: + obj = statement() + if obj is not None: + obj.finalize() + + if self.db: + ret = sqlite.sqlite3_close(self.db) + if ret != SQLITE_OK: + raise self._get_exception(ret) + self.db.value = 0 + + def _check_closed(self): + if self.db is None: + raise ProgrammingError("Base Connection.__init__ not called.") + if not self.db: + raise ProgrammingError("Cannot operate on a closed database.") + + def _check_closed_wrap(func): + @wraps(func) + def _check_closed_func(self, *args, **kwargs): + self._check_closed() + return func(self, *args, **kwargs) + return _check_closed_func + + def _check_thread(self): + if not hasattr(self, 'thread_ident'): + return + if self.thread_ident != thread_get_ident(): + raise ProgrammingError( + "SQLite objects created in a thread can only be used in that same thread." + "The object was created in thread id %d and this is thread id %d", + self.thread_ident, thread_get_ident()) + + def _check_thread_wrap(func): + @wraps(func) + def _check_thread_func(self, *args, **kwargs): + self._check_thread() + return func(self, *args, **kwargs) + return _check_thread_func + def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self.db) @@ -391,20 +436,13 @@ if self.statement_counter % 100 == 0: self.statements = [ref for ref in self.statements if ref() is not None] - def _check_thread(self): - if not hasattr(self, 'thread_ident'): - return - if self.thread_ident != thread_get_ident(): - raise ProgrammingError( - "SQLite objects created in a thread can only be used in that same thread." - "The object was created in thread id %d and this is thread id %d", - self.thread_ident, thread_get_ident()) - - def _reset_cursors(self): - for cursor_ref in self.cursors: - cursor = cursor_ref() - if cursor: - cursor.reset = True + @_check_thread_wrap + @_check_closed_wrap + def __call__(self, sql): + if not isinstance(sql, str): + raise Warning("SQL is of wrong type. Must be string or unicode.") + statement = self.statement_cache.get(sql, self.row_factory) + return statement def cursor(self, factory=None): self._check_thread() @@ -416,47 +454,23 @@ cur.row_factory = self.row_factory return cur + def execute(self, *args): + cur = self.cursor() + return cur.execute(*args) + def executemany(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.executemany(*args) - def execute(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory - return cur.execute(*args) - def executescript(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.executescript(*args) - def __call__(self, sql): - self._check_closed() - if not isinstance(sql, str): - raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self.statement_cache.get(sql, self.row_factory) - return statement - - def _get_isolation_level(self): - return self._isolation_level - - def _set_isolation_level(self, val): - if val is None: - self.commit() - if isinstance(val, str): - val = str(val) - self._isolation_level = val - isolation_level = property(_get_isolation_level, _set_isolation_level) + def iterdump(self): + from sqlite3.dump import _iterdump + return _iterdump(self) def _begin(self): - self._check_closed() if self._isolation_level is None: return if sqlite.sqlite3_get_autocommit(self.db): @@ -508,6 +522,11 @@ if obj is not None: obj.reset() + for cursor_ref in self.cursors: + cursor = cursor_ref() + if cursor: + cursor.reset = True + try: sql = "ROLLBACK" statement = c_void_p() @@ -520,13 +539,6 @@ raise self._get_exception(ret) finally: sqlite.sqlite3_finalize(statement) - self._reset_cursors() - - def _check_closed(self): - if self.db is None: - raise ProgrammingError("Base Connection.__init__ not called.") - if not self.db: - raise ProgrammingError("Cannot operate on a closed database.") def __enter__(self): return self @@ -537,105 +549,9 @@ else: self.rollback() - def _get_total_changes(self): - self._check_closed() - return sqlite.sqlite3_total_changes(self.db) - total_changes = property(_get_total_changes) - - def close(self): - self._check_thread() - - for statement in self.statements: - obj = statement() - if obj is not None: - obj.finalize() - - if self.db: - ret = sqlite.sqlite3_close(self.db) - if ret != SQLITE_OK: - raise self._get_exception(ret) - self.db.value = 0 - - def create_collation(self, name, callback): - self._check_thread() - self._check_closed() - name = name.upper() - if not name.replace('_', '').isalnum(): - raise ProgrammingError("invalid character in collation name") - - if callback is None: - del self._collations[name] - c_collation_callback = cast(None, COLLATION) - else: - if not callable(callback): - raise TypeError("parameter must be callable") - - def collation_callback(context, len1, str1, len2, str2): - text1 = string_at(str1, len1) - text2 = string_at(str2, len2) - - return callback(text1, text2) - - c_collation_callback = COLLATION(collation_callback) - self._collations[name] = c_collation_callback - - ret = sqlite.sqlite3_create_collation(self.db, name, - SQLITE_UTF8, - None, - c_collation_callback) - if ret != SQLITE_OK: - raise self._get_exception(ret) - - def set_progress_handler(self, callable, nsteps): - self._check_thread() - self._check_closed() - if callable is None: - c_progress_handler = cast(None, PROGRESS) - else: - try: - c_progress_handler, _ = self.func_cache[callable] - except KeyError: - def progress_handler(userdata): - try: - ret = callable() - return bool(ret) - except Exception: - # abort query if error occurred - return 1 - c_progress_handler = PROGRESS(progress_handler) - - self.func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self.db, nsteps, - c_progress_handler, - None) - if ret != SQLITE_OK: - raise self._get_exception(ret) - - def set_authorizer(self, callback): - self._check_thread() - self._check_closed() - - try: - c_authorizer, _ = self.func_cache[callback] - except KeyError: - def authorizer(userdata, action, arg1, arg2, dbname, source): - try: - return int(callback(action, arg1, arg2, dbname, source)) - except Exception: - return SQLITE_DENY - c_authorizer = AUTHORIZER(authorizer) - - self.func_cache[callback] = c_authorizer, authorizer - - ret = sqlite.sqlite3_set_authorizer(self.db, - c_authorizer, - None) - if ret != SQLITE_OK: - raise self._get_exception(ret) - + @_check_thread_wrap + @_check_closed_wrap def create_function(self, name, num_args, callback): - self._check_thread() - self._check_closed() try: c_closure, _ = self.func_cache[callback] except KeyError: @@ -651,10 +567,9 @@ if ret != SQLITE_OK: raise self.OperationalError("Error creating function") + @_check_thread_wrap + @_check_closed_wrap def create_aggregate(self, name, num_args, cls): - self._check_thread() - self._check_closed() - try: c_step_callback, c_final_callback, _, _ = self._aggregates[cls] except KeyError: @@ -721,21 +636,106 @@ if ret != SQLITE_OK: raise self._get_exception(ret) - def iterdump(self): - from sqlite3.dump import _iterdump - return _iterdump(self) + @_check_thread_wrap + @_check_closed_wrap + def create_collation(self, name, callback): + name = name.upper() + if not name.replace('_', '').isalnum(): + raise ProgrammingError("invalid character in collation name") + + if callback is None: + del self._collations[name] + c_collation_callback = cast(None, COLLATION) + else: + if not callable(callback): + raise TypeError("parameter must be callable") + + def collation_callback(context, len1, str1, len2, str2): + text1 = string_at(str1, len1) + text2 = string_at(str2, len2) + + return callback(text1, text2) + + c_collation_callback = COLLATION(collation_callback) + self._collations[name] = c_collation_callback + + ret = sqlite.sqlite3_create_collation(self.db, name, + SQLITE_UTF8, + None, + c_collation_callback) + if ret != SQLITE_OK: + raise self._get_exception(ret) + + @_check_thread_wrap + @_check_closed_wrap + def set_authorizer(self, callback): + try: + c_authorizer, _ = self.func_cache[callback] + except KeyError: + def authorizer(userdata, action, arg1, arg2, dbname, source): + try: + return int(callback(action, arg1, arg2, dbname, source)) + except Exception: + return SQLITE_DENY + c_authorizer = AUTHORIZER(authorizer) + + self.func_cache[callback] = c_authorizer, authorizer + + ret = sqlite.sqlite3_set_authorizer(self.db, + c_authorizer, + None) + if ret != SQLITE_OK: + raise self._get_exception(ret) + + @_check_thread_wrap + @_check_closed_wrap + def set_progress_handler(self, callable, nsteps): + if callable is None: + c_progress_handler = cast(None, PROGRESS) + else: + try: + c_progress_handler, _ = self.func_cache[callable] + except KeyError: + def progress_handler(userdata): + try: + ret = callable() + return bool(ret) + except Exception: + # abort query if error occurred + return 1 + c_progress_handler = PROGRESS(progress_handler) + + self.func_cache[callable] = c_progress_handler, progress_handler + ret = sqlite.sqlite3_progress_handler(self.db, nsteps, + c_progress_handler, + None) + if ret != SQLITE_OK: + raise self._get_exception(ret) + + def _get_isolation_level(self): + return self._isolation_level + + def _get_total_changes(self): + self._check_closed() + return sqlite.sqlite3_total_changes(self.db) + total_changes = property(_get_total_changes) + + def _set_isolation_level(self, val): + if val is None: + self.commit() + if isinstance(val, str): + val = str(val) + self._isolation_level = val + isolation_level = property(_get_isolation_level, _set_isolation_level) if HAS_LOAD_EXTENSION: + @_check_thread_wrap + @_check_closed_wrap def enable_load_extension(self, enabled): - self._check_thread() - self._check_closed() - rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled)) if rc != SQLITE_OK: raise OperationalError("Error enabling load extension") -DML, DQL, DDL = range(3) - class CursorLock(object): def __init__(self, cursor): diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -208,10 +208,7 @@ # app-level, very different from rpython.rlib.objectmodel.we_are_translated return hasattr(sys, 'pypy_translation_info') -if 'nt' in sys.builtin_module_names: - IS_WINDOWS = True -else: - IS_WINDOWS = False +IS_WINDOWS = 'nt' in sys.builtin_module_names def setup_and_fix_paths(ignore_environment=False, **extra): import os diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -104,9 +104,9 @@ return w_start, w_stop, w_step min_jitdriver = jit.JitDriver(name='min', - greens=['w_type'], reds='auto') + greens=['has_key', 'has_item', 'w_type'], reds='auto') max_jitdriver = jit.JitDriver(name='max', - greens=['w_type'], reds='auto') + greens=['has_key', 'has_item', 'w_type'], reds='auto') def make_min_max(unroll): @specialize.arg(2) @@ -136,23 +136,26 @@ w_iter = space.iter(w_sequence) w_type = space.type(w_iter) + has_key = w_key is not None + has_item = False w_max_item = None w_max_val = None while True: if not unroll: - jitdriver.jit_merge_point(w_type=w_type) + jitdriver.jit_merge_point(has_key=has_key, has_item=has_item, w_type=w_type) try: w_item = space.next(w_iter) except OperationError, e: if not e.match(space, space.w_StopIteration): raise break - if w_key is not None: + if has_key: w_compare_with = space.call_function(w_key, w_item) else: w_compare_with = w_item - if w_max_item is None or \ + if not has_item or \ space.is_true(compare(w_compare_with, w_max_val)): + has_item = True w_max_item = w_item w_max_val = w_compare_with if w_max_item is None: 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 @@ -45,6 +45,13 @@ e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')") assert '__init__' in e.value.message +def test_connection_after_close(): + con = _sqlite3.connect(':memory:') + pytest.raises(TypeError, "con()") + con.close() + # raises ProgrammingError because should check closed before check args + pytest.raises(_sqlite3.ProgrammingError, "con()") + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') @@ -67,6 +74,7 @@ @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): """For issue1325.""" + import os import gc try: import resource @@ -75,10 +83,19 @@ limit = resource.getrlimit(resource.RLIMIT_NOFILE) try: - resource.setrlimit(resource.RLIMIT_NOFILE, (min(10, limit[0]), limit[1])) + fds = 0 + while True: + fds += 1 + resource.setrlimit(resource.RLIMIT_NOFILE, (fds, limit[1])) + try: + for p in os.pipe(): os.close(p) + except OSError: + assert fds < 100 + else: + break def open_many(cleanup): con = [] - for i in range(20): + for i in range(3): con.append(_sqlite3.connect(str(tmpdir.join('test.db')))) if cleanup: con[i] = None From noreply at buildbot.pypy.org Wed Mar 6 01:42:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:42:28 +0100 (CET) Subject: [pypy-commit] pypy py3k: unnecessary in py3k Message-ID: <20130306004228.83B351C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62106:a17a3ecca4d2 Date: 2013-03-05 19:41 -0500 http://bitbucket.org/pypy/pypy/changeset/a17a3ecca4d2/ Log: unnecessary in py3k diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -723,8 +723,6 @@ def _set_isolation_level(self, val): if val is None: self.commit() - if isinstance(val, str): - val = str(val) self._isolation_level = val isolation_level = property(_get_isolation_level, _set_isolation_level) From noreply at buildbot.pypy.org Wed Mar 6 01:43:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 01:43:19 +0100 (CET) Subject: [pypy-commit] pypy py3k: pep8 Message-ID: <20130306004319.2E0E71C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62107:049d48fcc85f Date: 2013-03-05 16:11 -0500 http://bitbucket.org/pypy/pypy/changeset/049d48fcc85f/ Log: pep8 diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -476,7 +476,7 @@ def total_seconds(self): """Total seconds in the duration.""" - return ((self.days * 86400 + self.seconds)*10**6 + + return ((self.days * 86400 + self.seconds) * 10**6 + self.microseconds) / 10**6 # Read-only field accessors From noreply at buildbot.pypy.org Wed Mar 6 02:30:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 02:30:28 +0100 (CET) Subject: [pypy-commit] pypy default: use an explicit initialized variable for clarity Message-ID: <20130306013028.17E3C1C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62108:4241c22e47ae Date: 2013-03-05 20:30 -0500 http://bitbucket.org/pypy/pypy/changeset/4241c22e47ae/ Log: use an explicit initialized variable for clarity diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -306,7 +306,7 @@ class Connection(object): - db = None + initialized = False def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): @@ -344,10 +344,12 @@ self._collations = {} if check_same_thread: self.thread_ident = thread_get_ident() + self.initialized = True def __del__(self): - if self.db: - sqlite.sqlite3_close(self.db) + if self.initialized: + if self.db: + sqlite.sqlite3_close(self.db) def close(self): self._check_thread() @@ -361,10 +363,10 @@ ret = sqlite.sqlite3_close(self.db) if ret != SQLITE_OK: raise self._get_exception(ret) - self.db.value = 0 + self.db = None def _check_closed(self): - if self.db is None: + if not self.initialized: raise ProgrammingError("Base Connection.__init__ not called.") if not self.db: raise ProgrammingError("Cannot operate on a closed database.") From noreply at buildbot.pypy.org Wed Mar 6 02:40:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 02:40:54 +0100 (CET) Subject: [pypy-commit] pypy default: these should go before try: finally block Message-ID: <20130306014054.39A271C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62109:9939c0c252b8 Date: 2013-03-05 20:40 -0500 http://bitbucket.org/pypy/pypy/changeset/9939c0c252b8/ Log: these should go before try: finally block diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -468,11 +468,11 @@ if self._isolation_level is None: return if sqlite.sqlite3_get_autocommit(self.db): + sql = "BEGIN " + self._isolation_level + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) try: - sql = "BEGIN " + self._isolation_level - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) @@ -492,11 +492,11 @@ if obj is not None: obj.reset() + sql = "COMMIT" + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) try: - sql = "COMMIT" - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) @@ -521,11 +521,11 @@ if cursor: cursor.reset = True + sql = "ROLLBACK" + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) try: - sql = "ROLLBACK" - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) From noreply at buildbot.pypy.org Wed Mar 6 02:46:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 02:46:11 +0100 (CET) Subject: [pypy-commit] pypy default: structure begin like the commit/rollback Message-ID: <20130306014611.2E3AD1C1017@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62110:7edcb72f4072 Date: 2013-03-05 20:45 -0500 http://bitbucket.org/pypy/pypy/changeset/7edcb72f4072/ Log: structure begin like the commit/rollback diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -467,19 +467,21 @@ def _begin(self): if self._isolation_level is None: return - if sqlite.sqlite3_get_autocommit(self.db): - sql = "BEGIN " + self._isolation_level - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) - try: - if ret != SQLITE_OK: - raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: - raise self._get_exception(ret) - finally: - sqlite.sqlite3_finalize(statement) + if not sqlite.sqlite3_get_autocommit(self.db): + return + + sql = "BEGIN " + self._isolation_level + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) + try: + if ret != SQLITE_OK: + raise self._get_exception(ret) + ret = sqlite.sqlite3_step(statement) + if ret != SQLITE_DONE: + raise self._get_exception(ret) + finally: + sqlite.sqlite3_finalize(statement) def commit(self): self._check_thread() From noreply at buildbot.pypy.org Wed Mar 6 06:00:41 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:00:41 +0100 (CET) Subject: [pypy-commit] pypy default: have _sqlite3 cache in_transaction rather than calling get_autocommit all the time Message-ID: <20130306050041.0D32A1C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62111:5b19ec51c15b Date: 2013-03-05 21:39 -0500 http://bitbucket.org/pypy/pypy/changeset/5b19ec51c15b/ Log: have _sqlite3 cache in_transaction rather than calling get_autocommit all the time diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -321,10 +321,12 @@ self.statements = [] self.statement_counter = 0 self.row_factory = None - self._isolation_level = isolation_level self.detect_types = detect_types self.statement_cache = StatementCache(self, cached_statements) + self._isolation_level = isolation_level + self._in_transaction = False + self.cursors = [] self.Error = Error @@ -465,11 +467,6 @@ return _iterdump(self) def _begin(self): - if self._isolation_level is None: - return - if not sqlite.sqlite3_get_autocommit(self.db): - return - sql = "BEGIN " + self._isolation_level statement = c_void_p() next_char = c_char_p() @@ -480,13 +477,14 @@ ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: raise self._get_exception(ret) + self._in_transaction = True finally: sqlite.sqlite3_finalize(statement) def commit(self): self._check_thread() self._check_closed() - if sqlite.sqlite3_get_autocommit(self.db): + if not self._in_transaction: return for statement in self.statements: @@ -504,13 +502,14 @@ ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: raise self._get_exception(ret) + self._in_transaction = False finally: sqlite.sqlite3_finalize(statement) def rollback(self): self._check_thread() self._check_closed() - if sqlite.sqlite3_get_autocommit(self.db): + if not self._in_transaction: return for statement in self.statements: @@ -533,6 +532,7 @@ ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: raise self._get_exception(ret) + self._in_transaction = False finally: sqlite.sqlite3_finalize(statement) @@ -790,9 +790,11 @@ if self.connection._isolation_level is not None: if self.statement.kind == DDL: - self.connection.commit() + if self.connection._in_transaction: + self.connection.commit() elif self.statement.kind == DML: - self.connection._begin() + if not self.connection._in_transaction: + self.connection._begin() self.statement.set_params(params) @@ -800,6 +802,8 @@ ret = sqlite.sqlite3_step(self.statement.statement) if ret not in (SQLITE_DONE, SQLITE_ROW): self.statement.reset() + self.connection._in_transaction = \ + not sqlite.sqlite3_get_autocommit(self.connection.db) raise self.connection._get_exception(ret) if self.statement.kind == DML: @@ -829,7 +833,9 @@ sql, self.row_factory) if self.statement.kind == DML: - self.connection._begin() + if self.connection._isolation_level is not None: + if not self.connection._in_transaction: + self.connection._begin() else: raise ProgrammingError("executemany is only for DML statements") From noreply at buildbot.pypy.org Wed Mar 6 06:00:43 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:00:43 +0100 (CET) Subject: [pypy-commit] pypy default: mangle some names of implementation-specific variables in _sqlite3 to prevent clashes Message-ID: <20130306050043.7BC2C1C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62113:532dc327c36c Date: 2013-03-05 22:41 -0500 http://bitbucket.org/pypy/pypy/changeset/532dc327c36c/ Log: mangle some names of implementation-specific variables in _sqlite3 to prevent clashes diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -31,7 +31,7 @@ import datetime import sys import weakref -from threading import _get_ident as thread_get_ident +from threading import _get_ident as _thread_get_ident names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() for name in names: @@ -50,8 +50,6 @@ PARSE_COLNAMES = 1 PARSE_DECLTYPES = 2 -DML, DQL, DDL = range(3) - ########################################## # BEGIN Wrapped SQLite C API and constants ########################################## @@ -234,11 +232,13 @@ sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] sqlite.sqlite3_result_text.restype = None -HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") -if HAS_LOAD_EXTENSION: +_HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") +if _HAS_LOAD_EXTENSION: sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] sqlite.sqlite3_enable_load_extension.restype = c_int +_DML, _DQL, _DDL = range(3) + ########################################## # END Wrapped SQLite C API and constants ########################################## @@ -306,28 +306,36 @@ class Connection(object): - initialized = False + __initialized = False def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): - self.db = c_void_p() - if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK: + self._db = c_void_p() + if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds - sqlite.sqlite3_busy_timeout(self.db, timeout) + sqlite.sqlite3_busy_timeout(self._db, timeout) + self.row_factory = None self.text_factory = unicode_text_factory - self.statements = [] - self.statement_counter = 0 - self.row_factory = None - self.detect_types = detect_types - self.statement_cache = StatementCache(self, cached_statements) + self._detect_types = detect_types self._isolation_level = isolation_level self._in_transaction = False - self.cursors = [] + self._cursors = [] + self.__statements = [] + self.__statement_counter = 0 + self._statement_cache = StatementCache(self, cached_statements) + + self.__initialized = True + self.__func_cache = {} + self.__aggregates = {} + self.__aggregate_instances = {} + self.__collations = {} + if check_same_thread: + self.__thread_ident = _thread_get_ident() self.Error = Error self.Warning = Warning @@ -340,37 +348,29 @@ self.DataError = DataError self.NotSupportedError = NotSupportedError - self.func_cache = {} - self._aggregates = {} - self.aggregate_instances = {} - self._collations = {} - if check_same_thread: - self.thread_ident = thread_get_ident() - self.initialized = True - def __del__(self): - if self.initialized: - if self.db: - sqlite.sqlite3_close(self.db) + if self.__initialized: + if self._db: + sqlite.sqlite3_close(self._db) def close(self): self._check_thread() - for statement in self.statements: + for statement in self.__statements: obj = statement() if obj is not None: obj.finalize() - if self.db: - ret = sqlite.sqlite3_close(self.db) + if self._db: + ret = sqlite.sqlite3_close(self._db) if ret != SQLITE_OK: raise self._get_exception(ret) - self.db = None + self._db = None def _check_closed(self): - if not self.initialized: + if not self.__initialized: raise ProgrammingError("Base Connection.__init__ not called.") - if not self.db: + if not self._db: raise ProgrammingError("Cannot operate on a closed database.") def _check_closed_wrap(func): @@ -381,13 +381,16 @@ return _check_closed_func def _check_thread(self): - if not hasattr(self, 'thread_ident'): - return - if self.thread_ident != thread_get_ident(): + try: + if self.__thread_ident == _thread_get_ident(): + return + except AttributeError: + pass + else: raise ProgrammingError( "SQLite objects created in a thread can only be used in that same thread." "The object was created in thread id %d and this is thread id %d", - self.thread_ident, thread_get_ident()) + self.__thread_ident, _thread_get_ident()) def _check_thread_wrap(func): @wraps(func) @@ -398,8 +401,8 @@ def _get_exception(self, error_code=None): if error_code is None: - error_code = sqlite.sqlite3_errcode(self.db) - error_message = sqlite.sqlite3_errmsg(self.db) + error_code = sqlite.sqlite3_errcode(self._db) + error_message = sqlite.sqlite3_errmsg(self._db) if error_code == SQLITE_OK: raise ValueError("error signalled but got SQLITE_OK") @@ -426,18 +429,18 @@ return exc def _remember_statement(self, statement): - self.statements.append(weakref.ref(statement)) - self.statement_counter += 1 + self.__statements.append(weakref.ref(statement)) + self.__statement_counter += 1 - if self.statement_counter % 100 == 0: - self.statements = [ref for ref in self.statements if ref() is not None] + if self.__statement_counter % 100 == 0: + self.__statements = [ref for ref in self.__statements if ref() is not None] @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): if not isinstance(sql, (str, unicode)): raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self.statement_cache.get(sql, self.row_factory) + statement = self._statement_cache.get(sql, self.row_factory) return statement def cursor(self, factory=None): @@ -470,7 +473,7 @@ sql = "BEGIN " + self._isolation_level statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) + ret = sqlite.sqlite3_prepare_v2(self._db, sql, -1, byref(statement), next_char) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -487,7 +490,7 @@ if not self._in_transaction: return - for statement in self.statements: + for statement in self.__statements: obj = statement() if obj is not None: obj.reset() @@ -495,7 +498,7 @@ sql = "COMMIT" statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) + ret = sqlite.sqlite3_prepare_v2(self._db, sql, -1, byref(statement), next_char) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -512,12 +515,12 @@ if not self._in_transaction: return - for statement in self.statements: + for statement in self.__statements: obj = statement() if obj is not None: obj.reset() - for cursor_ref in self.cursors: + for cursor_ref in self._cursors: cursor = cursor_ref() if cursor: cursor.reset = True @@ -525,7 +528,7 @@ sql = "ROLLBACK" statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) + ret = sqlite.sqlite3_prepare_v2(self._db, sql, -1, byref(statement), next_char) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -549,17 +552,17 @@ @_check_closed_wrap def create_function(self, name, num_args, callback): try: - c_closure, _ = self.func_cache[callback] + c_closure, _ = self.__func_cache[callback] except KeyError: def closure(context, nargs, c_params): function_callback(callback, context, nargs, c_params) - c_closure = FUNC(closure) - self.func_cache[callback] = c_closure, closure - ret = sqlite.sqlite3_create_function(self.db, name, num_args, + c_closure = _FUNC(closure) + self.__func_cache[callback] = c_closure, closure + ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, c_closure, - cast(None, STEP), - cast(None, FINAL)) + cast(None, _STEP), + cast(None, _FINAL)) if ret != SQLITE_OK: raise self.OperationalError("Error creating function") @@ -567,7 +570,7 @@ @_check_closed_wrap def create_aggregate(self, name, num_args, cls): try: - c_step_callback, c_final_callback, _, _ = self._aggregates[cls] + c_step_callback, c_final_callback, _, _ = self.__aggregates[cls] except KeyError: def step_callback(context, argc, c_params): @@ -585,10 +588,10 @@ sqlite.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) - self.aggregate_instances[aggregate_id] = aggregate + self.__aggregate_instances[aggregate_id] = aggregate aggregate_ptr[0] = aggregate_id else: - aggregate = self.aggregate_instances[aggregate_ptr[0]] + aggregate = self.__aggregate_instances[aggregate_ptr[0]] params = _convert_params(context, argc, c_params) try: @@ -606,7 +609,7 @@ POINTER(c_ssize_t)) if aggregate_ptr[0]: - aggregate = self.aggregate_instances[aggregate_ptr[0]] + aggregate = self.__aggregate_instances[aggregate_ptr[0]] try: val = aggregate.finalize() except Exception: @@ -616,17 +619,17 @@ else: _convert_result(context, val) finally: - del self.aggregate_instances[aggregate_ptr[0]] + del self.__aggregate_instances[aggregate_ptr[0]] - c_step_callback = STEP(step_callback) - c_final_callback = FINAL(final_callback) + c_step_callback = _STEP(step_callback) + c_final_callback = _FINAL(final_callback) - self._aggregates[cls] = (c_step_callback, c_final_callback, + self.__aggregates[cls] = (c_step_callback, c_final_callback, step_callback, final_callback) - ret = sqlite.sqlite3_create_function(self.db, name, num_args, + ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, - cast(None, FUNC), + cast(None, _FUNC), c_step_callback, c_final_callback) if ret != SQLITE_OK: @@ -640,8 +643,8 @@ raise ProgrammingError("invalid character in collation name") if callback is None: - del self._collations[name] - c_collation_callback = cast(None, COLLATION) + del self.__collations[name] + c_collation_callback = cast(None, _COLLATION) else: if not callable(callback): raise TypeError("parameter must be callable") @@ -652,10 +655,10 @@ return callback(text1, text2) - c_collation_callback = COLLATION(collation_callback) - self._collations[name] = c_collation_callback + c_collation_callback = _COLLATION(collation_callback) + self.__collations[name] = c_collation_callback - ret = sqlite.sqlite3_create_collation(self.db, name, + ret = sqlite.sqlite3_create_collation(self._db, name, SQLITE_UTF8, None, c_collation_callback) @@ -666,18 +669,18 @@ @_check_closed_wrap def set_authorizer(self, callback): try: - c_authorizer, _ = self.func_cache[callback] + c_authorizer, _ = self.__func_cache[callback] except KeyError: def authorizer(userdata, action, arg1, arg2, dbname, source): try: return int(callback(action, arg1, arg2, dbname, source)) except Exception: return SQLITE_DENY - c_authorizer = AUTHORIZER(authorizer) + c_authorizer = _AUTHORIZER(authorizer) - self.func_cache[callback] = c_authorizer, authorizer + self.__func_cache[callback] = c_authorizer, authorizer - ret = sqlite.sqlite3_set_authorizer(self.db, + ret = sqlite.sqlite3_set_authorizer(self._db, c_authorizer, None) if ret != SQLITE_OK: @@ -687,10 +690,10 @@ @_check_closed_wrap def set_progress_handler(self, callable, nsteps): if callable is None: - c_progress_handler = cast(None, PROGRESS) + c_progress_handler = cast(None, _PROGRESS) else: try: - c_progress_handler, _ = self.func_cache[callable] + c_progress_handler, _ = self.__func_cache[callable] except KeyError: def progress_handler(userdata): try: @@ -699,45 +702,46 @@ except Exception: # abort query if error occurred return 1 - c_progress_handler = PROGRESS(progress_handler) + c_progress_handler = _PROGRESS(progress_handler) - self.func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self.db, nsteps, + self.__func_cache[callable] = c_progress_handler, progress_handler + ret = sqlite.sqlite3_progress_handler(self._db, nsteps, c_progress_handler, None) if ret != SQLITE_OK: raise self._get_exception(ret) - def _get_total_changes(self): + def __get_total_changes(self): self._check_closed() - return sqlite.sqlite3_total_changes(self.db) - total_changes = property(_get_total_changes) + return sqlite.sqlite3_total_changes(self._db) + total_changes = property(__get_total_changes) - def _get_isolation_level(self): + def __get_isolation_level(self): return self._isolation_level - def _set_isolation_level(self, val): + def __set_isolation_level(self, val): if val is None: self.commit() if isinstance(val, unicode): val = str(val) self._isolation_level = val - isolation_level = property(_get_isolation_level, _set_isolation_level) + isolation_level = property(__get_isolation_level, __set_isolation_level) - if HAS_LOAD_EXTENSION: + if _HAS_LOAD_EXTENSION: @_check_thread_wrap @_check_closed_wrap def enable_load_extension(self, enabled): - rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled)) + rc = sqlite.sqlite3_enable_load_extension(self._db, int(enabled)) if rc != SQLITE_OK: raise OperationalError("Error enabling load extension") -class CursorLock(object): +class _CursorLock(object): def __init__(self, cursor): self.cursor = cursor def __enter__(self): + self.cursor._check_closed() if self.cursor.locked: raise ProgrammingError("Recursive use of cursors not allowed.") self.cursor.locked = True @@ -747,14 +751,14 @@ class Cursor(object): - initialized = False + __initialized = False def __init__(self, con): if not isinstance(con, Connection): raise TypeError con._check_thread() con._check_closed() - con.cursors.append(weakref.ref(self)) + con._cursors.append(weakref.ref(self)) self.connection = con self._description = None self.arraysize = 1 @@ -764,35 +768,31 @@ self.reset = False self.locked = False self.closed = False - self.initialized = True + self.__initialized = True def _check_closed(self): - if not self.initialized: + if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") if self.closed: raise ProgrammingError("Cannot operate on a closed cursor.") self.connection._check_thread() self.connection._check_closed() - def _check_and_lock(self): - self._check_closed() - return CursorLock(self) - def execute(self, sql, params=None): if type(sql) is unicode: sql = sql.encode("utf-8") - with self._check_and_lock(): + with _CursorLock(self): self._description = None self.reset = False - self.statement = self.connection.statement_cache.get( + self.statement = self.connection._statement_cache.get( sql, self.row_factory) if self.connection._isolation_level is not None: - if self.statement.kind == DDL: + if self.statement.kind == _DDL: if self.connection._in_transaction: self.connection.commit() - elif self.statement.kind == DML: + elif self.statement.kind == _DML: if not self.connection._in_transaction: self.connection._begin() @@ -803,13 +803,13 @@ if ret not in (SQLITE_DONE, SQLITE_ROW): self.statement.reset() self.connection._in_transaction = \ - not sqlite.sqlite3_get_autocommit(self.connection.db) + not sqlite.sqlite3_get_autocommit(self.connection._db) raise self.connection._get_exception(ret) - if self.statement.kind == DML: + if self.statement.kind == _DML: self.statement.reset() - if self.statement.kind == DQL and ret == SQLITE_ROW: + if self.statement.kind == _DQL and ret == SQLITE_ROW: self.statement._build_row_cast_map() self.statement._readahead(self) else: @@ -817,8 +817,8 @@ self.statement.exhausted = True self.rowcount = -1 - if self.statement.kind == DML: - self.rowcount = sqlite.sqlite3_changes(self.connection.db) + if self.statement.kind == _DML: + self.rowcount = sqlite.sqlite3_changes(self.connection._db) return self @@ -826,13 +826,13 @@ if type(sql) is unicode: sql = sql.encode("utf-8") - with self._check_and_lock(): + with _CursorLock(self): self._description = None self.reset = False - self.statement = self.connection.statement_cache.get( + self.statement = self.connection._statement_cache.get( sql, self.row_factory) - if self.statement.kind == DML: + if self.statement.kind == _DML: if self.connection._isolation_level is not None: if not self.connection._in_transaction: self.connection._begin() @@ -845,7 +845,7 @@ ret = sqlite.sqlite3_step(self.statement.statement) if ret != SQLITE_DONE: raise self.connection._get_exception(ret) - self.rowcount += sqlite.sqlite3_changes(self.connection.db) + self.rowcount += sqlite.sqlite3_changes(self.connection._db) return self @@ -860,7 +860,7 @@ self.connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.connection.db, c_sql, -1, byref(statement), byref(c_sql)) + rc = sqlite.sqlite3_prepare(self.connection._db, c_sql, -1, byref(statement), byref(c_sql)) if rc != SQLITE_OK: raise self.connection._get_exception(rc) @@ -934,7 +934,7 @@ return self._description def _getlastrowid(self): - return sqlite.sqlite3_last_insert_rowid(self.connection.db) + return sqlite.sqlite3_last_insert_rowid(self.connection._db) def close(self): self.connection._check_thread() @@ -945,11 +945,11 @@ self.closed = True def __del__(self): - if self.initialized: + if self.__initialized: if self.statement: self.statement.reset() try: - self.connection.cursors.remove(weakref.ref(self)) + self.connection._cursors.remove(weakref.ref(self)) except ValueError: pass @@ -973,11 +973,11 @@ self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): - self.kind = DML + self.kind = _DML elif first_word in ("SELECT", "PRAGMA"): - self.kind = DQL + self.kind = _DQL else: - self.kind = DDL + self.kind = _DDL self.exhausted = False self.in_use = False # @@ -987,11 +987,11 @@ self.statement = c_void_p() next_char = c_char_p() sql_char = c_char_p(sql) - ret = sqlite.sqlite3_prepare_v2(self.con.db, sql_char, -1, byref(self.statement), byref(next_char)) + ret = sqlite.sqlite3_prepare_v2(self.con._db, sql_char, -1, byref(self.statement), byref(next_char)) if ret == SQLITE_OK and self.statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.con.db, "select 42", -1, byref(self.statement), byref(next_char)) - self.kind = DQL + ret = sqlite.sqlite3_prepare_v2(self.con._db, "select 42", -1, byref(self.statement), byref(next_char)) + self.kind = _DQL if ret != SQLITE_OK: raise self.con._get_exception(ret) @@ -1011,7 +1011,7 @@ for i in xrange(sqlite.sqlite3_column_count(self.statement)): converter = None - if self.con.detect_types & PARSE_COLNAMES: + if self.con._detect_types & PARSE_COLNAMES: colname = sqlite.sqlite3_column_name(self.statement, i) if colname is not None: type_start = -1 @@ -1023,7 +1023,7 @@ key = colname[type_start:pos] converter = converters[key.upper()] - if converter is None and self.con.detect_types & PARSE_DECLTYPES: + if converter is None and self.con._detect_types & PARSE_DECLTYPES: decltype = sqlite.sqlite3_column_decltype(self.statement, i) if decltype is not None: decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" @@ -1186,7 +1186,7 @@ sqlite.sqlite3_finalize(self.statement) def _get_description(self): - if self.kind == DML: + if self.kind == _DML: return None desc = [] for i in xrange(sqlite.sqlite3_column_count(self.statement)): @@ -1327,25 +1327,25 @@ else: _convert_result(context, val) -FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -FINAL = CFUNCTYPE(None, c_void_p) -sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, FUNC, STEP, FINAL] +_FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) +_STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) +_FINAL = CFUNCTYPE(None, c_void_p) +sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] sqlite.sqlite3_create_function.restype = c_int sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] sqlite.sqlite3_aggregate_context.restype = c_void_p -COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, COLLATION] +_COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) +sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, _COLLATION] sqlite.sqlite3_create_collation.restype = c_int -PROGRESS = CFUNCTYPE(c_int, c_void_p) -sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, PROGRESS, c_void_p] +_PROGRESS = CFUNCTYPE(c_int, c_void_p) +sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p] sqlite.sqlite3_progress_handler.restype = c_int -AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) -sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, AUTHORIZER, c_void_p] +_AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) +sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p] sqlite.sqlite3_set_authorizer.restype = c_int converters = {} From noreply at buildbot.pypy.org Wed Mar 6 06:00:42 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:00:42 +0100 (CET) Subject: [pypy-commit] pypy default: put getter with setter Message-ID: <20130306050042.3E11A1C104B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62112:4474d4b96147 Date: 2013-03-05 22:04 -0500 http://bitbucket.org/pypy/pypy/changeset/4474d4b96147/ Log: put getter with setter diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -708,14 +708,14 @@ if ret != SQLITE_OK: raise self._get_exception(ret) - def _get_isolation_level(self): - return self._isolation_level - def _get_total_changes(self): self._check_closed() return sqlite.sqlite3_total_changes(self.db) total_changes = property(_get_total_changes) + def _get_isolation_level(self): + return self._isolation_level + def _set_isolation_level(self, val): if val is None: self.commit() From noreply at buildbot.pypy.org Wed Mar 6 06:00:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:00:44 +0100 (CET) Subject: [pypy-commit] pypy default: have _sqlite3 cache begin statement Message-ID: <20130306050044.A55041C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62114:e052d7b7f0cd Date: 2013-03-05 23:10 -0500 http://bitbucket.org/pypy/pypy/changeset/e052d7b7f0cd/ Log: have _sqlite3 cache begin statement diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -310,6 +310,7 @@ def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): + self.__initialized = True self._db = c_void_p() if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") @@ -321,15 +322,14 @@ self.text_factory = unicode_text_factory self._detect_types = detect_types - self._isolation_level = isolation_level self._in_transaction = False + self.isolation_level = isolation_level self._cursors = [] self.__statements = [] self.__statement_counter = 0 self._statement_cache = StatementCache(self, cached_statements) - self.__initialized = True self.__func_cache = {} self.__aggregates = {} self.__aggregate_instances = {} @@ -470,10 +470,10 @@ return _iterdump(self) def _begin(self): - sql = "BEGIN " + self._isolation_level statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, sql, -1, byref(statement), next_char) + ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, + byref(statement), next_char) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -495,10 +495,10 @@ if obj is not None: obj.reset() - sql = "COMMIT" statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, sql, -1, byref(statement), next_char) + ret = sqlite.sqlite3_prepare_v2(self._db, "COMMIT", -1, + byref(statement), next_char) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -525,10 +525,10 @@ if cursor: cursor.reset = True - sql = "ROLLBACK" statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, sql, -1, byref(statement), next_char) + ret = sqlite.sqlite3_prepare_v2(self._db, "ROLLBACK", -1, + byref(statement), next_char) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -722,8 +722,10 @@ def __set_isolation_level(self, val): if val is None: self.commit() - if isinstance(val, unicode): - val = str(val) + else: + if isinstance(val, unicode): + val = str(val) + self.__begin_statement = 'BEGIN ' + val self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) From noreply at buildbot.pypy.org Wed Mar 6 06:00:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:00:45 +0100 (CET) Subject: [pypy-commit] pypy default: group _sqlite3.Cursor methods logically Message-ID: <20130306050045.E4ECA1C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62115:e076a6681f04 Date: 2013-03-05 23:26 -0500 http://bitbucket.org/pypy/pypy/changeset/e076a6681f04/ Log: group _sqlite3.Cursor methods logically diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -772,6 +772,23 @@ self.closed = False self.__initialized = True + def __del__(self): + if self.__initialized: + if self.statement: + self.statement.reset() + try: + self.connection._cursors.remove(weakref.ref(self)) + except ValueError: + pass + + def close(self): + self.connection._check_thread() + self.connection._check_closed() + if self.statement: + self.statement.reset() + self.statement = None + self.closed = True + def _check_closed(self): if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") @@ -887,9 +904,6 @@ break return self - def __iter__(self): - return iter(self.fetchone, None) - def _check_reset(self): if self.reset: raise self.connection.InterfaceError("Cursor needed to be reset because " @@ -930,30 +944,18 @@ return [] return list(self) + def __iter__(self): + return iter(self.fetchone, None) + def _getdescription(self): if self._description is None: self._description = self.statement._get_description() return self._description + description = property(_getdescription) def _getlastrowid(self): return sqlite.sqlite3_last_insert_rowid(self.connection._db) - - def close(self): - self.connection._check_thread() - self.connection._check_closed() - if self.statement: - self.statement.reset() - self.statement = None - self.closed = True - - def __del__(self): - if self.__initialized: - if self.statement: - self.statement.reset() - try: - self.connection._cursors.remove(weakref.ref(self)) - except ValueError: - pass + lastrowid = property(_getlastrowid) def setinputsizes(self, *args): pass @@ -961,9 +963,6 @@ def setoutputsize(self, *args): pass - description = property(_getdescription) - lastrowid = property(_getlastrowid) - class Statement(object): statement = None From noreply at buildbot.pypy.org Wed Mar 6 06:00:47 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:00:47 +0100 (CET) Subject: [pypy-commit] pypy default: mangle some more implementation-specific names in _sqlite3.Cursor Message-ID: <20130306050047.218EC1C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62116:b027d4428675 Date: 2013-03-05 23:47 -0500 http://bitbucket.org/pypy/pypy/changeset/b027d4428675/ Log: mangle some more implementation-specific names in _sqlite3.Cursor diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -307,11 +307,13 @@ class Connection(object): __initialized = False + _db = None def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): self.__initialized = True self._db = c_void_p() + if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: @@ -349,9 +351,8 @@ self.NotSupportedError = NotSupportedError def __del__(self): - if self.__initialized: - if self._db: - sqlite.sqlite3_close(self._db) + if self._db: + sqlite.sqlite3_close(self._db) def close(self): self._check_thread() @@ -523,7 +524,7 @@ for cursor_ref in self._cursors: cursor = cursor_ref() if cursor: - cursor.reset = True + cursor._reset = True statement = c_void_p() next_char = c_char_p() @@ -744,100 +745,103 @@ def __enter__(self): self.cursor._check_closed() - if self.cursor.locked: + if self.cursor._locked: raise ProgrammingError("Recursive use of cursors not allowed.") - self.cursor.locked = True + self.cursor._locked = True def __exit__(self, *args): - self.cursor.locked = False + self.cursor._locked = False class Cursor(object): __initialized = False + __connection = None + __statement = None def __init__(self, con): + self.__initialized = True + self.__connection = con + if not isinstance(con, Connection): raise TypeError con._check_thread() con._check_closed() con._cursors.append(weakref.ref(self)) - self.connection = con - self._description = None + self.arraysize = 1 self.row_factory = None - self.rowcount = -1 - self.statement = None - self.reset = False - self.locked = False - self.closed = False - self.__initialized = True + self._locked = False + self._reset = False + self.__closed = False + self.__description = None + self.__rowcount = -1 def __del__(self): - if self.__initialized: - if self.statement: - self.statement.reset() + if self.__connection: try: - self.connection._cursors.remove(weakref.ref(self)) + self.__connection._cursors.remove(weakref.ref(self)) except ValueError: pass + if self.__statement: + self.__statement.reset() def close(self): - self.connection._check_thread() - self.connection._check_closed() - if self.statement: - self.statement.reset() - self.statement = None - self.closed = True + self.__connection._check_thread() + self.__connection._check_closed() + if self.__statement: + self.__statement.reset() + self.__statement = None + self.__closed = True def _check_closed(self): if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") - if self.closed: + if self.__closed: raise ProgrammingError("Cannot operate on a closed cursor.") - self.connection._check_thread() - self.connection._check_closed() + self.__connection._check_thread() + self.__connection._check_closed() def execute(self, sql, params=None): if type(sql) is unicode: sql = sql.encode("utf-8") with _CursorLock(self): - self._description = None - self.reset = False - self.statement = self.connection._statement_cache.get( + self.__description = None + self._reset = False + self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) - if self.connection._isolation_level is not None: - if self.statement.kind == _DDL: - if self.connection._in_transaction: - self.connection.commit() - elif self.statement.kind == _DML: - if not self.connection._in_transaction: - self.connection._begin() + if self.__connection._isolation_level is not None: + if self.__statement.kind == _DDL: + if self.__connection._in_transaction: + self.__connection.commit() + elif self.__statement.kind == _DML: + if not self.__connection._in_transaction: + self.__connection._begin() - self.statement.set_params(params) + self.__statement.set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.statement.statement) + ret = sqlite.sqlite3_step(self.__statement.statement) if ret not in (SQLITE_DONE, SQLITE_ROW): - self.statement.reset() - self.connection._in_transaction = \ - not sqlite.sqlite3_get_autocommit(self.connection._db) - raise self.connection._get_exception(ret) + self.__statement.reset() + self.__connection._in_transaction = \ + not sqlite.sqlite3_get_autocommit(self.__connection._db) + raise self.__connection._get_exception(ret) - if self.statement.kind == _DML: - self.statement.reset() + if self.__statement.kind == _DML: + self.__statement.reset() - if self.statement.kind == _DQL and ret == SQLITE_ROW: - self.statement._build_row_cast_map() - self.statement._readahead(self) + if self.__statement.kind == _DQL and ret == SQLITE_ROW: + self.__statement._build_row_cast_map() + self.__statement._readahead(self) else: - self.statement.item = None - self.statement.exhausted = True + self.__statement.item = None + self.__statement.exhausted = True - self.rowcount = -1 - if self.statement.kind == _DML: - self.rowcount = sqlite.sqlite3_changes(self.connection._db) + self.__rowcount = -1 + if self.__statement.kind == _DML: + self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) return self @@ -846,42 +850,42 @@ sql = sql.encode("utf-8") with _CursorLock(self): - self._description = None - self.reset = False - self.statement = self.connection._statement_cache.get( + self.__description = None + self._reset = False + self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) - if self.statement.kind == _DML: - if self.connection._isolation_level is not None: - if not self.connection._in_transaction: - self.connection._begin() + if self.__statement.kind == _DML: + if self.__connection._isolation_level is not None: + if not self.__connection._in_transaction: + self.__connection._begin() else: raise ProgrammingError("executemany is only for DML statements") - self.rowcount = 0 + self.__rowcount = 0 for params in many_params: - self.statement.set_params(params) - ret = sqlite.sqlite3_step(self.statement.statement) + self.__statement.set_params(params) + ret = sqlite.sqlite3_step(self.__statement.statement) if ret != SQLITE_DONE: - raise self.connection._get_exception(ret) - self.rowcount += sqlite.sqlite3_changes(self.connection._db) + raise self.__connection._get_exception(ret) + self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) return self def executescript(self, sql): - self._description = None - self.reset = False + self.__description = None + self._reset = False if type(sql) is unicode: sql = sql.encode("utf-8") self._check_closed() statement = c_void_p() c_sql = c_char_p(sql) - self.connection.commit() + self.__connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.connection._db, c_sql, -1, byref(statement), byref(c_sql)) + rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) if rc != SQLITE_OK: - raise self.connection._get_exception(rc) + raise self.__connection._get_exception(rc) rc = SQLITE_ROW while rc == SQLITE_ROW: @@ -895,18 +899,18 @@ if rc == SQLITE_OK: return self else: - raise self.connection._get_exception(rc) + raise self.__connection._get_exception(rc) rc = sqlite.sqlite3_finalize(statement) if rc != SQLITE_OK: - raise self.connection._get_exception(rc) + raise self.__connection._get_exception(rc) if not c_sql.value: break return self def _check_reset(self): - if self.reset: - raise self.connection.InterfaceError("Cursor needed to be reset because " + if self._reset: + raise self.__connection.InterfaceError("Cursor needed to be reset because " "of commit/rollback and can " "no longer be fetched from.") @@ -915,18 +919,18 @@ self._check_closed() self._check_reset() - if self.statement is None: + if self.__statement is None: return None try: - return self.statement.next(self) + return self.__statement.next(self) except StopIteration: return None def fetchmany(self, size=None): self._check_closed() self._check_reset() - if self.statement is None: + if self.__statement is None: return [] if size is None: size = self.arraysize @@ -940,22 +944,30 @@ def fetchall(self): self._check_closed() self._check_reset() - if self.statement is None: + if self.__statement is None: return [] return list(self) def __iter__(self): return iter(self.fetchone, None) - def _getdescription(self): - if self._description is None: - self._description = self.statement._get_description() - return self._description - description = property(_getdescription) + def __get_connection(self): + return self.__connection + connection = property(__get_connection) - def _getlastrowid(self): - return sqlite.sqlite3_last_insert_rowid(self.connection._db) - lastrowid = property(_getlastrowid) + def __get_rowcount(self): + return self.__rowcount + rowcount = property(__get_rowcount) + + def __get_description(self): + if self.__description is None: + self.__description = self.__statement._get_description() + return self.__description + description = property(__get_description) + + def __get_lastrowid(self): + return sqlite.sqlite3_last_insert_rowid(self.__connection._db) + lastrowid = property(__get_lastrowid) def setinputsizes(self, *args): pass 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 @@ -63,13 +63,13 @@ def test_cursor_del(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') - stmt = cur.statement + stmt = cur._Cursor__statement cur.close() cur = con.execute('select 1') - assert cur.statement is stmt + assert cur._Cursor__statement is stmt del cur; import gc; gc.collect(); gc.collect() cur = con.execute('select 1') - assert cur.statement is stmt + assert cur._Cursor__statement is stmt @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): From noreply at buildbot.pypy.org Wed Mar 6 06:10:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:10:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130306051053.57D561C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62117:05429f9f75e9 Date: 2013-03-06 00:10 -0500 http://bitbucket.org/pypy/pypy/changeset/05429f9f75e9/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -31,7 +31,7 @@ import datetime import sys import weakref -from threading import _get_ident as thread_get_ident +from threading import _get_ident as _thread_get_ident names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() for name in names: @@ -50,8 +50,6 @@ PARSE_COLNAMES = 1 PARSE_DECLTYPES = 2 -DML, DQL, DDL = range(3) - ########################################## # BEGIN Wrapped SQLite C API and constants ########################################## @@ -241,11 +239,13 @@ sqlite.sqlite3_result_text.argtypes = [c_void_p, TEXT, c_int, c_void_p] sqlite.sqlite3_result_text.restype = None -HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") -if HAS_LOAD_EXTENSION: +_HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") +if _HAS_LOAD_EXTENSION: sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] sqlite.sqlite3_enable_load_extension.restype = c_int +_DML, _DQL, _DDL = range(3) + ########################################## # END Wrapped SQLite C API and constants ########################################## @@ -313,26 +313,38 @@ class Connection(object): - db = None + __initialized = False + _db = None def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): - self.db = c_void_p() - if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK: + self.__initialized = True + self._db = c_void_p() + + if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds - sqlite.sqlite3_busy_timeout(self.db, timeout) + sqlite.sqlite3_busy_timeout(self._db, timeout) + self.row_factory = None self.text_factory = unicode_text_factory - self.statements = [] - self.statement_counter = 0 - self.row_factory = None - self._isolation_level = isolation_level - self.detect_types = detect_types - self.statement_cache = StatementCache(self, cached_statements) - self.cursors = [] + self._detect_types = detect_types + self._in_transaction = False + self.isolation_level = isolation_level + + self._cursors = [] + self.__statements = [] + self.__statement_counter = 0 + self._statement_cache = StatementCache(self, cached_statements) + + self.__func_cache = {} + self.__aggregates = {} + self.__aggregate_instances = {} + self.__collations = {} + if check_same_thread: + self.__thread_ident = _thread_get_ident() self.Error = Error self.Warning = Warning @@ -345,35 +357,28 @@ self.DataError = DataError self.NotSupportedError = NotSupportedError - self.func_cache = {} - self._aggregates = {} - self.aggregate_instances = {} - self._collations = {} - if check_same_thread: - self.thread_ident = thread_get_ident() - def __del__(self): - if self.db: - sqlite.sqlite3_close(self.db) + if self._db: + sqlite.sqlite3_close(self._db) def close(self): self._check_thread() - for statement in self.statements: + for statement in self.__statements: obj = statement() if obj is not None: obj.finalize() - if self.db: - ret = sqlite.sqlite3_close(self.db) + if self._db: + ret = sqlite.sqlite3_close(self._db) if ret != SQLITE_OK: raise self._get_exception(ret) - self.db.value = 0 + self._db = None def _check_closed(self): - if self.db is None: + if not self.__initialized: raise ProgrammingError("Base Connection.__init__ not called.") - if not self.db: + if not self._db: raise ProgrammingError("Cannot operate on a closed database.") def _check_closed_wrap(func): @@ -384,13 +389,16 @@ return _check_closed_func def _check_thread(self): - if not hasattr(self, 'thread_ident'): - return - if self.thread_ident != thread_get_ident(): + try: + if self.__thread_ident == _thread_get_ident(): + return + except AttributeError: + pass + else: raise ProgrammingError( "SQLite objects created in a thread can only be used in that same thread." "The object was created in thread id %d and this is thread id %d", - self.thread_ident, thread_get_ident()) + self.__thread_ident, _thread_get_ident()) def _check_thread_wrap(func): @wraps(func) @@ -401,8 +409,8 @@ def _get_exception(self, error_code=None): if error_code is None: - error_code = sqlite.sqlite3_errcode(self.db) - error_message = sqlite.sqlite3_errmsg(self.db) + error_code = sqlite.sqlite3_errcode(self._db) + error_message = sqlite.sqlite3_errmsg(self._db) error_message = error_message.decode('utf-8') if error_code == SQLITE_OK: @@ -430,18 +438,18 @@ return exc def _remember_statement(self, statement): - self.statements.append(weakref.ref(statement)) - self.statement_counter += 1 + self.__statements.append(weakref.ref(statement)) + self.__statement_counter += 1 - if self.statement_counter % 100 == 0: - self.statements = [ref for ref in self.statements if ref() is not None] + if self.__statement_counter % 100 == 0: + self.__statements = [ref for ref in self.__statements if ref() is not None] @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): if not isinstance(sql, str): raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self.statement_cache.get(sql, self.row_factory) + statement = self._statement_cache.get(sql, self.row_factory) return statement def cursor(self, factory=None): @@ -471,72 +479,72 @@ return _iterdump(self) def _begin(self): - if self._isolation_level is None: - return - if sqlite.sqlite3_get_autocommit(self.db): - try: - sql = "BEGIN " + self._isolation_level - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) - if ret != SQLITE_OK: - raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: - raise self._get_exception(ret) - finally: - sqlite.sqlite3_finalize(statement) - - def commit(self): - self._check_thread() - self._check_closed() - if sqlite.sqlite3_get_autocommit(self.db): - return - - for statement in self.statements: - obj = statement() - if obj is not None: - obj.reset() - + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, + byref(statement), next_char) try: - sql = "COMMIT" - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: raise self._get_exception(ret) + self._in_transaction = True + finally: + sqlite.sqlite3_finalize(statement) + + def commit(self): + self._check_thread() + self._check_closed() + if not self._in_transaction: + return + + for statement in self.__statements: + obj = statement() + if obj is not None: + obj.reset() + + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self._db, "COMMIT", -1, + byref(statement), next_char) + try: + if ret != SQLITE_OK: + raise self._get_exception(ret) + ret = sqlite.sqlite3_step(statement) + if ret != SQLITE_DONE: + raise self._get_exception(ret) + self._in_transaction = False finally: sqlite.sqlite3_finalize(statement) def rollback(self): self._check_thread() self._check_closed() - if sqlite.sqlite3_get_autocommit(self.db): + if not self._in_transaction: return - for statement in self.statements: + for statement in self.__statements: obj = statement() if obj is not None: obj.reset() - for cursor_ref in self.cursors: + for cursor_ref in self._cursors: cursor = cursor_ref() if cursor: - cursor.reset = True + cursor._reset = True + statement = c_void_p() + next_char = c_char_p() + ret = sqlite.sqlite3_prepare_v2(self._db, "ROLLBACK", -1, + byref(statement), next_char) try: - sql = "ROLLBACK" - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: raise self._get_exception(ret) + self._in_transaction = False finally: sqlite.sqlite3_finalize(statement) @@ -553,17 +561,17 @@ @_check_closed_wrap def create_function(self, name, num_args, callback): try: - c_closure, _ = self.func_cache[callback] + c_closure, _ = self.__func_cache[callback] except KeyError: def closure(context, nargs, c_params): function_callback(callback, context, nargs, c_params) - c_closure = FUNC(closure) - self.func_cache[callback] = c_closure, closure - ret = sqlite.sqlite3_create_function(self.db, name, num_args, + c_closure = _FUNC(closure) + self.__func_cache[callback] = c_closure, closure + ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, c_closure, - cast(None, STEP), - cast(None, FINAL)) + cast(None, _STEP), + cast(None, _FINAL)) if ret != SQLITE_OK: raise self.OperationalError("Error creating function") @@ -571,7 +579,7 @@ @_check_closed_wrap def create_aggregate(self, name, num_args, cls): try: - c_step_callback, c_final_callback, _, _ = self._aggregates[cls] + c_step_callback, c_final_callback, _, _ = self.__aggregates[cls] except KeyError: def step_callback(context, argc, c_params): @@ -589,10 +597,10 @@ sqlite.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) - self.aggregate_instances[aggregate_id] = aggregate + self.__aggregate_instances[aggregate_id] = aggregate aggregate_ptr[0] = aggregate_id else: - aggregate = self.aggregate_instances[aggregate_ptr[0]] + aggregate = self.__aggregate_instances[aggregate_ptr[0]] params = _convert_params(context, argc, c_params) try: @@ -610,7 +618,7 @@ POINTER(c_ssize_t)) if aggregate_ptr[0]: - aggregate = self.aggregate_instances[aggregate_ptr[0]] + aggregate = self.__aggregate_instances[aggregate_ptr[0]] try: val = aggregate.finalize() except Exception: @@ -620,17 +628,17 @@ else: _convert_result(context, val) finally: - del self.aggregate_instances[aggregate_ptr[0]] + del self.__aggregate_instances[aggregate_ptr[0]] - c_step_callback = STEP(step_callback) - c_final_callback = FINAL(final_callback) + c_step_callback = _STEP(step_callback) + c_final_callback = _FINAL(final_callback) - self._aggregates[cls] = (c_step_callback, c_final_callback, + self.__aggregates[cls] = (c_step_callback, c_final_callback, step_callback, final_callback) - ret = sqlite.sqlite3_create_function(self.db, name, num_args, + ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, - cast(None, FUNC), + cast(None, _FUNC), c_step_callback, c_final_callback) if ret != SQLITE_OK: @@ -644,8 +652,8 @@ raise ProgrammingError("invalid character in collation name") if callback is None: - del self._collations[name] - c_collation_callback = cast(None, COLLATION) + del self.__collations[name] + c_collation_callback = cast(None, _COLLATION) else: if not callable(callback): raise TypeError("parameter must be callable") @@ -656,10 +664,10 @@ return callback(text1, text2) - c_collation_callback = COLLATION(collation_callback) - self._collations[name] = c_collation_callback + c_collation_callback = _COLLATION(collation_callback) + self.__collations[name] = c_collation_callback - ret = sqlite.sqlite3_create_collation(self.db, name, + ret = sqlite.sqlite3_create_collation(self._db, name, SQLITE_UTF8, None, c_collation_callback) @@ -670,18 +678,18 @@ @_check_closed_wrap def set_authorizer(self, callback): try: - c_authorizer, _ = self.func_cache[callback] + c_authorizer, _ = self.__func_cache[callback] except KeyError: def authorizer(userdata, action, arg1, arg2, dbname, source): try: return int(callback(action, arg1, arg2, dbname, source)) except Exception: return SQLITE_DENY - c_authorizer = AUTHORIZER(authorizer) + c_authorizer = _AUTHORIZER(authorizer) - self.func_cache[callback] = c_authorizer, authorizer + self.__func_cache[callback] = c_authorizer, authorizer - ret = sqlite.sqlite3_set_authorizer(self.db, + ret = sqlite.sqlite3_set_authorizer(self._db, c_authorizer, None) if ret != SQLITE_OK: @@ -691,10 +699,10 @@ @_check_closed_wrap def set_progress_handler(self, callable, nsteps): if callable is None: - c_progress_handler = cast(None, PROGRESS) + c_progress_handler = cast(None, _PROGRESS) else: try: - c_progress_handler, _ = self.func_cache[callable] + c_progress_handler, _ = self.__func_cache[callable] except KeyError: def progress_handler(userdata): try: @@ -703,156 +711,179 @@ except Exception: # abort query if error occurred return 1 - c_progress_handler = PROGRESS(progress_handler) + c_progress_handler = _PROGRESS(progress_handler) - self.func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self.db, nsteps, + self.__func_cache[callable] = c_progress_handler, progress_handler + ret = sqlite.sqlite3_progress_handler(self._db, nsteps, c_progress_handler, None) if ret != SQLITE_OK: raise self._get_exception(ret) - def _get_isolation_level(self): + def __get_total_changes(self): + self._check_closed() + return sqlite.sqlite3_total_changes(self._db) + total_changes = property(__get_total_changes) + + def __get_isolation_level(self): return self._isolation_level - def _get_total_changes(self): - self._check_closed() - return sqlite.sqlite3_total_changes(self.db) - total_changes = property(_get_total_changes) - - def _set_isolation_level(self, val): + def __set_isolation_level(self, val): if val is None: self.commit() + else: + self.__begin_statement = 'BEGIN ' + val self._isolation_level = val - isolation_level = property(_get_isolation_level, _set_isolation_level) + isolation_level = property(__get_isolation_level, __set_isolation_level) - if HAS_LOAD_EXTENSION: + if _HAS_LOAD_EXTENSION: @_check_thread_wrap @_check_closed_wrap def enable_load_extension(self, enabled): - rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled)) + rc = sqlite.sqlite3_enable_load_extension(self._db, int(enabled)) if rc != SQLITE_OK: raise OperationalError("Error enabling load extension") -class CursorLock(object): +class _CursorLock(object): def __init__(self, cursor): self.cursor = cursor def __enter__(self): - if self.cursor.locked: + self.cursor._check_closed() + if self.cursor._locked: raise ProgrammingError("Recursive use of cursors not allowed.") - self.cursor.locked = True + self.cursor._locked = True def __exit__(self, *args): - self.cursor.locked = False + self.cursor._locked = False class Cursor(object): - initialized = False + __initialized = False + __connection = None + __statement = None def __init__(self, con): + self.__initialized = True + self.__connection = con + if not isinstance(con, Connection): raise TypeError con._check_thread() con._check_closed() - con.cursors.append(weakref.ref(self)) - self.connection = con - self._description = None + con._cursors.append(weakref.ref(self)) + self.arraysize = 1 self.row_factory = None - self.rowcount = -1 - self.statement = None - self.reset = False - self.locked = False - self.closed = False - self.initialized = True + self._locked = False + self._reset = False + self.__closed = False + self.__description = None + self.__rowcount = -1 + + def __del__(self): + if self.__connection: + try: + self.__connection._cursors.remove(weakref.ref(self)) + except ValueError: + pass + if self.__statement: + self.__statement.reset() + + def close(self): + self.__connection._check_thread() + self.__connection._check_closed() + if self.__statement: + self.__statement.reset() + self.__statement = None + self.__closed = True def _check_closed(self): - if not self.initialized: + if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") - if self.closed: + if self.__closed: raise ProgrammingError("Cannot operate on a closed cursor.") - self.connection._check_thread() - self.connection._check_closed() - - def _check_and_lock(self): - self._check_closed() - return CursorLock(self) + self.__connection._check_thread() + self.__connection._check_closed() def execute(self, sql, params=None): - with self._check_and_lock(): - self._description = None - self.reset = False - self.statement = self.connection.statement_cache.get( + with _CursorLock(self): + self.__description = None + self._reset = False + self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) - if self.connection._isolation_level is not None: - if self.statement.kind == DDL: - self.connection.commit() - elif self.statement.kind == DML: - self.connection._begin() + if self.__connection._isolation_level is not None: + if self.__statement.kind == _DDL: + if self.__connection._in_transaction: + self.__connection.commit() + elif self.__statement.kind == _DML: + if not self.__connection._in_transaction: + self.__connection._begin() - self.statement.set_params(params) + self.__statement.set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.statement.statement) + ret = sqlite.sqlite3_step(self.__statement.statement) if ret not in (SQLITE_DONE, SQLITE_ROW): - self.statement.reset() - raise self.connection._get_exception(ret) + self.__statement.reset() + self.__connection._in_transaction = \ + not sqlite.sqlite3_get_autocommit(self.__connection._db) + raise self.__connection._get_exception(ret) - if self.statement.kind == DML: - self.statement.reset() + if self.__statement.kind == _DML: + self.__statement.reset() - if self.statement.kind == DQL and ret == SQLITE_ROW: - self.statement._build_row_cast_map() - self.statement._readahead(self) + if self.__statement.kind == _DQL and ret == SQLITE_ROW: + self.__statement._build_row_cast_map() + self.__statement._readahead(self) else: - self.statement.item = None - self.statement.exhausted = True + self.__statement.item = None + self.__statement.exhausted = True - self.rowcount = -1 - if self.statement.kind == DML: - self.rowcount = sqlite.sqlite3_changes(self.connection.db) + self.__rowcount = -1 + if self.__statement.kind == _DML: + self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) return self def executemany(self, sql, many_params): - with self._check_and_lock(): - self._description = None - self.reset = False - self.statement = self.connection.statement_cache.get( + with _CursorLock(self): + self.__description = None + self._reset = False + self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) - if self.statement.kind == DML: - self.connection._begin() + if self.__statement.kind == _DML: + if self.__connection._isolation_level is not None: + if not self.__connection._in_transaction: + self.__connection._begin() else: raise ProgrammingError("executemany is only for DML statements") - self.rowcount = 0 + self.__rowcount = 0 for params in many_params: - self.statement.set_params(params) - ret = sqlite.sqlite3_step(self.statement.statement) + self.__statement.set_params(params) + ret = sqlite.sqlite3_step(self.__statement.statement) if ret != SQLITE_DONE: - raise self.connection._get_exception(ret) - self.rowcount += sqlite.sqlite3_changes(self.connection.db) + raise self.__connection._get_exception(ret) + self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) return self def executescript(self, sql): - self._description = None - self.reset = False - if type(sql) is str: - sql = sql.encode("utf-8") + self.__description = None + self._reset = False self._check_closed() statement = c_void_p() c_sql = c_char_p(sql) - self.connection.commit() + self.__connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.connection.db, c_sql, -1, byref(statement), byref(c_sql)) + rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) if rc != SQLITE_OK: - raise self.connection._get_exception(rc) + raise self.__connection._get_exception(rc) rc = SQLITE_ROW while rc == SQLITE_ROW: @@ -866,21 +897,18 @@ if rc == SQLITE_OK: return self else: - raise self.connection._get_exception(rc) + raise self.__connection._get_exception(rc) rc = sqlite.sqlite3_finalize(statement) if rc != SQLITE_OK: - raise self.connection._get_exception(rc) + raise self.__connection._get_exception(rc) if not c_sql.value: break return self - def __iter__(self): - return iter(self.fetchone, None) - def _check_reset(self): - if self.reset: - raise self.connection.InterfaceError("Cursor needed to be reset because " + if self._reset: + raise self.__connection.InterfaceError("Cursor needed to be reset because " "of commit/rollback and can " "no longer be fetched from.") @@ -889,18 +917,18 @@ self._check_closed() self._check_reset() - if self.statement is None: + if self.__statement is None: return None try: - return self.statement.next(self) + return self.__statement.next(self) except StopIteration: return None def fetchmany(self, size=None): self._check_closed() self._check_reset() - if self.statement is None: + if self.__statement is None: return [] if size is None: size = self.arraysize @@ -914,34 +942,30 @@ def fetchall(self): self._check_closed() self._check_reset() - if self.statement is None: + if self.__statement is None: return [] return list(self) - def _getdescription(self): - if self._description is None: - self._description = self.statement._get_description() - return self._description + def __iter__(self): + return iter(self.fetchone, None) - def _getlastrowid(self): - return sqlite.sqlite3_last_insert_rowid(self.connection.db) + def __get_connection(self): + return self.__connection + connection = property(__get_connection) - def close(self): - self.connection._check_thread() - self.connection._check_closed() - if self.statement: - self.statement.reset() - self.statement = None - self.closed = True + def __get_rowcount(self): + return self.__rowcount + rowcount = property(__get_rowcount) - def __del__(self): - if self.initialized: - if self.statement: - self.statement.reset() - try: - self.connection.cursors.remove(weakref.ref(self)) - except ValueError: - pass + def __get_description(self): + if self.__description is None: + self.__description = self.__statement._get_description() + return self.__description + description = property(__get_description) + + def __get_lastrowid(self): + return sqlite.sqlite3_last_insert_rowid(self.__connection._db) + lastrowid = property(__get_lastrowid) def setinputsizes(self, *args): pass @@ -949,9 +973,6 @@ def setoutputsize(self, *args): pass - description = property(_getdescription) - lastrowid = property(_getlastrowid) - class Statement(object): statement = None @@ -963,11 +984,11 @@ self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): - self.kind = DML + self.kind = _DML elif first_word in ("SELECT", "PRAGMA"): - self.kind = DQL + self.kind = _DQL else: - self.kind = DDL + self.kind = _DDL self.exhausted = False self.in_use = False # @@ -977,11 +998,11 @@ self.statement = c_void_p() next_char = c_char_p() sql_char = sql - ret = sqlite.sqlite3_prepare_v2(self.con.db, sql_char, -1, byref(self.statement), byref(next_char)) + ret = sqlite.sqlite3_prepare_v2(self.con._db, sql_char, -1, byref(self.statement), byref(next_char)) if ret == SQLITE_OK and self.statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.con.db, "select 42", -1, byref(self.statement), byref(next_char)) - self.kind = DQL + ret = sqlite.sqlite3_prepare_v2(self.con._db, "select 42", -1, byref(self.statement), byref(next_char)) + self.kind = _DQL if ret != SQLITE_OK: raise self.con._get_exception(ret) @@ -1002,7 +1023,7 @@ for i in range(sqlite.sqlite3_column_count(self.statement)): converter = None - if self.con.detect_types & PARSE_COLNAMES: + if self.con._detect_types & PARSE_COLNAMES: colname = sqlite.sqlite3_column_name(self.statement, i) if colname is not None: colname = colname.decode('utf-8') @@ -1015,7 +1036,7 @@ key = colname[type_start:pos] converter = converters[key.upper()] - if converter is None and self.con.detect_types & PARSE_DECLTYPES: + if converter is None and self.con._detect_types & PARSE_DECLTYPES: decltype = sqlite.sqlite3_column_decltype(self.statement, i) if decltype is not None: decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" @@ -1166,7 +1187,7 @@ sqlite.sqlite3_finalize(self.statement) def _get_description(self): - if self.kind == DML: + if self.kind == _DML: return None desc = [] for i in range(sqlite.sqlite3_column_count(self.statement)): @@ -1306,25 +1327,25 @@ else: _convert_result(context, val) -FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -FINAL = CFUNCTYPE(None, c_void_p) -sqlite.sqlite3_create_function.argtypes = [c_void_p, TEXT, c_int, c_int, c_void_p, FUNC, STEP, FINAL] +_FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) +_STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) +_FINAL = CFUNCTYPE(None, c_void_p) +sqlite.sqlite3_create_function.argtypes = [c_void_p, TEXT, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] sqlite.sqlite3_create_function.restype = c_int sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] sqlite.sqlite3_aggregate_context.restype = c_void_p -COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -sqlite.sqlite3_create_collation.argtypes = [c_void_p, TEXT, c_int, c_void_p, COLLATION] +_COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) +sqlite.sqlite3_create_collation.argtypes = [c_void_p, TEXT, c_int, c_void_p, _COLLATION] sqlite.sqlite3_create_collation.restype = c_int -PROGRESS = CFUNCTYPE(c_int, c_void_p) -sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, PROGRESS, c_void_p] +_PROGRESS = CFUNCTYPE(c_int, c_void_p) +sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p] sqlite.sqlite3_progress_handler.restype = c_int -AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) -sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, AUTHORIZER, c_void_p] +_AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) +sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p] sqlite.sqlite3_set_authorizer.restype = c_int converters = {} 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 @@ -63,13 +63,13 @@ def test_cursor_del(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') - stmt = cur.statement + stmt = cur._Cursor__statement cur.close() cur = con.execute('select 1') - assert cur.statement is stmt + assert cur._Cursor__statement is stmt del cur; import gc; gc.collect(); gc.collect() cur = con.execute('select 1') - assert cur.statement is stmt + assert cur._Cursor__statement is stmt @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_connection_del(tmpdir): From noreply at buildbot.pypy.org Wed Mar 6 06:26:05 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 06:26:05 +0100 (CET) Subject: [pypy-commit] pypy py3k: some fixes for _sqlite3 on py3k Message-ID: <20130306052605.9D0091C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62118:94919475f7b5 Date: 2013-03-06 00:25 -0500 http://bitbucket.org/pypy/pypy/changeset/94919475f7b5/ Log: some fixes for _sqlite3 on py3k diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -215,7 +215,7 @@ sqlite.sqlite3_libversion.restype = c_char_p sqlite.sqlite3_open.argtypes = [TEXT, c_void_p] sqlite.sqlite3_open.restype = c_int -sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] +sqlite.sqlite3_prepare.argtypes = [c_void_p, TEXT, c_int, c_void_p, POINTER(c_char_p)] sqlite.sqlite3_prepare.restype = c_int sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, TEXT, c_int, c_void_p, POINTER(c_char_p)] sqlite.sqlite3_prepare_v2.restype = c_int @@ -720,6 +720,10 @@ if ret != SQLITE_OK: raise self._get_exception(ret) + def __get_in_transaction(self): + return self._in_transaction + in_transaction = property(__get_in_transaction) + def __get_total_changes(self): self._check_closed() return sqlite.sqlite3_total_changes(self._db) @@ -877,11 +881,12 @@ self._reset = False self._check_closed() statement = c_void_p() - c_sql = c_char_p(sql) + next_char = c_char_p() + c_sql = sql self.__connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) + rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(next_char)) if rc != SQLITE_OK: raise self.__connection._get_exception(rc) @@ -902,7 +907,7 @@ if rc != SQLITE_OK: raise self.__connection._get_exception(rc) - if not c_sql.value: + if not next_char.value: break return self From noreply at buildbot.pypy.org Wed Mar 6 07:50:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 07:50:25 +0100 (CET) Subject: [pypy-commit] pypy py3k: more _sqlite3 fixes Message-ID: <20130306065025.3E3EC1C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62119:4824ebaf6a55 Date: 2013-03-06 01:50 -0500 http://bitbucket.org/pypy/pypy/changeset/4824ebaf6a55/ Log: more _sqlite3 fixes diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -215,7 +215,7 @@ sqlite.sqlite3_libversion.restype = c_char_p sqlite.sqlite3_open.argtypes = [TEXT, c_void_p] sqlite.sqlite3_open.restype = c_int -sqlite.sqlite3_prepare.argtypes = [c_void_p, TEXT, c_int, c_void_p, POINTER(c_char_p)] +sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] sqlite.sqlite3_prepare.restype = c_int sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, TEXT, c_int, c_void_p, POINTER(c_char_p)] sqlite.sqlite3_prepare_v2.restype = c_int @@ -879,14 +879,15 @@ def executescript(self, sql): self.__description = None self._reset = False + if type(sql) is str: + sql = sql.encode("utf-8") self._check_closed() statement = c_void_p() - next_char = c_char_p() - c_sql = sql + c_sql = c_char_p(sql) self.__connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(next_char)) + rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) if rc != SQLITE_OK: raise self.__connection._get_exception(rc) @@ -907,7 +908,7 @@ if rc != SQLITE_OK: raise self.__connection._get_exception(rc) - if not next_char.value: + if not c_sql.value: break return self @@ -1061,7 +1062,7 @@ if param is None: sqlite.sqlite3_bind_null(self.statement, idx) - elif type(param) in (bool, int, int): + elif type(param) in (bool, int): if -2147483648 <= param <= 2147483647: sqlite.sqlite3_bind_int(self.statement, idx, param) else: From noreply at buildbot.pypy.org Wed Mar 6 08:17:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 08:17:20 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _sqlite3 'on conflict rollback' in executemany Message-ID: <20130306071720.C8BB81C106A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62120:da02a02dadeb Date: 2013-03-06 02:15 -0500 http://bitbucket.org/pypy/pypy/changeset/da02a02dadeb/ Log: test and fix for _sqlite3 'on conflict rollback' in executemany diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -867,8 +867,12 @@ self.__statement.set_params(params) ret = sqlite.sqlite3_step(self.__statement.statement) if ret != SQLITE_DONE: + self.__statement.reset() + self.__connection._in_transaction = \ + not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) + self.__statement.reset() return self 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 @@ -106,3 +106,20 @@ open_many(True) finally: resource.setrlimit(resource.RLIMIT_NOFILE, limit) + +def test_on_conflict_rollback_executemany(): + major, minor, micro = _sqlite3.sqlite_version.split('.') + if (int(major), int(minor), int(micro)) < (3, 2, 2): + pytest.skip("requires sqlite3 version >= 3.2.2") + con = _sqlite3.connect(":memory:") + con.execute("create table foo(x, unique(x) on conflict rollback)") + con.execute("insert into foo(x) values (1)") + try: + con.executemany("insert into foo(x) values (?)", [[1]]) + except _sqlite3.DatabaseError: + pass + con.execute("insert into foo(x) values (2)") + try: + con.commit() + except _sqlite3.OperationalError: + pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") From noreply at buildbot.pypy.org Wed Mar 6 08:17:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 08:17:23 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130306071723.D3FB21C01D2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62121:6c374f053724 Date: 2013-03-06 02:16 -0500 http://bitbucket.org/pypy/pypy/changeset/6c374f053724/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -867,8 +867,12 @@ self.__statement.set_params(params) ret = sqlite.sqlite3_step(self.__statement.statement) if ret != SQLITE_DONE: + self.__statement.reset() + self.__connection._in_transaction = \ + not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) + self.__statement.reset() return self 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 @@ -106,3 +106,20 @@ open_many(True) finally: resource.setrlimit(resource.RLIMIT_NOFILE, limit) + +def test_on_conflict_rollback_executemany(): + major, minor, micro = _sqlite3.sqlite_version.split('.') + if (int(major), int(minor), int(micro)) < (3, 2, 2): + pytest.skip("requires sqlite3 version >= 3.2.2") + con = _sqlite3.connect(":memory:") + con.execute("create table foo(x, unique(x) on conflict rollback)") + con.execute("insert into foo(x) values (1)") + try: + con.executemany("insert into foo(x) values (?)", [[1]]) + except _sqlite3.DatabaseError: + pass + con.execute("insert into foo(x) values (2)") + try: + con.commit() + except _sqlite3.OperationalError: + pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") From noreply at buildbot.pypy.org Wed Mar 6 08:17:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 08:17:25 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130306071725.658451C01D2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62122:6938c45d35ce Date: 2013-03-06 02:17 -0500 http://bitbucket.org/pypy/pypy/changeset/6938c45d35ce/ Log: merge heads diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -720,6 +720,10 @@ if ret != SQLITE_OK: raise self._get_exception(ret) + def __get_in_transaction(self): + return self._in_transaction + in_transaction = property(__get_in_transaction) + def __get_total_changes(self): self._check_closed() return sqlite.sqlite3_total_changes(self._db) @@ -879,6 +883,8 @@ def executescript(self, sql): self.__description = None self._reset = False + if type(sql) is str: + sql = sql.encode("utf-8") self._check_closed() statement = c_void_p() c_sql = c_char_p(sql) @@ -1060,7 +1066,7 @@ if param is None: sqlite.sqlite3_bind_null(self.statement, idx) - elif type(param) in (bool, int, int): + elif type(param) in (bool, int): if -2147483648 <= param <= 2147483647: sqlite.sqlite3_bind_int(self.statement, idx, param) else: From noreply at buildbot.pypy.org Wed Mar 6 09:35:12 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 09:35:12 +0100 (CET) Subject: [pypy-commit] pypy default: simplify sqlite cursor locking Message-ID: <20130306083512.0C4D31C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62123:92298f0e65e7 Date: 2013-03-06 02:35 -0500 http://bitbucket.org/pypy/pypy/changeset/92298f0e65e7/ Log: simplify sqlite cursor locking diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -739,20 +739,6 @@ raise OperationalError("Error enabling load extension") -class _CursorLock(object): - def __init__(self, cursor): - self.cursor = cursor - - def __enter__(self): - self.cursor._check_closed() - if self.cursor._locked: - raise ProgrammingError("Recursive use of cursors not allowed.") - self.cursor._locked = True - - def __exit__(self, *args): - self.cursor._locked = False - - class Cursor(object): __initialized = False __connection = None @@ -770,8 +756,8 @@ self.arraysize = 1 self.row_factory = None - self._locked = False self._reset = False + self.__locked = False self.__closed = False self.__description = None self.__rowcount = -1 @@ -798,6 +784,8 @@ raise ProgrammingError("Base Cursor.__init__ not called.") if self.__closed: raise ProgrammingError("Cannot operate on a closed cursor.") + if self.__locked: + raise ProgrammingError("Recursive use of cursors not allowed.") self.__connection._check_thread() self.__connection._check_closed() @@ -805,7 +793,9 @@ if type(sql) is unicode: sql = sql.encode("utf-8") - with _CursorLock(self): + self._check_closed() + self.__locked = True + try: self.__description = None self._reset = False self.__statement = self.__connection._statement_cache.get( @@ -842,6 +832,8 @@ self.__rowcount = -1 if self.__statement.kind == _DML: self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) + finally: + self.__locked = False return self @@ -849,7 +841,9 @@ if type(sql) is unicode: sql = sql.encode("utf-8") - with _CursorLock(self): + self._check_closed() + self.__locked = True + try: self.__description = None self._reset = False self.__statement = self.__connection._statement_cache.get( @@ -873,6 +867,8 @@ raise self.__connection._get_exception(ret) self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) self.__statement.reset() + finally: + self.__locked = False return self From noreply at buildbot.pypy.org Wed Mar 6 09:35:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 09:35:13 +0100 (CET) Subject: [pypy-commit] pypy default: mangle these implementation-specific function names Message-ID: <20130306083513.5831E1C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62124:c02d9c36ffa2 Date: 2013-03-06 02:40 -0500 http://bitbucket.org/pypy/pypy/changeset/c02d9c36ffa2/ Log: mangle these implementation-specific function names diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -779,7 +779,7 @@ self.__statement = None self.__closed = True - def _check_closed(self): + def __check_cursor(self): if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") if self.__closed: @@ -793,7 +793,7 @@ if type(sql) is unicode: sql = sql.encode("utf-8") - self._check_closed() + self.__check_cursor() self.__locked = True try: self.__description = None @@ -841,7 +841,7 @@ if type(sql) is unicode: sql = sql.encode("utf-8") - self._check_closed() + self.__check_cursor() self.__locked = True try: self.__description = None @@ -877,7 +877,7 @@ self._reset = False if type(sql) is unicode: sql = sql.encode("utf-8") - self._check_closed() + self.__check_cursor() statement = c_void_p() c_sql = c_char_p(sql) @@ -908,7 +908,7 @@ break return self - def _check_reset(self): + def __check_reset(self): if self._reset: raise self.__connection.InterfaceError("Cursor needed to be reset because " "of commit/rollback and can " @@ -916,8 +916,8 @@ # do all statements def fetchone(self): - self._check_closed() - self._check_reset() + self.__check_cursor() + self.__check_reset() if self.__statement is None: return None @@ -928,8 +928,8 @@ return None def fetchmany(self, size=None): - self._check_closed() - self._check_reset() + self.__check_cursor() + self.__check_reset() if self.__statement is None: return [] if size is None: @@ -942,8 +942,8 @@ return lst def fetchall(self): - self._check_closed() - self._check_reset() + self.__check_cursor() + self.__check_reset() if self.__statement is None: return [] return list(self) From noreply at buildbot.pypy.org Wed Mar 6 09:35:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 09:35:14 +0100 (CET) Subject: [pypy-commit] pypy default: additional small cleanups for sqlite Message-ID: <20130306083514.88CCA1C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62125:51cce4632d7c Date: 2013-03-06 02:56 -0500 http://bitbucket.org/pypy/pypy/changeset/51cce4632d7c/ Log: additional small cleanups for sqlite diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -284,13 +284,16 @@ return unicode(x, 'utf-8') -class StatementCache(object): +class _StatementCache(object): def __init__(self, connection, maxcount): self.connection = connection self.maxcount = maxcount self.cache = OrderedDict() def get(self, sql, row_factory): + if isinstance(sql, unicode): + sql = sql.encode('utf-8') + try: stat = self.cache[sql] except KeyError: @@ -298,7 +301,7 @@ self.cache[sql] = stat if len(self.cache) > self.maxcount: self.cache.popitem(0) - # + if stat.in_use: stat = Statement(self.connection, sql) stat.set_row_factory(row_factory) @@ -330,7 +333,7 @@ self._cursors = [] self.__statements = [] self.__statement_counter = 0 - self._statement_cache = StatementCache(self, cached_statements) + self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} self.__aggregates = {} @@ -376,10 +379,10 @@ def _check_closed_wrap(func): @wraps(func) - def _check_closed_func(self, *args, **kwargs): + def wrapper(self, *args, **kwargs): self._check_closed() return func(self, *args, **kwargs) - return _check_closed_func + return wrapper def _check_thread(self): try: @@ -395,10 +398,10 @@ def _check_thread_wrap(func): @wraps(func) - def _check_thread_func(self, *args, **kwargs): + def wrapper(self, *args, **kwargs): self._check_thread() return func(self, *args, **kwargs) - return _check_thread_func + return wrapper def _get_exception(self, error_code=None): if error_code is None: @@ -441,8 +444,7 @@ def __call__(self, sql): if not isinstance(sql, (str, unicode)): raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self._statement_cache.get(sql, self.row_factory) - return statement + return self._statement_cache.get(sql, self.row_factory) def cursor(self, factory=None): self._check_thread() @@ -790,9 +792,6 @@ self.__connection._check_closed() def execute(self, sql, params=None): - if type(sql) is unicode: - sql = sql.encode("utf-8") - self.__check_cursor() self.__locked = True try: @@ -838,9 +837,6 @@ return self def executemany(self, sql, many_params): - if type(sql) is unicode: - sql = sql.encode("utf-8") - self.__check_cursor() self.__locked = True try: @@ -910,9 +906,9 @@ def __check_reset(self): if self._reset: - raise self.__connection.InterfaceError("Cursor needed to be reset because " - "of commit/rollback and can " - "no longer be fetched from.") + raise self.__connection.InterfaceError( + "Cursor needed to be reset because of commit/rollback " + "and can no longer be fetched from.") # do all statements def fetchone(self): From noreply at buildbot.pypy.org Wed Mar 6 09:46:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 09:46:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130306084608.A0D3C1C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62126:878a364bd84f Date: 2013-03-06 03:45 -0500 http://bitbucket.org/pypy/pypy/changeset/878a364bd84f/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -291,7 +291,7 @@ return str(x, 'utf-8') -class StatementCache(object): +class _StatementCache(object): def __init__(self, connection, maxcount): self.connection = connection self.maxcount = maxcount @@ -305,7 +305,7 @@ self.cache[sql] = stat if len(self.cache) > self.maxcount: self.cache.popitem(0) - # + if stat.in_use: stat = Statement(self.connection, sql) stat.set_row_factory(row_factory) @@ -337,7 +337,7 @@ self._cursors = [] self.__statements = [] self.__statement_counter = 0 - self._statement_cache = StatementCache(self, cached_statements) + self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} self.__aggregates = {} @@ -383,10 +383,10 @@ def _check_closed_wrap(func): @wraps(func) - def _check_closed_func(self, *args, **kwargs): + def wrapper(self, *args, **kwargs): self._check_closed() return func(self, *args, **kwargs) - return _check_closed_func + return wrapper def _check_thread(self): try: @@ -402,10 +402,10 @@ def _check_thread_wrap(func): @wraps(func) - def _check_thread_func(self, *args, **kwargs): + def wrapper(self, *args, **kwargs): self._check_thread() return func(self, *args, **kwargs) - return _check_thread_func + return wrapper def _get_exception(self, error_code=None): if error_code is None: @@ -449,8 +449,7 @@ def __call__(self, sql): if not isinstance(sql, str): raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self._statement_cache.get(sql, self.row_factory) - return statement + return self._statement_cache.get(sql, self.row_factory) def cursor(self, factory=None): self._check_thread() @@ -749,20 +748,6 @@ raise OperationalError("Error enabling load extension") -class _CursorLock(object): - def __init__(self, cursor): - self.cursor = cursor - - def __enter__(self): - self.cursor._check_closed() - if self.cursor._locked: - raise ProgrammingError("Recursive use of cursors not allowed.") - self.cursor._locked = True - - def __exit__(self, *args): - self.cursor._locked = False - - class Cursor(object): __initialized = False __connection = None @@ -780,8 +765,8 @@ self.arraysize = 1 self.row_factory = None - self._locked = False self._reset = False + self.__locked = False self.__closed = False self.__description = None self.__rowcount = -1 @@ -803,16 +788,20 @@ self.__statement = None self.__closed = True - def _check_closed(self): + def __check_cursor(self): if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") if self.__closed: raise ProgrammingError("Cannot operate on a closed cursor.") + if self.__locked: + raise ProgrammingError("Recursive use of cursors not allowed.") self.__connection._check_thread() self.__connection._check_closed() def execute(self, sql, params=None): - with _CursorLock(self): + self.__check_cursor() + self.__locked = True + try: self.__description = None self._reset = False self.__statement = self.__connection._statement_cache.get( @@ -849,11 +838,15 @@ self.__rowcount = -1 if self.__statement.kind == _DML: self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) + finally: + self.__locked = False return self def executemany(self, sql, many_params): - with _CursorLock(self): + self.__check_cursor() + self.__locked = True + try: self.__description = None self._reset = False self.__statement = self.__connection._statement_cache.get( @@ -877,6 +870,8 @@ raise self.__connection._get_exception(ret) self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) self.__statement.reset() + finally: + self.__locked = False return self @@ -885,7 +880,7 @@ self._reset = False if type(sql) is str: sql = sql.encode("utf-8") - self._check_closed() + self.__check_cursor() statement = c_void_p() c_sql = c_char_p(sql) @@ -916,16 +911,16 @@ break return self - def _check_reset(self): + def __check_reset(self): if self._reset: - raise self.__connection.InterfaceError("Cursor needed to be reset because " - "of commit/rollback and can " - "no longer be fetched from.") + raise self.__connection.InterfaceError( + "Cursor needed to be reset because of commit/rollback " + "and can no longer be fetched from.") # do all statements def fetchone(self): - self._check_closed() - self._check_reset() + self.__check_cursor() + self.__check_reset() if self.__statement is None: return None @@ -936,8 +931,8 @@ return None def fetchmany(self, size=None): - self._check_closed() - self._check_reset() + self.__check_cursor() + self.__check_reset() if self.__statement is None: return [] if size is None: @@ -950,8 +945,8 @@ return lst def fetchall(self): - self._check_closed() - self._check_reset() + self.__check_cursor() + self.__check_reset() if self.__statement is None: return [] return list(self) From noreply at buildbot.pypy.org Wed Mar 6 09:57:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 09:57:56 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for sqlite check_cursor behavior Message-ID: <20130306085756.B52F01C01D2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62127:cdcf1ad3fcbe Date: 2013-03-06 03:57 -0500 http://bitbucket.org/pypy/pypy/changeset/cdcf1ad3fcbe/ Log: test and fix for sqlite check_cursor behavior diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -791,8 +791,15 @@ self.__connection._check_thread() self.__connection._check_closed() + def __check_cursor_wrap(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + self.__check_cursor() + return func(self, *args, **kwargs) + return wrapper + + @__check_cursor_wrap def execute(self, sql, params=None): - self.__check_cursor() self.__locked = True try: self.__description = None @@ -836,8 +843,8 @@ return self + @__check_cursor_wrap def executemany(self, sql, many_params): - self.__check_cursor() self.__locked = True try: self.__description = None 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 @@ -58,6 +58,9 @@ cur.close() con.close() pytest.raises(_sqlite3.ProgrammingError, "cur.close()") + # raises ProgrammingError because should check closed before check args + pytest.raises(_sqlite3.ProgrammingError, "cur.execute(1,2,3,4,5)") + pytest.raises(_sqlite3.ProgrammingError, "cur.executemany(1,2,3,4,5)") @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_cursor_del(): From noreply at buildbot.pypy.org Wed Mar 6 11:59:05 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 6 Mar 2013 11:59:05 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: Temporarily rename array's itemsize to itemsize_ to work around an annotator bug. Message-ID: <20130306105905.935CC1C13EB@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62128:45b480dc2f6d Date: 2013-03-06 10:49 +0100 http://bitbucket.org/pypy/pypy/changeset/45b480dc2f6d/ Log: Temporarily rename array's itemsize to itemsize_ to work around an annotator bug. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -83,7 +83,7 @@ def descr_itemsize(space, self): - return space.wrap(self.itemsize) + return space.wrap(self.itemsize_) def descr_typecode(space, self): @@ -157,7 +157,7 @@ def __init__(self, array): self.array = array self.format = array.typecode - self.itemsize = array.itemsize + self.itemsize = array.itemsize_ def getlength(self): return self.array.len @@ -203,7 +203,7 @@ W_ArrayBase = globals()['W_ArrayBase'] class W_Array(W_ArrayBase): - itemsize = mytype.bytes + itemsize_ = mytype.bytes typecode = mytype.typecode @staticmethod @@ -321,7 +321,7 @@ self.setlen(oldlen + i) def fromstring(self, s): - if len(s) % self.itemsize != 0: + if len(s) % self.itemsize_ != 0: msg = 'string length not a multiple of item size' raise OperationError(self.space.w_ValueError, self.space.wrap(msg)) oldlen = self.len @@ -598,14 +598,14 @@ n = space.int_w(w_n) try: - size = ovfcheck(self.itemsize * n) + size = ovfcheck(self.itemsize_ * n) except OverflowError: raise MemoryError w_item = space.call_method(w_f, 'read', space.wrap(size)) item = space.bytes_w(w_item) if len(item) < size: - n = len(item) % self.itemsize - elems = max(0, len(item) - (len(item) % self.itemsize)) + n = len(item) % self.itemsize_ + elems = max(0, len(item) - (len(item) % self.itemsize_)) if n != 0: item = item[0:elems] w_item = space.wrapbytes(item) From noreply at buildbot.pypy.org Wed Mar 6 11:59:07 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 6 Mar 2013 11:59:07 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: Python 3.2 supports tolist() only on byte memoryviews. Message-ID: <20130306105907.120731C13EB@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62129:b1c812a69e23 Date: 2013-03-06 11:54 +0100 http://bitbucket.org/pypy/pypy/changeset/b1c812a69e23/ Log: Python 3.2 supports tolist() only on byte memoryviews. diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py --- a/pypy/module/__builtin__/interp_memoryview.py +++ b/pypy/module/__builtin__/interp_memoryview.py @@ -78,9 +78,12 @@ def descr_tolist(self, space): self._check_released(space) buf = self.buf + if buf.format != 'B': + raise OperationError(space.w_NotImplementedError, space.wrap( + "tolist() only supports byte views")) result = [] for i in range(buf.getlength()): - result.append(space.wrap(ord(buf.getitem(i)))) + result.append(space.wrap(ord(buf.getitem(i)[0]))) return space.newlist(result) def descr_getitem(self, space, w_index): From noreply at buildbot.pypy.org Wed Mar 6 11:59:08 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 6 Mar 2013 11:59:08 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: Mark 'format' and 'itemsize' as immutable fields. Message-ID: <20130306105908.58D431C13EB@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62130:ac19e2710459 Date: 2013-03-06 11:57 +0100 http://bitbucket.org/pypy/pypy/changeset/ac19e2710459/ Log: Mark 'format' and 'itemsize' as immutable fields. diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -27,6 +27,7 @@ """Abstract base class for memory views.""" __slots__ = ('format', 'itemsize') + _immutable_fields_ = ('format', 'itemsize') def getlength(self): raise NotImplementedError From noreply at buildbot.pypy.org Wed Mar 6 15:10:23 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 6 Mar 2013 15:10:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fixes for frame_realloc Message-ID: <20130306141023.DF9B51C01D2@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62131:aea384698a85 Date: 2013-03-06 15:09 +0100 http://bitbucket.org/pypy/pypy/changeset/aea384698a85/ Log: fixes for frame_realloc diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -742,14 +742,14 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - mc.LDR_ri(r.r12.value, r.fp.value, imm=ofs) + mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) stack_check_cmp_ofs = mc.currpos() if expected_size == -1: mc.NOP() mc.NOP() else: mc.gen_load_int(r.lr.value, expected_size) - mc.CMP_rr(r.lr.value, r.ip.value) + mc.CMP_rr(r.ip.value, r.lr.value) jg_location = mc.currpos() mc.BKPT() @@ -805,11 +805,12 @@ # mc.BL(self.cpu.realloc_frame) + # set fp to the new jitframe + mc.MOV_rr(r.fp.value, r.r0.value) + # restore a possibly present exception self._restore_exception(mc, None, r.fp) - # set fp to the new jitframe - mc.MOV_rr(r.fp.value, r.r0.value) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: From noreply at buildbot.pypy.org Wed Mar 6 17:36:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 6 Mar 2013 17:36:23 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: rework numpypy namespace changes (bdk) Message-ID: <20130306163623.B64D81C029E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: extradoc Changeset: r4952:b9c938b296b6 Date: 2013-03-06 18:36 +0200 http://bitbucket.org/pypy/extradoc/changeset/b9c938b296b6/ Log: rework numpypy namespace changes (bdk) diff --git a/blog/draft/numpy-status-update-6.rst b/blog/draft/numpy-status-update-6.rst --- a/blog/draft/numpy-status-update-6.rst +++ b/blog/draft/numpy-status-update-6.rst @@ -17,11 +17,13 @@ * **pickling support for numarray** - hasn't started yet, but next on the list -* There has been some work on exposing FFI routines in numpypy. +* There has been some work on exposing **FFI routines** in numpypy. -* Brian Kearns has made progress in mapping translated _numpypy submodules to - the numpy core c-based submodules, furthering the goal of being able to install - numpy as a pure-python module with few modifications. +* Brian Kearns has made progress in improving the **numpypy namespace**. + The python numpypy submodules now more closely resemble their numpy + counterparts. Also, translated _numpypy submodules are now more properly + mapped to the numpy core c-based submodules, furthering the goal of being + able to install numpy as a pure-python module with few modifications. And now the good news: From noreply at buildbot.pypy.org Wed Mar 6 20:00:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 20:00:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the test Message-ID: <20130306190053.929771C029E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62132:195a90abd218 Date: 2013-03-06 21:00 +0200 http://bitbucket.org/pypy/pypy/changeset/195a90abd218/ Log: fix the test diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -24,7 +24,9 @@ # ====> ../../test/runner_test.py add_loop_instructions = ['ldr', 'mov', 'adds', 'cmp', 'beq', 'b'] - bridge_loop_instructions = ['movw', 'movt', 'bx'] + bridge_loop_instructions = ['ldr', 'mov', 'nop', 'cmp', 'bge', + 'push', 'mov', 'mov', 'push', 'mov', 'mov', + 'blx', 'mov', 'mov', 'bx'] def get_cpu(self): cpu = CPU(rtyper=None, stats=FakeStats()) From noreply at buildbot.pypy.org Wed Mar 6 21:16:28 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:28 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Switched from a context return based implementation to Exception Raising returns. Message-ID: <20130306201628.B5E811C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r121:079f6dd1e62f Date: 2013-03-05 17:14 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/079f6dd1e62f/ Log: Switched from a context return based implementation to Exception Raising returns. This way, contexts are not manipulated during return, but on catching the exception. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -28,8 +28,8 @@ _last_indent = "" jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], - reds=['s_active_context'], - #virtualizables=['s_active_context'], + reds=['mark', 's_context'], + #virtualizables=['s_context'], get_printable_location=get_printable_location ) @@ -60,25 +60,31 @@ s_new_context = w_active_context.as_context_get_shadow(self.space) while True: try: - s_new_context = self.c_loop(s_new_context) + s_new_context = self.c_loop(s_new_context, mark=False) except StackOverflow, e: self.remaining_stack_depth = self.max_stack_depth s_new_context = e.s_context + except Return, nlr: + while s_new_context is not nlr.s_target_context: + s_new_context, _ = s_new_context.s_sender(), s_new_context.mark_returned() + s_new_context.push(nlr.value) - def c_loop(self, s_context): - s_active_context = s_context + def c_loop(self, s_context, mark=True): while True: - pc = s_active_context._pc - method = s_active_context.s_method() + pc = s_context._pc + method = s_context.s_method() self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, - s_active_context=s_active_context) - s_return_to_context = self.step(s_active_context) - if (s_return_to_context is not None - and s_return_to_context is not s_context): - s_active_context.mark_returned() - return s_return_to_context + mark=mark, s_context=s_context) + try: + self.step(s_context) + except Return, nlr: + if nlr.s_target_context is not s_context: + if mark: s_context.mark_returned() + raise nlr + else: + s_context.push(nlr.value) def stack_frame(self, s_new_frame): if not self._loop: @@ -88,8 +94,10 @@ raise StackOverflow(s_new_frame) self.remaining_stack_depth -= 1 - retval = self.c_loop(s_new_frame) - self.remaining_stack_depth += 1 + try: + retval = self.c_loop(s_new_frame) + finally: + self.remaining_stack_depth += 1 return retval def perform(self, w_receiver, selector, *arguments_w): @@ -109,7 +117,11 @@ s_frame.push(w_receiver) s_frame.push_all(list(arguments_w)) try: - s_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self) + try: + s_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self) + except Return, nlr: + s_new_frame = nlr.s_target_context + nlr.s_target_context.push(nlr.value) if s_new_frame == None: # which means that we tried to call a primitive method return s_frame.pop() @@ -125,6 +137,10 @@ class StackOverflow(Exception): def __init__(self, s_top_context): self.s_context = s_top_context +class Return(Exception): + def __init__(self, object, s_context): + self.value = object + self.s_target_context = s_context def make_call_primitive_bytecode(primitive, selector, argcount): def callPrimitive(self, interp, current_bytecode): @@ -281,11 +297,7 @@ # unfortunately, the assert below is not true for some tests # assert self._stack_ptr == self.tempsize() - # make this context a returned one - self.mark_returned() - - s_return_to.push(return_value) - return s_return_to + raise Return(return_value, s_return_to) def returnReceiver(self, interp, current_bytecode): return self._return(self.w_receiver(), interp, self.s_home().s_sender()) @@ -695,7 +707,7 @@ code.append(" %sif %s:" % (prefix, cond, )) code.append(" return context.%s(self, bytecode)" % (entry[-1], )) prefix = "el" - code.append("bytecode_step_translated._always_inline_ = True") + # code.append("bytecode_step_translated._always_inline_ = True") source = py.code.Source("\n".join(code)) #print source miniglob = {} diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -8,10 +8,13 @@ interp = interpreter.Interpreter(space) def step_in_interp(ctxt): # due to missing resets in between tests interp._loop = False - return_value = interp.step(ctxt) - if return_value is not None: - return return_value.w_self() - return None + try: + retval = interp.step(ctxt) + if retval is not None: + return retval.w_self() + except interpreter.Return, nlr: + nlr.s_target_context.push(nlr.value) + return nlr.s_target_context.w_self() # expose the bytecode's values as global constants. # Bytecodes that have a whole range are exposed as global functions: @@ -988,9 +991,10 @@ assert False try: interp = interpreter.Interpreter(space, None, "", max_stack_depth=10) + interp._loop = True interp.c_loop(w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), [])) except interpreter.StackOverflow, e: - assert e.w_context.getclass(space) is space.w_MethodContext + assert isinstance(e.s_context, shadow.MethodContextShadow) except interpreter.ReturnFromTopLevel, e: assert False From noreply at buildbot.pypy.org Wed Mar 6 21:16:29 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: removed the mark-variable by saving the needed information prior to calling c-loop Message-ID: <20130306201629.DC1101C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r122:ea61821e69dd Date: 2013-03-06 21:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ea61821e69dd/ Log: removed the mark-variable by saving the needed information prior to calling c-loop diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -28,7 +28,7 @@ _last_indent = "" jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], - reds=['mark', 's_context'], + reds=['s_context'], #virtualizables=['s_context'], get_printable_location=get_printable_location ) @@ -59,29 +59,31 @@ self._loop = True s_new_context = w_active_context.as_context_get_shadow(self.space) while True: + s_sender = s_new_context.s_sender() try: - s_new_context = self.c_loop(s_new_context, mark=False) + s_new_context = self.c_loop(s_new_context) except StackOverflow, e: self.remaining_stack_depth = self.max_stack_depth s_new_context = e.s_context except Return, nlr: while s_new_context is not nlr.s_target_context: - s_new_context, _ = s_new_context.s_sender(), s_new_context.mark_returned() + s_new_context.mark_returned() + s_new_context = s_sender s_new_context.push(nlr.value) - def c_loop(self, s_context, mark=True): + def c_loop(self, s_context): while True: pc = s_context._pc method = s_context.s_method() self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, - mark=mark, s_context=s_context) + s_context=s_context) try: self.step(s_context) except Return, nlr: if nlr.s_target_context is not s_context: - if mark: s_context.mark_returned() + s_context.mark_returned() raise nlr else: s_context.push(nlr.value) @@ -707,7 +709,6 @@ code.append(" %sif %s:" % (prefix, cond, )) code.append(" return context.%s(self, bytecode)" % (entry[-1], )) prefix = "el" - # code.append("bytecode_step_translated._always_inline_ = True") source = py.code.Source("\n".join(code)) #print source miniglob = {} From noreply at buildbot.pypy.org Wed Mar 6 21:16:31 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, lwassermann): added attribute information to the model classes to prevent the typechecker from pulling variables up Message-ID: <20130306201631.0C53A1C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r123:cb75ad6978de Date: 2013-03-06 21:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/cb75ad6978de/ Log: (cfbolz, lwassermann): added attribute information to the model classes to prevent the typechecker from pulling variables up In the wake, added some assertions to pacify the typechecker diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -25,7 +25,8 @@ class W_Object(object): """Root of Squeak model, abstract.""" - __slots__ = () # no RPython-level instance variables allowed in W_Object + _attrs_ = [] # no RPython-level instance variables allowed in W_Object + _settled_ = True def size(self): """Return bytesize that conforms to Blue Book. @@ -112,6 +113,7 @@ class W_SmallInteger(W_Object): """Boxed integer value""" # TODO can we tell pypy that its never larger then 31-bit? + _attrs_ = ['value'] __slots__ = ('value',) # the only allowed slot here _immutable_fields_ = ["value"] @@ -152,6 +154,8 @@ class W_Float(W_Object): """Boxed float value.""" + _attrs_ = ['value'] + def __init__(self, value): self.value = value @@ -191,6 +195,8 @@ class W_AbstractObjectWithIdentityHash(W_Object): """Object with explicit hash (ie all except small ints and floats).""" + _attrs_ = ['hash'] + #XXX maybe this is too extreme, but it's very random hash_generator = rrandom.Random() UNASSIGNED_HASH = sys.maxint @@ -215,6 +221,7 @@ class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash): """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" + _attrs_ = ['w_class'] def __init__(self, w_class): if w_class is not None: # it's None only for testing and space generation @@ -251,6 +258,7 @@ class W_PointersObject(W_AbstractObjectWithClassReference): """Common object.""" + _attrs_ = ['_shadow', '_vars'] _shadow = None # Default value @@ -371,6 +379,8 @@ return w_result class W_BytesObject(W_AbstractObjectWithClassReference): + _attrs_ = ['bytes'] + def __init__(self, w_class, size): W_AbstractObjectWithClassReference.__init__(self, w_class) assert isinstance(size, int) @@ -421,6 +431,8 @@ return w_result class W_WordsObject(W_AbstractObjectWithClassReference): + _attrs_ = ['words'] + def __init__(self, w_class, size): W_AbstractObjectWithClassReference.__init__(self, w_class) self.words = [r_uint(0)] * size diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -298,12 +298,16 @@ def attach_shadow(self): AbstractShadow.attach_shadow(self) + w_self = self.w_self() + assert isinstance(w_self, model.W_PointersObject) for i in range(self._w_self_size): self.copy_from_w_self(i) - self.w_self()._vars = None + w_self._vars = None def detach_shadow(self): - self.w_self()._vars = [self.space.w_nil] * self._w_self_size + w_self = self.w_self() + assert isinstance(w_self, model.W_PointersObject) + w_self._vars = [self.space.w_nil] * self._w_self_size for i in range(self._w_self_size): self.copy_to_w_self(i) @@ -325,6 +329,7 @@ def __init__(self, space, w_self): self._s_sender = None AbstractRedirectingShadow.__init__(self, space, w_self) + self.instances_w = None @staticmethod def is_block_context(w_pointers, space): diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -492,24 +492,26 @@ assert s_new_context.w_receiver() is space.w_nil def test_primitive_closure_value_value(): - s_initial_context, closure, s_new_context = build_up_closure_environment(["first arg", "second arg"]) + s_initial_context, closure, s_new_context = build_up_closure_environment([ + wrap("first arg"), wrap("second arg")]) assert s_new_context.w_closure_or_nil is closure assert s_new_context.s_sender() is s_initial_context assert s_new_context.w_receiver() is space.w_nil - assert s_new_context.gettemp(0) == "first arg" - assert s_new_context.gettemp(1) == "second arg" + assert s_new_context.gettemp(0).as_string() == "first arg" + assert s_new_context.gettemp(1).as_string() == "second arg" def test_primitive_closure_value_value_with_temps(): - s_initial_context, closure, s_new_context = build_up_closure_environment(["first arg", "second arg"], - copiedValues=['some value']) + s_initial_context, closure, s_new_context = build_up_closure_environment( + [wrap("first arg"), wrap("second arg")], + copiedValues=[wrap('some value')]) assert s_new_context.w_closure_or_nil is closure assert s_new_context.s_sender() is s_initial_context assert s_new_context.w_receiver() is space.w_nil - assert s_new_context.gettemp(0) == "first arg" - assert s_new_context.gettemp(1) == "second arg" - assert s_new_context.gettemp(2) == "some value" + assert s_new_context.gettemp(0).as_string() == "first arg" + assert s_new_context.gettemp(1).as_string() == "second arg" + assert s_new_context.gettemp(2).as_string() == "some value" def test_primitive_some_instance(): someInstance = map(space.wrap_list, [[1], [2]]) diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -1,5 +1,5 @@ from spyvm import model, constants -from spyvm.error import FatalError, WrapperException +from spyvm.error import FatalError, WrapperException, PrimitiveFailedError class Wrapper(object): def __init__(self, space, w_self): From noreply at buildbot.pypy.org Wed Mar 6 21:16:32 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:32 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, lwassermann): changed the version checker to test for 64bit images only on 64bit systems Message-ID: <20130306201632.1F5E91C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r124:d6155cf750e0 Date: 2013-03-06 21:08 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d6155cf750e0/ Log: (cfbolz, lwassermann): changed the version checker to test for 64bit images only on 64bit systems diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -1,5 +1,6 @@ import py import os +import sys from spyvm import constants from spyvm import model from spyvm.tool.bitmanipulation import splitter @@ -134,6 +135,10 @@ 0x00001969: ImageVersion(6505, True, False, True, True ), 0x69190000: ImageVersion(6505, False, False, True, True ), 0x00000000000109A0: ImageVersion(68000, True, True, False, False), +} + +if sys.maxint == 2 ** 63 - 1: + image_versions.update({ -0x5ff6ff0000000000: # signed version of 0xA009010000000000: ImageVersion(68000, False, True, False, False), @@ -145,7 +150,7 @@ -0x5cf6ff0000000000: # signed version of 0xA309010000000000: ImageVersion(68003, False, True, True, True ), -} +}) def version(magic): diff --git a/spyvm/test/test_squeakimage.py b/spyvm/test/test_squeakimage.py --- a/spyvm/test/test_squeakimage.py +++ b/spyvm/test/test_squeakimage.py @@ -184,6 +184,9 @@ assert r.stream.pos == len(image_2) def test_simple_image64(): + import sys + if not sys.maxint == 2 ** 63 - 1: + py.test.skip("on 32 bit platforms, we can't need to check for 64 bit images") word_size = 8 header_size = 16 * word_size From noreply at buildbot.pypy.org Wed Mar 6 21:16:33 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:33 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, lwassermann): updated the targettinybenchsmalltalk to reflect the jit test changes needed because of interpreter restructuring Message-ID: <20130306201633.28B7A1C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r125:2f7194263d4b Date: 2013-03-06 21:10 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2f7194263d4b/ Log: (tfel, lwassermann): updated the targettinybenchsmalltalk to reflect the jit test changes needed because of interpreter restructuring diff --git a/targettinybenchsmalltalk.py b/targettinybenchsmalltalk.py --- a/targettinybenchsmalltalk.py +++ b/targettinybenchsmalltalk.py @@ -15,45 +15,27 @@ # compile... sys.setrecursionlimit(100000) - -def tinyBenchmarks(): +def setup(): from spyvm import objspace space = objspace.ObjSpace() image = create_testimage(space) - interp = interpreter.Interpreter(space) + interp = interpreter.Interpreter(space, image) + w_selector = interp.perform(space.wrap_string("loopTest"), "asSymbol") + w_object = model.W_SmallInteger(0) + s_class = w_object.shadow_of_my_class(space) + s_method = s_class.lookup(w_selector) + s_frame = s_method.create_frame(space, w_object, []) + return interp, s_frame - w_object = model.W_SmallInteger(0) - - s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("loopTest") - - assert w_method - w_frame = w_method.create_frame(space, w_object, []) - interp.store_w_active_context(w_frame) - - counter = 0 - - from spyvm.interpreter import BYTECODE_TABLE - return interp - - -interp = tinyBenchmarks() - +interp, s_frame = setup() def entry_point(argv): - counter = 0 try: - while True: - counter += 1 - interp.interpret() - if counter == 100000: - counter = 0 - os.write(2, '#') + interp.loop(s_frame.w_self()) except interpreter.ReturnFromTopLevel, e: w_result = e.object - - assert isinstance(w_result, model.W_BytesObject) - print w_result.as_string() + assert isinstance(w_result, model.W_BytesObject) + print w_result.as_string() return 0 From noreply at buildbot.pypy.org Wed Mar 6 21:16:34 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: removed the recursion increasing lines from the test-cases, because they cause segfaults Message-ID: <20130306201634.46D8B1C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r126:c7a6275e8187 Date: 2013-03-06 21:11 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c7a6275e8187/ Log: removed the recursion increasing lines from the test-cases, because they cause segfaults diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -46,7 +46,7 @@ # Tests # -sys.setrecursionlimit(100000) +# sys.setrecursionlimit(100000) class TestLLtype(LLJitMixin): diff --git a/targettinybenchsmalltalk.py b/targettinybenchsmalltalk.py --- a/targettinybenchsmalltalk.py +++ b/targettinybenchsmalltalk.py @@ -13,7 +13,7 @@ # XXX this only compiles if sys.recursionlimit is high enough! # On non-Linux platforms I don't know if there is enough stack to # compile... -sys.setrecursionlimit(100000) +#sys.setrecursionlimit(100000) def setup(): from spyvm import objspace From noreply at buildbot.pypy.org Wed Mar 6 21:16:35 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:16:35 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, lwassermann): Added type-checks in several places to pacify pypy. In most cases, the program will abort, if the wrong types are supplied. Message-ID: <20130306201635.6CA251C01D2@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r127:d0d2369575cf Date: 2013-03-06 21:14 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d0d2369575cf/ Log: (cfbolz, lwassermann): Added type-checks in several places to pacify pypy. In most cases, the program will abort, if the wrong types are supplied. The stack can now only contain model.W_Object-instances. Generic shadows can now only exists for model.W_PointersObject. diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -260,6 +260,10 @@ elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value) raise UnwrappingError() + def unwrap_pointersobject(self, w_v): + if not isinstance(w_v, model.W_PointersObject): + raise UnwrappingError() + return w_v def unwrap_array(self, w_array): # Check that our argument has pointers format and the class: if not w_array.getclass(self).is_same_object(self.w_Array): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -93,6 +93,7 @@ elif spec is float: args += (interp.space.unwrap_float(w_arg), ) elif spec is object: + assert isinstance(w_arg, model.W_Object) args += (w_arg, ) elif spec is str: assert isinstance(w_arg, model.W_BytesObject) @@ -963,7 +964,9 @@ interp.space.w_Process): raise PrimitiveFailedError() s_frame.push(w_rcvr) # w_rcvr is the result in the old frame - return wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self()).as_context_get_shadow(interp.space) + w_frame = wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self()) + w_frame = interp.space.unwrap_pointersobject(w_frame) + return w_frame.as_context_get_shadow(interp.space) @expose_primitive(SUSPEND, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr, result_is_new_frame=True): @@ -972,7 +975,9 @@ interp.space.w_Process): raise PrimitiveFailedError() s_frame.push(w_rcvr) # w_rcvr is the result in the old frame - return wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self()).as_context_get_shadow(interp.space) + w_frame = wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self()) + w_frame = interp.space.unwrap_pointersobject(w_frame) + return w_frame.as_context_get_shadow(interp.space) @expose_primitive(FLUSH_CACHE, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -798,8 +798,10 @@ def returnTopFromMethod(self, interp, current_bytecode): if self.is_closure_context(): # this is a context for a blockClosure - s_outerContext = self.w_closure_or_nil.fetch(self.space, - constants.BLKCLSR_OUTER_CONTEXT).get_shadow(self.space) + w_outerContext = self.w_closure_or_nil.fetch(self.space, + constants.BLKCLSR_OUTER_CONTEXT) + assert isinstance(w_outerContext, model.W_PointersObject) + s_outerContext = w_outerContext.as_context_get_shadow(self.space) # XXX check whether we can actually return from that context if s_outerContext.pc() == -1: raise error.BlockCannotReturnError() diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -226,7 +226,10 @@ def asContextWithSender(self, w_aContext, arguments): from spyvm import shadow - s_outerContext = self.outerContext().get_shadow(self.space) + w_outerContext = self.outerContext() + if not isinstance(w_outerContext, model.W_PointersObject): + raise PrimitiveFailedError + s_outerContext = w_outerContext.as_context_get_shadow(self.space) s_method = s_outerContext.w_method().as_compiledmethod_get_shadow(self.space) w_receiver = s_outerContext.w_receiver() w_new_frame = shadow.MethodContextShadow.make_context(self.space, s_method, w_receiver, From noreply at buildbot.pypy.org Wed Mar 6 21:39:39 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 21:39:39 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup _sqlite3.Statement Message-ID: <20130306203939.664421C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62133:45bbcccf99e5 Date: 2013-03-06 15:25 -0500 http://bitbucket.org/pypy/pypy/changeset/45bbcccf99e5/ Log: cleanup _sqlite3.Statement diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -237,8 +237,6 @@ sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] sqlite.sqlite3_enable_load_extension.restype = c_int -_DML, _DQL, _DDL = range(3) - ########################################## # END Wrapped SQLite C API and constants ########################################## @@ -302,9 +300,9 @@ if len(self.cache) > self.maxcount: self.cache.popitem(0) - if stat.in_use: + if stat._in_use: stat = Statement(self.connection, sql) - stat.set_row_factory(row_factory) + stat._row_factory = row_factory return stat @@ -363,7 +361,7 @@ for statement in self.__statements: obj = statement() if obj is not None: - obj.finalize() + obj._finalize() if self._db: ret = sqlite.sqlite3_close(self._db) @@ -496,7 +494,7 @@ for statement in self.__statements: obj = statement() if obj is not None: - obj.reset() + obj._reset() statement = c_void_p() next_char = c_char_p() @@ -521,7 +519,7 @@ for statement in self.__statements: obj = statement() if obj is not None: - obj.reset() + obj._reset() for cursor_ref in self._cursors: cursor = cursor_ref() @@ -771,13 +769,13 @@ except ValueError: pass if self.__statement: - self.__statement.reset() + self.__statement._reset() def close(self): self.__connection._check_thread() self.__connection._check_closed() if self.__statement: - self.__statement.reset() + self.__statement._reset() self.__statement = None self.__closed = True @@ -808,35 +806,35 @@ sql, self.row_factory) if self.__connection._isolation_level is not None: - if self.__statement.kind == _DDL: + if self.__statement._kind == Statement._DDL: if self.__connection._in_transaction: self.__connection.commit() - elif self.__statement.kind == _DML: + elif self.__statement._kind == Statement._DML: if not self.__connection._in_transaction: self.__connection._begin() - self.__statement.set_params(params) + self.__statement._set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.__statement.statement) + ret = sqlite.sqlite3_step(self.__statement._statement) if ret not in (SQLITE_DONE, SQLITE_ROW): - self.__statement.reset() + self.__statement._reset() self.__connection._in_transaction = \ not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) - if self.__statement.kind == _DML: - self.__statement.reset() + if self.__statement._kind == Statement._DML: + self.__statement._reset() - if self.__statement.kind == _DQL and ret == SQLITE_ROW: + if self.__statement._kind == Statement._DQL and ret == SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) else: - self.__statement.item = None - self.__statement.exhausted = True + self.__statement._item = None + self.__statement._exhausted = True self.__rowcount = -1 - if self.__statement.kind == _DML: + if self.__statement._kind == Statement._DML: self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) finally: self.__locked = False @@ -852,7 +850,7 @@ self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) - if self.__statement.kind == _DML: + if self.__statement._kind == Statement._DML: if self.__connection._isolation_level is not None: if not self.__connection._in_transaction: self.__connection._begin() @@ -861,15 +859,15 @@ self.__rowcount = 0 for params in many_params: - self.__statement.set_params(params) - ret = sqlite.sqlite3_step(self.__statement.statement) + self.__statement._set_params(params) + ret = sqlite.sqlite3_step(self.__statement._statement) if ret != SQLITE_DONE: - self.__statement.reset() + self.__statement._reset() self.__connection._in_transaction = \ not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) - self.__statement.reset() + self.__statement._reset() finally: self.__locked = False @@ -926,7 +924,7 @@ return None try: - return self.__statement.next(self) + return self.__statement._next(self) except StopIteration: return None @@ -980,55 +978,67 @@ class Statement(object): - statement = None + _DML, _DQL, _DDL = range(3) + + _statement = None def __init__(self, connection, sql): - if not isinstance(sql, str): + self.__con = connection + + if isinstance(sql, unicode): + sql = sql.encode('utf-8') + elif not isinstance(sql, str): raise ValueError("sql must be a string") - self.con = connection - self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): - self.kind = _DML + self._kind = Statement._DML elif first_word in ("SELECT", "PRAGMA"): - self.kind = _DQL + self._kind = Statement._DQL else: - self.kind = _DDL - self.exhausted = False - self.in_use = False - # - # set by set_row_factory - self.row_factory = None + self._kind = Statement._DDL - self.statement = c_void_p() + self._in_use = False + self._exhausted = False + self._row_factory = None + + self._statement = c_void_p() next_char = c_char_p() sql_char = c_char_p(sql) - ret = sqlite.sqlite3_prepare_v2(self.con._db, sql_char, -1, byref(self.statement), byref(next_char)) - if ret == SQLITE_OK and self.statement.value is None: + ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql_char, -1, byref(self._statement), byref(next_char)) + if ret == SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.con._db, "select 42", -1, byref(self.statement), byref(next_char)) - self.kind = _DQL + ret = sqlite.sqlite3_prepare_v2(self.__con._db, "select 42", -1, byref(self._statement), byref(next_char)) + self._kind = Statement._DQL if ret != SQLITE_OK: - raise self.con._get_exception(ret) - self.con._remember_statement(self) + raise self.__con._get_exception(ret) + self.__con._remember_statement(self) if _check_remaining_sql(next_char.value): raise Warning("One and only one statement required: %r" % (next_char.value,)) - # sql_char should remain alive until here - self._build_row_cast_map() + def __del__(self): + if self._statement: + sqlite.sqlite3_finalize(self._statement) - def set_row_factory(self, row_factory): - self.row_factory = row_factory + def _finalize(self): + sqlite.sqlite3_finalize(self._statement) + self._statement = None + self._in_use = False + + def _reset(self): + ret = sqlite.sqlite3_reset(self._statement) + self._in_use = False + self._exhausted = False + return ret def _build_row_cast_map(self): - self.row_cast_map = [] - for i in xrange(sqlite.sqlite3_column_count(self.statement)): + self.__row_cast_map = [] + for i in xrange(sqlite.sqlite3_column_count(self._statement)): converter = None - if self.con._detect_types & PARSE_COLNAMES: - colname = sqlite.sqlite3_column_name(self.statement, i) + if self.__con._detect_types & PARSE_COLNAMES: + colname = sqlite.sqlite3_column_name(self._statement, i) if colname is not None: type_start = -1 key = None @@ -1039,28 +1049,28 @@ key = colname[type_start:pos] converter = converters[key.upper()] - if converter is None and self.con._detect_types & PARSE_DECLTYPES: - decltype = sqlite.sqlite3_column_decltype(self.statement, i) + if converter is None and self.__con._detect_types & PARSE_DECLTYPES: + decltype = sqlite.sqlite3_column_decltype(self._statement, i) if decltype is not None: decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" if '(' in decltype: decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) - self.row_cast_map.append(converter) + self.__row_cast_map.append(converter) - def _check_decodable(self, param): - if self.con.text_factory in (unicode, OptimizedUnicode, unicode_text_factory): + def __check_decodable(self, param): + if self.__con.text_factory in (unicode, OptimizedUnicode, unicode_text_factory): for c in param: if ord(c) & 0x80 != 0: - raise self.con.ProgrammingError( + raise self.__con.ProgrammingError( "You must not use 8-bit bytestrings unless " "you use a text_factory that can interpret " "8-bit bytestrings (like text_factory = str). " "It is highly recommended that you instead " "just switch your application to Unicode strings.") - def set_param(self, idx, param): + def __set_param(self, idx, param): cvt = converters.get(type(param)) if cvt is not None: cvt = param = cvt(param) @@ -1068,34 +1078,34 @@ param = adapt(param) if param is None: - sqlite.sqlite3_bind_null(self.statement, idx) + sqlite.sqlite3_bind_null(self._statement, idx) elif type(param) in (bool, int, long): if -2147483648 <= param <= 2147483647: - sqlite.sqlite3_bind_int(self.statement, idx, param) + sqlite.sqlite3_bind_int(self._statement, idx, param) else: - sqlite.sqlite3_bind_int64(self.statement, idx, param) + sqlite.sqlite3_bind_int64(self._statement, idx, param) elif type(param) is float: - sqlite.sqlite3_bind_double(self.statement, idx, param) + sqlite.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, str): - self._check_decodable(param) - sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) + self.__check_decodable(param) + sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif isinstance(param, unicode): param = param.encode("utf-8") - sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) + sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) is buffer: - sqlite.sqlite3_bind_blob(self.statement, idx, str(param), len(param), SQLITE_TRANSIENT) + sqlite.sqlite3_bind_blob(self._statement, idx, str(param), len(param), SQLITE_TRANSIENT) else: raise InterfaceError("parameter type %s is not supported" % str(type(param))) - def set_params(self, params): - ret = sqlite.sqlite3_reset(self.statement) + def _set_params(self, params): + ret = sqlite.sqlite3_reset(self._statement) if ret != SQLITE_OK: - raise self.con._get_exception(ret) - self.mark_dirty() + raise self.__con._get_exception(ret) + self._in_use = True if params is None: - if sqlite.sqlite3_bind_parameter_count(self.statement) != 0: + if sqlite.sqlite3_bind_parameter_count(self._statement) != 0: raise ProgrammingError("wrong number of arguments") return @@ -1106,14 +1116,14 @@ params_type = list if params_type == list: - if len(params) != sqlite.sqlite3_bind_parameter_count(self.statement): + if len(params) != sqlite.sqlite3_bind_parameter_count(self._statement): raise ProgrammingError("wrong number of arguments") for i in range(len(params)): - self.set_param(i+1, params[i]) + self.__set_param(i+1, params[i]) else: - for idx in range(1, sqlite.sqlite3_bind_parameter_count(self.statement) + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self.statement, idx) + for idx in range(1, sqlite.sqlite3_bind_parameter_count(self._statement) + 1): + param_name = sqlite.sqlite3_bind_parameter_name(self._statement, idx) if param_name is None: raise ProgrammingError("need named parameters") param_name = param_name[1:] @@ -1121,92 +1131,73 @@ param = params[param_name] except KeyError: raise ProgrammingError("missing parameter '%s'" % param) - self.set_param(idx, param) + self.__set_param(idx, param) - def next(self, cursor): - self.con._check_closed() - self.con._check_thread() - if self.exhausted: + def _next(self, cursor): + self.__con._check_closed() + self.__con._check_thread() + if self._exhausted: raise StopIteration - item = self.item + item = self._item - ret = sqlite.sqlite3_step(self.statement) + ret = sqlite.sqlite3_step(self._statement) if ret == SQLITE_DONE: - self.exhausted = True - self.item = None + self._exhausted = True + self._item = None elif ret != SQLITE_ROW: - exc = self.con._get_exception(ret) - sqlite.sqlite3_reset(self.statement) + exc = self.__con._get_exception(ret) + sqlite.sqlite3_reset(self._statement) raise exc self._readahead(cursor) return item def _readahead(self, cursor): - self.column_count = sqlite.sqlite3_column_count(self.statement) + self.column_count = sqlite.sqlite3_column_count(self._statement) row = [] for i in xrange(self.column_count): - typ = sqlite.sqlite3_column_type(self.statement, i) + typ = sqlite.sqlite3_column_type(self._statement, i) - converter = self.row_cast_map[i] + converter = self.__row_cast_map[i] if converter is None: if typ == SQLITE_INTEGER: - val = sqlite.sqlite3_column_int64(self.statement, i) + val = sqlite.sqlite3_column_int64(self._statement, i) if -sys.maxint-1 <= val <= sys.maxint: val = int(val) elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_column_double(self.statement, i) + val = sqlite.sqlite3_column_double(self._statement, i) elif typ == SQLITE_BLOB: - blob_len = sqlite.sqlite3_column_bytes(self.statement, i) - blob = sqlite.sqlite3_column_blob(self.statement, i) + blob_len = sqlite.sqlite3_column_bytes(self._statement, i) + blob = sqlite.sqlite3_column_blob(self._statement, i) val = buffer(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: - text_len = sqlite.sqlite3_column_bytes(self.statement, i) - text = sqlite.sqlite3_column_text(self.statement, i) + text_len = sqlite.sqlite3_column_bytes(self._statement, i) + text = sqlite.sqlite3_column_text(self._statement, i) val = string_at(text, text_len) - val = self.con.text_factory(val) + val = self.__con.text_factory(val) else: - blob = sqlite.sqlite3_column_blob(self.statement, i) + blob = sqlite.sqlite3_column_blob(self._statement, i) if not blob: val = None else: - blob_len = sqlite.sqlite3_column_bytes(self.statement, i) + blob_len = sqlite.sqlite3_column_bytes(self._statement, i) val = string_at(blob, blob_len) val = converter(val) row.append(val) row = tuple(row) - if self.row_factory is not None: - row = self.row_factory(cursor, row) - self.item = row - - def reset(self): - self.row_cast_map = None - ret = sqlite.sqlite3_reset(self.statement) - self.in_use = False - self.exhausted = False - return ret - - def finalize(self): - sqlite.sqlite3_finalize(self.statement) - self.statement = None - self.in_use = False - - def mark_dirty(self): - self.in_use = True - - def __del__(self): - if self.statement: - sqlite.sqlite3_finalize(self.statement) + if self._row_factory is not None: + row = self._row_factory(cursor, row) + self._item = row def _get_description(self): - if self.kind == _DML: + if self._kind == Statement._DML: return None desc = [] - for i in xrange(sqlite.sqlite3_column_count(self.statement)): - name = sqlite.sqlite3_column_name(self.statement, i).split("[")[0].strip() + for i in xrange(sqlite.sqlite3_column_count(self._statement)): + name = sqlite.sqlite3_column_name(self._statement, i).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc From noreply at buildbot.pypy.org Wed Mar 6 21:39:40 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 21:39:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130306203940.C9D721C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62134:36a3c5c18e36 Date: 2013-03-06 15:35 -0500 http://bitbucket.org/pypy/pypy/changeset/36a3c5c18e36/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -244,8 +244,6 @@ sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] sqlite.sqlite3_enable_load_extension.restype = c_int -_DML, _DQL, _DDL = range(3) - ########################################## # END Wrapped SQLite C API and constants ########################################## @@ -306,9 +304,9 @@ if len(self.cache) > self.maxcount: self.cache.popitem(0) - if stat.in_use: + if stat._in_use: stat = Statement(self.connection, sql) - stat.set_row_factory(row_factory) + stat._row_factory = row_factory return stat @@ -367,7 +365,7 @@ for statement in self.__statements: obj = statement() if obj is not None: - obj.finalize() + obj._finalize() if self._db: ret = sqlite.sqlite3_close(self._db) @@ -501,7 +499,7 @@ for statement in self.__statements: obj = statement() if obj is not None: - obj.reset() + obj._reset() statement = c_void_p() next_char = c_char_p() @@ -526,7 +524,7 @@ for statement in self.__statements: obj = statement() if obj is not None: - obj.reset() + obj._reset() for cursor_ref in self._cursors: cursor = cursor_ref() @@ -778,13 +776,13 @@ except ValueError: pass if self.__statement: - self.__statement.reset() + self.__statement._reset() def close(self): self.__connection._check_thread() self.__connection._check_closed() if self.__statement: - self.__statement.reset() + self.__statement._reset() self.__statement = None self.__closed = True @@ -798,8 +796,15 @@ self.__connection._check_thread() self.__connection._check_closed() + def __check_cursor_wrap(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + self.__check_cursor() + return func(self, *args, **kwargs) + return wrapper + + @__check_cursor_wrap def execute(self, sql, params=None): - self.__check_cursor() self.__locked = True try: self.__description = None @@ -808,43 +813,43 @@ sql, self.row_factory) if self.__connection._isolation_level is not None: - if self.__statement.kind == _DDL: + if self.__statement._kind == Statement._DDL: if self.__connection._in_transaction: self.__connection.commit() - elif self.__statement.kind == _DML: + elif self.__statement._kind == Statement._DML: if not self.__connection._in_transaction: self.__connection._begin() - self.__statement.set_params(params) + self.__statement._set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.__statement.statement) + ret = sqlite.sqlite3_step(self.__statement._statement) if ret not in (SQLITE_DONE, SQLITE_ROW): - self.__statement.reset() + self.__statement._reset() self.__connection._in_transaction = \ not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) - if self.__statement.kind == _DML: - self.__statement.reset() + if self.__statement._kind == Statement._DML: + self.__statement._reset() - if self.__statement.kind == _DQL and ret == SQLITE_ROW: + if self.__statement._kind == Statement._DQL and ret == SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) else: - self.__statement.item = None - self.__statement.exhausted = True + self.__statement._item = None + self.__statement._exhausted = True self.__rowcount = -1 - if self.__statement.kind == _DML: + if self.__statement._kind == Statement._DML: self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) finally: self.__locked = False return self + @__check_cursor_wrap def executemany(self, sql, many_params): - self.__check_cursor() self.__locked = True try: self.__description = None @@ -852,7 +857,7 @@ self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) - if self.__statement.kind == _DML: + if self.__statement._kind == Statement._DML: if self.__connection._isolation_level is not None: if not self.__connection._in_transaction: self.__connection._begin() @@ -861,15 +866,15 @@ self.__rowcount = 0 for params in many_params: - self.__statement.set_params(params) - ret = sqlite.sqlite3_step(self.__statement.statement) + self.__statement._set_params(params) + ret = sqlite.sqlite3_step(self.__statement._statement) if ret != SQLITE_DONE: - self.__statement.reset() + self.__statement._reset() self.__connection._in_transaction = \ not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) - self.__statement.reset() + self.__statement._reset() finally: self.__locked = False @@ -926,7 +931,7 @@ return None try: - return self.__statement.next(self) + return self.__statement._next(self) except StopIteration: return None @@ -980,56 +985,66 @@ class Statement(object): - statement = None + _DML, _DQL, _DDL = range(3) + + _statement = None def __init__(self, connection, sql): + self.__con = connection + if not isinstance(sql, str): raise ValueError("sql must be a string") - self.con = connection - self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): - self.kind = _DML + self._kind = Statement._DML elif first_word in ("SELECT", "PRAGMA"): - self.kind = _DQL + self._kind = Statement._DQL else: - self.kind = _DDL - self.exhausted = False - self.in_use = False - # - # set by set_row_factory - self.row_factory = None + self._kind = Statement._DDL - self.statement = c_void_p() + self._in_use = False + self._exhausted = False + self._row_factory = None + + self._statement = c_void_p() next_char = c_char_p() sql_char = sql - ret = sqlite.sqlite3_prepare_v2(self.con._db, sql_char, -1, byref(self.statement), byref(next_char)) - if ret == SQLITE_OK and self.statement.value is None: + ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql_char, -1, byref(self._statement), byref(next_char)) + if ret == SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.con._db, "select 42", -1, byref(self.statement), byref(next_char)) - self.kind = _DQL + ret = sqlite.sqlite3_prepare_v2(self.__con._db, "select 42", -1, byref(self._statement), byref(next_char)) + self._kind = Statement._DQL if ret != SQLITE_OK: - raise self.con._get_exception(ret) - self.con._remember_statement(self) + raise self.__con._get_exception(ret) + self.__con._remember_statement(self) next_char = next_char.value.decode('utf-8') if _check_remaining_sql(next_char): raise Warning("One and only one statement required: %r" % (next_char,)) - # sql_char should remain alive until here - self._build_row_cast_map() + def __del__(self): + if self._statement: + sqlite.sqlite3_finalize(self._statement) - def set_row_factory(self, row_factory): - self.row_factory = row_factory + def _finalize(self): + sqlite.sqlite3_finalize(self._statement) + self._statement = None + self._in_use = False + + def _reset(self): + ret = sqlite.sqlite3_reset(self._statement) + self._in_use = False + self._exhausted = False + return ret def _build_row_cast_map(self): - self.row_cast_map = [] - for i in range(sqlite.sqlite3_column_count(self.statement)): + self.__row_cast_map = [] + for i in range(sqlite.sqlite3_column_count(self._statement)): converter = None - if self.con._detect_types & PARSE_COLNAMES: - colname = sqlite.sqlite3_column_name(self.statement, i) + if self.__con._detect_types & PARSE_COLNAMES: + colname = sqlite.sqlite3_column_name(self._statement, i) if colname is not None: colname = colname.decode('utf-8') type_start = -1 @@ -1041,8 +1056,8 @@ key = colname[type_start:pos] converter = converters[key.upper()] - if converter is None and self.con._detect_types & PARSE_DECLTYPES: - decltype = sqlite.sqlite3_column_decltype(self.statement, i) + if converter is None and self.__con._detect_types & PARSE_DECLTYPES: + decltype = sqlite.sqlite3_column_decltype(self._statement, i) if decltype is not None: decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" decltype = decltype.decode('utf-8') @@ -1050,9 +1065,9 @@ decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) - self.row_cast_map.append(converter) + self.__row_cast_map.append(converter) - def set_param(self, idx, param): + def __set_param(self, idx, param): cvt = converters.get(type(param)) if cvt is not None: cvt = param = cvt(param) @@ -1060,32 +1075,32 @@ param = adapt(param) if param is None: - sqlite.sqlite3_bind_null(self.statement, idx) + sqlite.sqlite3_bind_null(self._statement, idx) elif type(param) in (bool, int): if -2147483648 <= param <= 2147483647: - sqlite.sqlite3_bind_int(self.statement, idx, param) + sqlite.sqlite3_bind_int(self._statement, idx, param) else: - sqlite.sqlite3_bind_int64(self.statement, idx, param) + sqlite.sqlite3_bind_int64(self._statement, idx, param) elif type(param) is float: - sqlite.sqlite3_bind_double(self.statement, idx, param) + sqlite.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, str): param = param.encode('utf-8') - sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) + sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) in (bytes, memoryview): param = bytes(param) - sqlite.sqlite3_bind_blob(self.statement, idx, param, len(param), SQLITE_TRANSIENT) + sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) else: raise InterfaceError("parameter type %s is not supported" % type(param)) - def set_params(self, params): - ret = sqlite.sqlite3_reset(self.statement) + def _set_params(self, params): + ret = sqlite.sqlite3_reset(self._statement) if ret != SQLITE_OK: - raise self.con._get_exception(ret) - self.mark_dirty() + raise self.__con._get_exception(ret) + self._in_use = True if params is None: - if sqlite.sqlite3_bind_parameter_count(self.statement) != 0: + if sqlite.sqlite3_bind_parameter_count(self._statement) != 0: raise ProgrammingError("wrong number of arguments") return @@ -1096,14 +1111,14 @@ params_type = list if params_type == list: - if len(params) != sqlite.sqlite3_bind_parameter_count(self.statement): + if len(params) != sqlite.sqlite3_bind_parameter_count(self._statement): raise ProgrammingError("wrong number of arguments") for i in range(len(params)): - self.set_param(i+1, params[i]) + self.__set_param(i+1, params[i]) else: - for idx in range(1, sqlite.sqlite3_bind_parameter_count(self.statement) + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self.statement, idx) + for idx in range(1, sqlite.sqlite3_bind_parameter_count(self._statement) + 1): + param_name = sqlite.sqlite3_bind_parameter_name(self._statement, idx) if param_name is None: raise ProgrammingError("need named parameters") param_name = param_name[1:].decode('utf-8') @@ -1111,92 +1126,73 @@ param = params[param_name] except KeyError: raise ProgrammingError("missing parameter %r" % param_name) - self.set_param(idx, param) + self.__set_param(idx, param) - def next(self, cursor): - self.con._check_closed() - self.con._check_thread() - if self.exhausted: + def _next(self, cursor): + self.__con._check_closed() + self.__con._check_thread() + if self._exhausted: raise StopIteration - item = self.item + item = self._item - ret = sqlite.sqlite3_step(self.statement) + ret = sqlite.sqlite3_step(self._statement) if ret == SQLITE_DONE: - self.exhausted = True - self.item = None + self._exhausted = True + self._item = None elif ret != SQLITE_ROW: - exc = self.con._get_exception(ret) - sqlite.sqlite3_reset(self.statement) + exc = self.__con._get_exception(ret) + sqlite.sqlite3_reset(self._statement) raise exc self._readahead(cursor) return item def _readahead(self, cursor): - self.column_count = sqlite.sqlite3_column_count(self.statement) + self.column_count = sqlite.sqlite3_column_count(self._statement) row = [] for i in range(self.column_count): - typ = sqlite.sqlite3_column_type(self.statement, i) + typ = sqlite.sqlite3_column_type(self._statement, i) - converter = self.row_cast_map[i] + converter = self.__row_cast_map[i] if converter is None: if typ == SQLITE_INTEGER: - val = sqlite.sqlite3_column_int64(self.statement, i) + val = sqlite.sqlite3_column_int64(self._statement, i) if -sys.maxsize-1 <= val <= sys.maxsize: val = int(val) elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_column_double(self.statement, i) + val = sqlite.sqlite3_column_double(self._statement, i) elif typ == SQLITE_BLOB: - blob_len = sqlite.sqlite3_column_bytes(self.statement, i) - blob = sqlite.sqlite3_column_blob(self.statement, i) + blob_len = sqlite.sqlite3_column_bytes(self._statement, i) + blob = sqlite.sqlite3_column_blob(self._statement, i) val = bytes(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: - text_len = sqlite.sqlite3_column_bytes(self.statement, i) - text = sqlite.sqlite3_column_text(self.statement, i) + text_len = sqlite.sqlite3_column_bytes(self._statement, i) + text = sqlite.sqlite3_column_text(self._statement, i) val = string_at(text, text_len) - val = self.con.text_factory(val) + val = self.__con.text_factory(val) else: - blob = sqlite.sqlite3_column_blob(self.statement, i) + blob = sqlite.sqlite3_column_blob(self._statement, i) if not blob: val = None else: - blob_len = sqlite.sqlite3_column_bytes(self.statement, i) + blob_len = sqlite.sqlite3_column_bytes(self._statement, i) val = string_at(blob, blob_len) val = converter(val) row.append(val) row = tuple(row) - if self.row_factory is not None: - row = self.row_factory(cursor, row) - self.item = row - - def reset(self): - self.row_cast_map = None - ret = sqlite.sqlite3_reset(self.statement) - self.in_use = False - self.exhausted = False - return ret - - def finalize(self): - sqlite.sqlite3_finalize(self.statement) - self.statement = None - self.in_use = False - - def mark_dirty(self): - self.in_use = True - - def __del__(self): - if self.statement: - sqlite.sqlite3_finalize(self.statement) + if self._row_factory is not None: + row = self._row_factory(cursor, row) + self._item = row def _get_description(self): - if self.kind == _DML: + if self._kind == Statement._DML: return None desc = [] - for i in range(sqlite.sqlite3_column_count(self.statement)): - col_name = sqlite.sqlite3_column_name(self.statement, i) + for i in range(sqlite.sqlite3_column_count(self._statement)): + col_name = sqlite.sqlite3_column_name(self._statement, i) name = col_name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc 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 @@ -58,6 +58,9 @@ cur.close() con.close() pytest.raises(_sqlite3.ProgrammingError, "cur.close()") + # raises ProgrammingError because should check closed before check args + pytest.raises(_sqlite3.ProgrammingError, "cur.execute(1,2,3,4,5)") + pytest.raises(_sqlite3.ProgrammingError, "cur.executemany(1,2,3,4,5)") @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')") def test_cursor_del(): From noreply at buildbot.pypy.org Wed Mar 6 21:41:04 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 21:41:04 +0100 (CET) Subject: [pypy-commit] pypy default: redundant call to encode Message-ID: <20130306204104.F38271C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62135:5b25d91f1f35 Date: 2013-03-06 15:40 -0500 http://bitbucket.org/pypy/pypy/changeset/5b25d91f1f35/ Log: redundant call to encode diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -985,9 +985,7 @@ def __init__(self, connection, sql): self.__con = connection - if isinstance(sql, unicode): - sql = sql.encode('utf-8') - elif not isinstance(sql, str): + if not isinstance(sql, str): raise ValueError("sql must be a string") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): From noreply at buildbot.pypy.org Wed Mar 6 21:54:23 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 21:54:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130306205423.E57761C101B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62136:1acd1abdb117 Date: 2013-03-06 22:53 +0200 http://bitbucket.org/pypy/pypy/changeset/1acd1abdb117/ Log: fix diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -805,12 +805,11 @@ # mc.BL(self.cpu.realloc_frame) - # set fp to the new jitframe - mc.MOV_rr(r.fp.value, r.r0.value) - # restore a possibly present exception self._restore_exception(mc, None, r.fp) + # set fp to the new jitframe + mc.MOV_rr(r.fp.value, r.r0.value) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: From noreply at buildbot.pypy.org Wed Mar 6 21:54:35 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 6 Mar 2013 21:54:35 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Added class attribute information to the ContextPartShadow class-chain. Message-ID: <20130306205435.D8B9D1C101B@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r128:0e0ba48f9e2a Date: 2013-03-06 21:54 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0e0ba48f9e2a/ Log: Added class attribute information to the ContextPartShadow class- chain. Renamed _w_method to __w_method to circumvent outside access from an unknown place. Unfortunately, the maximum recursion depth circumvents any attempts to see whether the system broke. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -29,7 +29,7 @@ jit_driver = jit.JitDriver( greens=['pc', 'self', 'method'], reds=['s_context'], - #virtualizables=['s_context'], + virtualizables=['s_context'], get_printable_location=get_printable_location ) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -7,6 +7,8 @@ """A shadow is an optional extra bit of information that can be attached at run-time to any Smalltalk object. """ + _attr_ = ['_w_self'] + def __init__(self, space, w_self): self.space = space self._w_self = w_self @@ -25,6 +27,8 @@ def sync_shadow(self): pass class AbstractCachingShadow(AbstractShadow): + _attr_ = [] + def __init__(self, space, w_self): AbstractShadow.__init__(self, space, w_self) @@ -282,6 +286,8 @@ class AbstractRedirectingShadow(AbstractShadow): + _attr_ = ['_w_self_size'] + def __init__(self, space, w_self): AbstractShadow.__init__(self, space, w_self) if w_self is not None: @@ -319,12 +325,14 @@ class ContextPartShadow(AbstractRedirectingShadow): __metaclass__ = extendabletype + _attr_ = ['_s_sender', '_pc', '_temps_and_stack', + '_stack_ptr', 'instances_w'] - # _virtualizable2_ = [ - # "_s_sender", "_pc", - # "_temps_and_stack[*]", "_stack_ptr", - # "_w_self", "_w_self_size" - # ] + _virtualizable2_ = [ + "_s_sender", "_pc", + "_temps_and_stack[*]", "_stack_ptr", + "_w_self", "_w_self_size" + ] def __init__(self, space, w_self): self._s_sender = None @@ -464,7 +472,9 @@ # Method that contains the bytecode for this method/block context def w_method(self): - return self.s_home().w_method() + retval = self.s_home().w_method() + assert isinstance(retval, model.W_CompiledMethod) + return retval def s_method(self): w_method = jit.promote(self.w_method()) @@ -585,6 +595,7 @@ class BlockContextShadow(ContextPartShadow): + _attr_ = ['_w_home', '_initialip', '_eargc'] @staticmethod def make_context(space, w_home, s_sender, argcnt, initialip): @@ -679,11 +690,12 @@ return 0 class MethodContextShadow(ContextPartShadow): - + _attr_ = ['w_closure_or_nil', '_w_receiver', '__w_method'] def __init__(self, space, w_self): self.w_closure_or_nil = space.w_nil - self._w_receiver = None + self._w_receiver = space.w_nil + self.__w_method = None ContextPartShadow.__init__(self, space, w_self) @staticmethod @@ -761,11 +773,13 @@ self.w_closure_or_nil).tempsize() def w_method(self): - return self._w_method + retval = self.__w_method + assert isinstance(retval, model.W_CompiledMethod) + return retval def store_w_method(self, w_method): assert isinstance(w_method, model.W_CompiledMethod) - self._w_method = w_method + self.__w_method = w_method def w_receiver(self): return self._w_receiver From noreply at buildbot.pypy.org Wed Mar 6 22:00:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 22:00:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: disable the debug Message-ID: <20130306210056.D24811C101B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62137:523baa10ad2f Date: 2013-03-06 22:55 +0200 http://bitbucket.org/pypy/pypy/changeset/523baa10ad2f/ Log: disable the debug diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -51,7 +51,7 @@ _output_loop_log = None _second_tmp_reg = ecx - DEBUG_FRAME_DEPTH = True + DEBUG_FRAME_DEPTH = False def __init__(self, cpu, translate_support_code=False): BaseAssembler.__init__(self, cpu, translate_support_code) From noreply at buildbot.pypy.org Wed Mar 6 22:00:58 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 22:00:58 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: this guy can go away (a better version is in llsupport) Message-ID: <20130306210058.0A3951C101B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62138:46ce7f2e3cb9 Date: 2013-03-06 23:00 +0200 http://bitbucket.org/pypy/pypy/changeset/46ce7f2e3cb9/ Log: this guy can go away (a better version is in llsupport) diff --git a/rpython/jit/backend/arm/test/test_gc_integration.py b/rpython/jit/backend/arm/test/test_gc_integration.py deleted file mode 100644 --- a/rpython/jit/backend/arm/test/test_gc_integration.py +++ /dev/null @@ -1,207 +0,0 @@ - -""" Tests for register allocation for common constructs -""" - -from rpython.jit.metainterp.history import TargetToken -from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm -from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.arm.arch import WORD -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi - -from rpython.jit.backend.arm.test.test_regalloc import BaseTestRegalloc - -CPU = getcpuclass() - - -class MockGcRootMap(object): - is_shadow_stack = False - - def get_basic_shape(self, is_64_bit): - return ['shape'] - - def add_frame_offset(self, shape, offset): - shape.append(offset) - - def add_callee_save_reg(self, shape, reg_index): - index_to_name = {1: 'ebx', 2: 'esi', 3: 'edi'} - shape.append(index_to_name[reg_index]) - - def compress_callshape(self, shape, datablockwrapper): - assert datablockwrapper == 'fakedatablockwrapper' - assert shape[0] == 'shape' - return ['compressed'] + shape[1:] - - -class MockGcDescr(GcLLDescr_boehm): - gcrootmap = MockGcRootMap() - - -class TestRegallocGcIntegration(BaseTestRegalloc): - - cpu = CPU(None, None) - cpu.gc_ll_descr = MockGcDescr(None, None, None) - cpu.setup_once() - - S = lltype.GcForwardReference() - S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), - ('int', lltype.Signed))) - - fielddescr = cpu.fielddescrof(S, 'field') - - struct_ptr = lltype.malloc(S) - struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr) - child_ptr = lltype.nullptr(S) - struct_ptr.field = child_ptr - - - descr0 = cpu.fielddescrof(S, 'int') - ptr0 = struct_ref - targettoken = TargetToken() - - namespace = locals().copy() - - def test_basic(self): - ops = ''' - [p0] - p1 = getfield_gc(p0, descr=fielddescr) - finish(p1) - ''' - self.interpret(ops, [self.struct_ptr]) - assert not self.getptr(0, lltype.Ptr(self.S)) - - def test_rewrite_constptr(self): - ops = ''' - [] - p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr) - finish(p1) - ''' - self.interpret(ops, []) - assert not self.getptr(0, lltype.Ptr(self.S)) - - def test_bug_0(self): - ops = ''' - [i0, i1, i2, i3, i4, i5, i6, i7, i8] - label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken) - guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8] - guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8] - i11 = getfield_gc(i4, descr=descr0) - guard_nonnull(i11) [i4, i5, i6, i7, i0, i1, i11, i8] - i13 = getfield_gc(i11, descr=descr0) - guard_isnull(i13) [i4, i5, i6, i7, i0, i1, i11, i8] - i15 = getfield_gc(i4, descr=descr0) - i17 = int_lt(i15, 0) - guard_false(i17) [i4, i5, i6, i7, i0, i1, i11, i15, i8] - i18 = getfield_gc(i11, descr=descr0) - i19 = int_ge(i15, i18) - guard_false(i19) [i4, i5, i6, i7, i0, i1, i11, i15, i8] - i20 = int_lt(i15, 0) - guard_false(i20) [i4, i5, i6, i7, i0, i1, i11, i15, i8] - i21 = getfield_gc(i11, descr=descr0) - i22 = getfield_gc(i11, descr=descr0) - i23 = int_mul(i15, i22) - i24 = int_add(i21, i23) - i25 = getfield_gc(i4, descr=descr0) - i27 = int_add(i25, 1) - setfield_gc(i4, i27, descr=descr0) - i29 = getfield_raw(144839744, descr=descr0) - i31 = int_and(i29, -2141192192) - i32 = int_is_true(i31) - guard_false(i32) [i4, i6, i7, i0, i1, i24] - i33 = getfield_gc(i0, descr=descr0) - guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24] - jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken) - ''' - self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False) - -NOT_INITIALIZED = chr(0xdd) - -class GCDescrFastpathMalloc(GcLLDescription): - gcrootmap = None - write_barrier_descr = None - - def __init__(self): - GcLLDescription.__init__(self, None) - # create a nursery - NTP = rffi.CArray(lltype.Char) - self.nursery = lltype.malloc(NTP, 64, flavor='raw') - for i in range(64): - self.nursery[i] = NOT_INITIALIZED - self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 2, - flavor='raw') - self.addrs[0] = rffi.cast(lltype.Signed, self.nursery) - self.addrs[1] = self.addrs[0] + 64 - self.calls = [] - def malloc_slowpath(size): - self.calls.append(size) - # reset the nursery - nadr = rffi.cast(lltype.Signed, self.nursery) - self.addrs[0] = nadr + size - return nadr - self.generate_function('malloc_nursery', malloc_slowpath, - [lltype.Signed], lltype.Signed) - - def get_nursery_free_addr(self): - return rffi.cast(lltype.Signed, self.addrs) - - def get_nursery_top_addr(self): - return rffi.cast(lltype.Signed, self.addrs) + WORD - - def get_malloc_slowpath_addr(self): - return self.get_malloc_fn_addr('malloc_nursery') - - def check_nothing_in_nursery(self): - # CALL_MALLOC_NURSERY should not write anything in the nursery - for i in range(64): - assert self.nursery[i] == NOT_INITIALIZED - -class TestMallocFastpath(BaseTestRegalloc): - - def setup_method(self, method): - cpu = CPU(None, None) - cpu.gc_ll_descr = GCDescrFastpathMalloc() - cpu.setup_once() - self.cpu = cpu - - def test_malloc_fastpath(self): - ops = ''' - [] - p0 = call_malloc_nursery(16) - p1 = call_malloc_nursery(32) - p2 = call_malloc_nursery(16) - finish(p0, p1, p2) - ''' - self.interpret(ops, []) - # check the returned pointers - gc_ll_descr = self.cpu.gc_ll_descr - nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) - ref = self.cpu.get_latest_value_ref - assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 - assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 - assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 48 - # check the nursery content and state - gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.addrs[0] == nurs_adr + 64 - # slowpath never called - assert gc_ll_descr.calls == [] - - def test_malloc_slowpath(self): - ops = ''' - [] - p0 = call_malloc_nursery(16) - p1 = call_malloc_nursery(32) - p2 = call_malloc_nursery(24) # overflow - finish(p0, p1, p2) - ''' - self.interpret(ops, []) - # check the returned pointers - gc_ll_descr = self.cpu.gc_ll_descr - nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) - ref = self.cpu.get_latest_value_ref - assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 - assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 - assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 0 - # check the nursery content and state - gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.addrs[0] == nurs_adr + 24 - # this should call slow path once - assert gc_ll_descr.calls == [24] From noreply at buildbot.pypy.org Wed Mar 6 22:07:14 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 22:07:14 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix imporrt Message-ID: <20130306210714.9EEF91C0925@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62139:b6e3c93df3fd Date: 2013-03-06 23:06 +0200 http://bitbucket.org/pypy/pypy/changeset/b6e3c93df3fd/ Log: fix imporrt diff --git a/rpython/jit/backend/arm/test/test_trace_operations.py b/rpython/jit/backend/arm/test/test_trace_operations.py --- a/rpython/jit/backend/arm/test/test_trace_operations.py +++ b/rpython/jit/backend/arm/test/test_trace_operations.py @@ -1,4 +1,4 @@ -from rpython.jit.backend.x86.test.test_regalloc import BaseTestRegalloc +from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc from rpython.jit.backend.detect_cpu import getcpuclass from rpython.rtyper.lltypesystem import lltype, llmemory CPU = getcpuclass() From noreply at buildbot.pypy.org Wed Mar 6 22:12:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 22:12:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: another fix Message-ID: <20130306211256.8C3DB1C029E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62140:20c676368ee9 Date: 2013-03-06 23:12 +0200 http://bitbucket.org/pypy/pypy/changeset/20c676368ee9/ Log: another fix diff --git a/rpython/jit/backend/arm/test/test_assembler.py b/rpython/jit/backend/arm/test/test_assembler.py --- a/rpython/jit/backend/arm/test/test_assembler.py +++ b/rpython/jit/backend/arm/test/test_assembler.py @@ -24,7 +24,7 @@ clt = CompiledLoopToken(cpu, 0) clt.allgcrefs = [] token.compiled_loop_token = clt - self.a.setup(token, []) + self.a.setup(token) def test_make_operation_list(self): i = rop.INT_ADD From noreply at buildbot.pypy.org Wed Mar 6 22:29:00 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 6 Mar 2013 22:29:00 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Use platform.configure() to detect the presence of most posix functions. Message-ID: <20130306212900.B07541C101B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r62141:873c7be6cbfe Date: 2013-03-06 22:28 +0100 http://bitbucket.org/pypy/pypy/changeset/873c7be6cbfe/ Log: Use platform.configure() to detect the presence of most posix functions. The posix module now relies on these HAVE_XXX instead of the host Python running the translation. diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -73,6 +73,7 @@ 'access' : 'interp_posix.access', 'times' : 'interp_posix.times', 'system' : 'interp_posix.system', + 'getpid' : 'interp_posix.getpid', 'unlink' : 'interp_posix.unlink', 'remove' : 'interp_posix.remove', 'getcwd' : 'interp_posix.getcwd', @@ -84,7 +85,6 @@ 'listdir' : 'interp_posix.listdir', 'strerror' : 'interp_posix.strerror', 'pipe' : 'interp_posix.pipe', - 'chmod' : 'interp_posix.chmod', 'rename' : 'interp_posix.rename', 'umask' : 'interp_posix.umask', '_exit' : 'interp_posix._exit', @@ -95,25 +95,33 @@ 'urandom' : 'interp_posix.urandom', } + # XXX Missing functions: chflags lchmod lchflags ctermid fork1 + # plock setgroups initgroups tcgetpgrp + # tcsetpgrp confstr pathconf + for name in ''' - wait wait3 wait4 chown lchown ftruncate - fsync fdatasync fchdir putenv unsetenv killpg getpid - link symlink readlink - fork openpty forkpty waitpid execv execve uname sysconf fpathconf - ttyname getloadavg makedev major minor mkfifo mknod nice getlogin + ttyname chmod fchmod chown lchown fchown chroot link symlink readlink + ftruncate getloadavg nice uname execv execve fork spawnv spawnve + putenv unsetenv fchdir fsync fdatasync mknod + openpty forkpty mkfifo getlogin sysconf fpathconf getsid getuid geteuid getgid getegid getpgrp getpgid setsid setuid seteuid setgid setegid setpgrp setpgid - getppid getgroups setreuid setregid chroot - _getfullpathname + getppid getgroups setreuid setregid + wait wait3 wait4 killpg waitpid '''.split(): - if hasattr(posix, name): + symbol = 'HAVE_' + name.upper() + if getattr(rposix, symbol): interpleveldefs[name] = 'interp_posix.%s' % (name,) - for name in '''fchmod fchown - '''.split(): - symbol = 'HAS_' + name.upper() - if getattr(rposix, symbol): - interpleveldefs[name] = 'interp_posix.%s' % (name,) + if rposix.HAVE_DEVICE_MACROS: + interpleveldefs['major'] = 'interp_posix.major' + interpleveldefs['minor'] = 'interp_posix.minor' + interpleveldefs['makedev'] = 'interp_posix.makedev' + + if os.name == 'nt': + interpleveldefs['_getfullpathname'] = 'interp_posix._getfullpathname' + # On Windows, _cwait() can be used to emulate waitpid + interpleveldefs['waitpid'] = 'interp_posix.waitpid' for constant in ''' F_OK R_OK W_OK X_OK NGROUPS_MAX TMP_MAX @@ -138,6 +146,7 @@ interpleveldefs['pathconf_names'] = 'space.wrap(os.pathconf_names)' # Macros for process exit statuses: WIFEXITED &co + # XXX HAVE_SYS_WAIT_H for name in RegisterOs.w_star: if hasattr(posix, name): interpleveldefs[name] = 'interp_posix.' + name diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -63,25 +63,26 @@ except UnicodeDecodeError: # filesystem encoding is not good enough cls.w_unicode_dir = space.w_None - if hasattr(os, 'getuid'): + if rposix.HAVE_GETUID: cls.w_getuid = space.wrap(os.getuid()) + if rposix.HAVE_GETEUID: cls.w_geteuid = space.wrap(os.geteuid()) - if hasattr(os, 'getgid'): + if rposix.HAVE_GETGID: cls.w_getgid = space.wrap(os.getgid()) - if hasattr(os, 'getgroups'): + if rposix.HAVE_GETGROUPS: cls.w_getgroups = space.newlist([space.wrap(e) for e in os.getgroups()]) - if hasattr(os, 'getpgid'): + if rposix.HAVE_GETPGID: cls.w_getpgid = space.wrap(os.getpgid(os.getpid())) - if hasattr(os, 'getsid'): + if rposix.HAVE_GETSID: cls.w_getsid0 = space.wrap(os.getsid(0)) - if hasattr(os, 'sysconf'): + if rposix.HAVE_SYSCONF: sysconf_name = os.sysconf_names.keys()[0] cls.w_sysconf_name = space.wrap(sysconf_name) cls.w_sysconf_value = space.wrap(os.sysconf_names[sysconf_name]) cls.w_sysconf_result = space.wrap(os.sysconf(sysconf_name)) cls.w_SIGABRT = space.wrap(signal.SIGABRT) cls.w_python = space.wrap(sys.executable) - if hasattr(os, 'major'): + if rposix.HAVE_DEVICE_MACROS: cls.w_expected_major_12345 = space.wrap(os.major(12345)) cls.w_expected_minor_12345 = space.wrap(os.minor(12345)) cls.w_udir = space.wrap(str(udir)) @@ -101,6 +102,7 @@ if sys.platform.startswith('win32'): for name in '''_getfullpathname O_TEXT O_BINARY'''.split(): assert name in dir(self.posix) + assert 'kill' in dir(self.posix) def test_some_posix_basic_operation(self): path = self.path @@ -583,7 +585,7 @@ assert os.WIFSIGNALED(0) == False assert os.WIFSIGNALED(1) == True - if hasattr(os, 'uname'): + if rposix.HAVE_UNAME: def test_os_uname(self): os = self.posix res = os.uname() @@ -592,47 +594,47 @@ assert isinstance(i, str) assert isinstance(res, tuple) - if hasattr(os, 'getuid'): + if rposix.HAVE_GETUID: def test_os_getuid(self): os = self.posix assert os.getuid() == self.getuid assert os.geteuid() == self.geteuid - if hasattr(os, 'setuid'): + if rposix.HAVE_SETUID: def test_os_setuid_error(self): os = self.posix raises(OverflowError, os.setuid, -2**31-1) raises(OverflowError, os.setuid, 2**32) - if hasattr(os, 'getgid'): + if rposix.HAVE_GETGID: def test_os_getgid(self): os = self.posix assert os.getgid() == self.getgid - if hasattr(os, 'getgroups'): + if rposix.HAVE_GETGROUPS: def test_os_getgroups(self): os = self.posix assert os.getgroups() == self.getgroups - if hasattr(os, 'getpgid'): + if rposix.HAVE_GETPGID: def test_os_getpgid(self): os = self.posix assert os.getpgid(os.getpid()) == self.getpgid raises(OSError, os.getpgid, 1234567) - if hasattr(os, 'setgid'): + if rposix.HAVE_SETGID: def test_os_setgid_error(self): os = self.posix raises(OverflowError, os.setgid, -2**31-1) raises(OverflowError, os.setgid, 2**32) - if hasattr(os, 'getsid'): + if rposix.HAVE_GETSID: def test_os_getsid(self): os = self.posix assert os.getsid(0) == self.getsid0 raises(OSError, os.getsid, -100000) - if hasattr(os, 'sysconf'): + if rposix.HAVE_SYSCONF: def test_os_sysconf(self): os = self.posix assert os.sysconf(self.sysconf_value) == self.sysconf_result @@ -643,14 +645,14 @@ os = self.posix raises(ValueError, os.sysconf, "!@#$%!#$!@#") - if hasattr(os, 'fpathconf'): + if rposix.HAVE_FPATHCONF: def test_os_fpathconf(self): os = self.posix assert os.fpathconf(1, "PC_PIPE_BUF") >= 128 raises(OSError, os.fpathconf, -1, "PC_PIPE_BUF") raises(ValueError, os.fpathconf, 1, "##") - if hasattr(os, 'wait'): + if rposix.HAVE_WAIT: def test_os_wait(self): os = self.posix exit_status = 0x33 @@ -672,7 +674,7 @@ assert os.WIFEXITED(status) assert os.WEXITSTATUS(status) == exit_status - if hasattr(os, 'getloadavg'): + if rposix.HAVE_GETLOADAVG: def test_os_getloadavg(self): os = self.posix l0, l1, l2 = os.getloadavg() @@ -680,7 +682,7 @@ assert type(l1) is float and l0 >= 0.0 assert type(l2) is float and l0 >= 0.0 - if hasattr(os, 'major'): + if rposix.HAVE_DEVICE_MACROS: def test_major_minor(self): os = self.posix assert os.major(12345) == self.expected_major_12345 @@ -688,7 +690,7 @@ assert os.makedev(self.expected_major_12345, self.expected_minor_12345) == 12345 - if hasattr(os, 'fsync'): + if rposix.HAVE_FSYNC: def test_fsync(self): os = self.posix f = open(self.path2, "w") @@ -706,7 +708,7 @@ pass raises(ValueError, os.fsync, -1) - if hasattr(os, 'fdatasync'): + if rposix.HAVE_FDATASYNC: def test_fdatasync(self): os = self.posix f = open(self.path2, "w") @@ -722,7 +724,7 @@ pass raises(ValueError, os.fdatasync, -1) - if hasattr(os, 'fchdir'): + if rposix.HAVE_FCHDIR: def test_fchdir(self): os = self.posix localdir = os.getcwd() @@ -801,8 +803,6 @@ def test_closerange(self): os = self.posix - if not hasattr(os, 'closerange'): - skip("missing os.closerange()") fds = [os.open(self.path + str(i), os.O_CREAT|os.O_WRONLY, 0777) for i in range(15)] fds.sort() @@ -816,7 +816,7 @@ for fd in range(start, stop): raises(OSError, os.fstat, fd) # should have been closed - if hasattr(os, 'chown'): + if rposix.HAVE_CHOWN: def test_chown(self): os = self.posix os.unlink(self.path) @@ -826,7 +826,7 @@ f.close() os.chown(self.path, os.getuid(), os.getgid()) - if hasattr(os, 'lchown'): + if rposix.HAVE_LCHOWN: def test_lchown(self): os = self.posix os.unlink(self.path) @@ -834,14 +834,14 @@ os.symlink('foobar', self.path) os.lchown(self.path, os.getuid(), os.getgid()) - if rposix.HAS_FCHOWN: + if rposix.HAVE_FCHOWN: def test_fchown(self): os = self.posix f = open(self.path, "w") os.fchown(f.fileno(), os.getuid(), os.getgid()) f.close() - if hasattr(os, 'chmod'): + if rposix.HAVE_CHMOD: def test_chmod(self): import sys os = self.posix @@ -857,7 +857,7 @@ os.chmod(self.path, 0200) assert (os.stat(self.path).st_mode & 0777) == 0200 - if rposix.HAS_FCHMOD: + if rposix.HAVE_FCHMOD: def test_fchmod(self): os = self.posix f = open(self.path, "w") @@ -866,7 +866,7 @@ f.close() assert (os.stat(self.path).st_mode & 0777) == 0200 - if hasattr(os, 'mkfifo'): + if rposix.HAVE_MKFIFO: def test_mkfifo(self): os = self.posix os.mkfifo(self.path2 + 'test_mkfifo', 0666) @@ -874,7 +874,7 @@ import stat assert stat.S_ISFIFO(st.st_mode) - if hasattr(os, 'mknod'): + if rposix.HAVE_MKNOD: def test_mknod(self): import stat os = self.posix @@ -907,7 +907,7 @@ assert stat.S_ISCHR(st.st_mode) assert st.st_rdev == 0x105 - if hasattr(os, 'nice') and hasattr(os, 'fork') and hasattr(os, 'waitpid'): + if rposix.HAVE_NICE and rposix.HAVE_FORK and rposix.HAVE_WAITPID: def test_nice(self): os = self.posix myprio = os.nice(0) @@ -922,7 +922,7 @@ assert os.WIFEXITED(status1) assert os.WEXITSTATUS(status1) == myprio + 3 - if hasattr(os, 'symlink'): + if rposix.HAVE_SYMLINK: def test_symlink(self): posix = self.posix unicode_dir = self.unicode_dir @@ -1005,10 +1005,6 @@ # not to some code inside app_posix.py assert w[-1].lineno == f_tmpnam_warning.func_code.co_firstlineno - def test_has_kill(self): - import os - assert hasattr(os, 'kill') - def test_pipe_flush(self): os = self.posix ffd, gfd = os.pipe() diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -84,7 +84,8 @@ else: separate_module_sources = [] export_symbols = [] - includes=['errno.h', 'stdio.h', 'unistd.h', 'sys/stat.h'] + includes=['errno.h', 'stdio.h', 'stdlib.h', 'unistd.h', 'sys/stat.h', + 'signal.h', 'pty.h', 'sys/utsname.h', 'sys/wait.h'] rposix_eci = ExternalCompilationInfo( includes=includes, separate_module_sources=separate_module_sources, @@ -94,8 +95,20 @@ class CConfig: _compilation_info_ = rposix_eci - HAS_FCHMOD = rffi_platform.Has("fchmod") - HAS_FCHOWN = rffi_platform.Has("fchown") + HAVE_DEVICE_MACROS = rffi_platform.Has("makedev(major(0),minor(0))") + +for name in ''' + ttyname chmod fchmod chown lchown fchown chroot link symlink readlink + ftruncate getloadavg nice uname execv execve fork spawnv spawnve + putenv unsetenv fchdir fsync fdatasync mknod + openpty forkpty mkfifo getlogin sysconf fpathconf + getsid getuid geteuid getgid getegid getpgrp getpgid + setsid setuid seteuid setgid setegid setpgrp setpgid + getppid getgroups setreuid setregid + wait wait3 wait4 killpg waitpid + '''.split(): + symbol = 'HAVE_' + name.upper() + setattr(CConfig, symbol, rffi_platform.Has(name)) globals().update(rffi_platform.configure(CConfig)) From noreply at buildbot.pypy.org Wed Mar 6 22:31:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 22:31:55 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup _sqlite3.Statement.set_params Message-ID: <20130306213155.D49F41C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62142:42054fe35ff6 Date: 2013-03-06 16:29 -0500 http://bitbucket.org/pypy/pypy/changeset/42054fe35ff6/ Log: cleanup _sqlite3.Statement.set_params diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -797,7 +797,7 @@ return wrapper @__check_cursor_wrap - def execute(self, sql, params=None): + def execute(self, sql, params=[]): self.__locked = True try: self.__description = None @@ -1102,34 +1102,30 @@ raise self.__con._get_exception(ret) self._in_use = True - if params is None: - if sqlite.sqlite3_bind_parameter_count(self._statement) != 0: - raise ProgrammingError("wrong number of arguments") - return - - params_type = None - if isinstance(params, dict): - params_type = dict + num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) + if not isinstance(params, dict): + num_params = len(params) + if num_params != num_params_needed: + raise ProgrammingError("Incorrect number of bindings supplied. " + "The current statement uses %d, and " + "there are %d supplied." % + (num_params_needed, num_params)) + for i in range(num_params): + self.__set_param(i + 1, params[i]) else: - params_type = list - - if params_type == list: - if len(params) != sqlite.sqlite3_bind_parameter_count(self._statement): - raise ProgrammingError("wrong number of arguments") - - for i in range(len(params)): - self.__set_param(i+1, params[i]) - else: - for idx in range(1, sqlite.sqlite3_bind_parameter_count(self._statement) + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self._statement, idx) + for i in range(1, num_params_needed + 1): + param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) if param_name is None: - raise ProgrammingError("need named parameters") + raise ProgrammingError("Binding %d has no name, but you " + "supplied a dictionary (which has " + "only names)." % i) param_name = param_name[1:] try: param = params[param_name] except KeyError: - raise ProgrammingError("missing parameter '%s'" % param) - self.__set_param(idx, param) + raise ProgrammingError("You did not supply a value for " + "binding %d." % i) + self.__set_param(i, param) def _next(self, cursor): self.__con._check_closed() From noreply at buildbot.pypy.org Wed Mar 6 22:31:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 22:31:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130306213157.55EF81C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62143:f4c340c0fdad Date: 2013-03-06 16:31 -0500 http://bitbucket.org/pypy/pypy/changeset/f4c340c0fdad/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -804,7 +804,7 @@ return wrapper @__check_cursor_wrap - def execute(self, sql, params=None): + def execute(self, sql, params=[]): self.__locked = True try: self.__description = None @@ -1099,34 +1099,30 @@ raise self.__con._get_exception(ret) self._in_use = True - if params is None: - if sqlite.sqlite3_bind_parameter_count(self._statement) != 0: - raise ProgrammingError("wrong number of arguments") - return - - params_type = None - if isinstance(params, dict): - params_type = dict + num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) + if not isinstance(params, dict): + num_params = len(params) + if num_params != num_params_needed: + raise ProgrammingError("Incorrect number of bindings supplied. " + "The current statement uses %d, and " + "there are %d supplied." % + (num_params_needed, num_params)) + for i in range(num_params): + self.__set_param(i + 1, params[i]) else: - params_type = list - - if params_type == list: - if len(params) != sqlite.sqlite3_bind_parameter_count(self._statement): - raise ProgrammingError("wrong number of arguments") - - for i in range(len(params)): - self.__set_param(i+1, params[i]) - else: - for idx in range(1, sqlite.sqlite3_bind_parameter_count(self._statement) + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self._statement, idx) + for i in range(1, num_params_needed + 1): + param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) if param_name is None: - raise ProgrammingError("need named parameters") + raise ProgrammingError("Binding %d has no name, but you " + "supplied a dictionary (which has " + "only names)." % i) param_name = param_name[1:].decode('utf-8') try: param = params[param_name] except KeyError: - raise ProgrammingError("missing parameter %r" % param_name) - self.__set_param(idx, param) + raise ProgrammingError("You did not supply a value for " + "binding %d." % i) + self.__set_param(i, param) def _next(self, cursor): self.__con._check_closed() From noreply at buildbot.pypy.org Wed Mar 6 22:47:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 22:47:53 +0100 (CET) Subject: [pypy-commit] pypy default: more small cleanups for sqlite Message-ID: <20130306214753.E99921C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62144:a511e6de3ae1 Date: 2013-03-06 16:45 -0500 http://bitbucket.org/pypy/pypy/changeset/a511e6de3ae1/ Log: more small cleanups for sqlite diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -741,7 +741,6 @@ class Cursor(object): __initialized = False - __connection = None __statement = None def __init__(self, con): @@ -763,11 +762,10 @@ self.__rowcount = -1 def __del__(self): - if self.__connection: - try: - self.__connection._cursors.remove(weakref.ref(self)) - except ValueError: - pass + try: + self.__connection._cursors.remove(weakref.ref(self)) + except (AttributeError, ValueError): + pass if self.__statement: self.__statement._reset() @@ -866,8 +864,8 @@ self.__connection._in_transaction = \ not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) + self.__statement._reset() self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) - self.__statement._reset() finally: self.__locked = False @@ -1097,9 +1095,6 @@ str(type(param))) def _set_params(self, params): - ret = sqlite.sqlite3_reset(self._statement) - if ret != SQLITE_OK: - raise self.__con._get_exception(ret) self._in_use = True num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) From noreply at buildbot.pypy.org Wed Mar 6 22:52:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 22:52:41 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: try to write a better test Message-ID: <20130306215241.BF7141C101B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62145:11b4e036be3e Date: 2013-03-06 23:52 +0200 http://bitbucket.org/pypy/pypy/changeset/11b4e036be3e/ Log: try to write a better test 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 @@ -107,7 +107,7 @@ class CPU_ARM(AbstractARMCPU): """ARM v7 uses softfp ABI, requires vfp""" - pass + backend_name = "arm" ArmCPU = CPU_ARM class CPU_ARMHF(AbstractARMCPU): 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 @@ -2,6 +2,7 @@ """ Tests for register allocation for common constructs """ +import re from rpython.jit.metainterp.history import TargetToken, BasicFinalDescr,\ JitCellToken, BasicFailDescr, AbstractDescr from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm,\ @@ -18,6 +19,12 @@ CPU = getcpuclass() +def getmap(frame): + r = '' + for elem in frame.jf_gcmap: + r += bin(elem)[2:] + return r[r.find('1'):] + class TestRegallocGcIntegration(BaseTestRegalloc): cpu = CPU(None, None) @@ -66,17 +73,21 @@ frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, self.deadframe) # p0 and p3 should be in registers, p1 not so much assert self.getptr(0, lltype.Ptr(self.S)) == s1 - # this is a fairly CPU specific check - assert len(frame.jf_gcmap) == 1 # the gcmap should contain three things, p0, p1 and p3 # p3 stays in a register # while p0 and p1 are on the frame - if self.cpu.IS_64_BIT: - nos = [11, 12, 31] + b = getmap(frame) + nos = [len(b) - 1 - i.start() for i in re.finditer('1', b)] + nos.reverse() + if self.cpu.backend_name.startswith('x86'): + if self.cpu.IS_64_BIT: + assert nos == [11, 12, 31] + else: + assert nos == [4, 5, 25] + elif self.cpu.backend_name.startswith('arm'): + assert nos == [] else: - nos = [4, 5, 25] - assert frame.jf_gcmap[0] == ((1 << nos[0]) | (1 << nos[1]) | - (1 << nos[2])) + raise Exception("write the data here") assert frame.jf_frame[nos[0]] assert frame.jf_frame[nos[1]] assert frame.jf_frame[nos[2]] From noreply at buildbot.pypy.org Wed Mar 6 23:01:58 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 23:01:58 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the test Message-ID: <20130306220158.76CC61C106A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62146:aef7ed124ee1 Date: 2013-03-07 00:01 +0200 http://bitbucket.org/pypy/pypy/changeset/aef7ed124ee1/ Log: fix the test 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 @@ -85,7 +85,7 @@ else: assert nos == [4, 5, 25] elif self.cpu.backend_name.startswith('arm'): - assert nos == [] + assert nos == [15, 25, 26] else: raise Exception("write the data here") assert frame.jf_frame[nos[0]] From noreply at buildbot.pypy.org Wed Mar 6 23:05:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Mar 2013 23:05:15 +0100 (CET) Subject: [pypy-commit] pypy default: only call sqlite3_{finalize, reset} if not already called Message-ID: <20130306220515.BEF511C106A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62147:60a6a2e99263 Date: 2013-03-06 17:04 -0500 http://bitbucket.org/pypy/pypy/changeset/60a6a2e99263/ Log: only call sqlite3_{finalize,reset} if not already called diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1018,15 +1018,16 @@ sqlite.sqlite3_finalize(self._statement) def _finalize(self): - sqlite.sqlite3_finalize(self._statement) - self._statement = None + if self._statement: + sqlite.sqlite3_finalize(self._statement) + self._statement = None self._in_use = False def _reset(self): - ret = sqlite.sqlite3_reset(self._statement) - self._in_use = False + if self._in_use and self._statement: + ret = sqlite.sqlite3_reset(self._statement) + self._in_use = False self._exhausted = False - return ret def _build_row_cast_map(self): self.__row_cast_map = [] From noreply at buildbot.pypy.org Wed Mar 6 23:05:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 23:05:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: store the loop for debugging Message-ID: <20130306220527.2E63B1C0925@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62148:ea68db3f9825 Date: 2013-03-07 00:04 +0200 http://bitbucket.org/pypy/pypy/changeset/ea68db3f9825/ Log: store the loop for debugging diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py --- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py @@ -95,6 +95,7 @@ def interpret(self, ops, args, run=True): loop = self.parse(ops) + self.loop = loop looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) arguments = [] From noreply at buildbot.pypy.org Wed Mar 6 23:34:21 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 23:34:21 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: oops Message-ID: <20130306223421.3AD2C1C106A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62149:f30e3aaca824 Date: 2013-03-07 00:33 +0200 http://bitbucket.org/pypy/pypy/changeset/f30e3aaca824/ Log: oops 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 @@ -22,7 +22,7 @@ def getmap(frame): r = '' for elem in frame.jf_gcmap: - r += bin(elem)[2:] + r = bin(elem)[2:] + r return r[r.find('1'):] class TestRegallocGcIntegration(BaseTestRegalloc): @@ -85,7 +85,7 @@ else: assert nos == [4, 5, 25] elif self.cpu.backend_name.startswith('arm'): - assert nos == [15, 25, 26] + assert nos == [9, 10, 47] else: raise Exception("write the data here") assert frame.jf_frame[nos[0]] From noreply at buildbot.pypy.org Wed Mar 6 23:36:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Mar 2013 23:36:37 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: one more Message-ID: <20130306223637.CE2F31C01D2@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62150:f635eff12548 Date: 2013-03-07 00:36 +0200 http://bitbucket.org/pypy/pypy/changeset/f635eff12548/ Log: one more 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 @@ -22,7 +22,9 @@ def getmap(frame): r = '' for elem in frame.jf_gcmap: - r = bin(elem)[2:] + r + elem = bin(elem)[2:] + elem = '0' * (WORD * 8 - len(elem)) + elem + r = elem + r return r[r.find('1'):] class TestRegallocGcIntegration(BaseTestRegalloc): From noreply at buildbot.pypy.org Thu Mar 7 00:54:40 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 7 Mar 2013 00:54:40 +0100 (CET) Subject: [pypy-commit] pypy py3k-memoryview: Only check for TypeError here. Message-ID: <20130306235440.5075D1C106A@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k-memoryview Changeset: r62151:e444775753c6 Date: 2013-03-06 12:51 +0100 http://bitbucket.org/pypy/pypy/changeset/e444775753c6/ Log: Only check for TypeError here. diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -67,7 +67,7 @@ assert data == bytearray(eval("b'zbcefg'")) v[1:4] = b'123' assert data == bytearray(eval("b'z123fg'")) - raises((ValueError, TypeError), "v[2] = 'spam'") + raises(TypeError, "v[2] = 'spam'") def test_memoryview_attrs(self): v = memoryview(b"a"*100) From noreply at buildbot.pypy.org Thu Mar 7 00:55:15 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 7 Mar 2013 00:55:15 +0100 (CET) Subject: [pypy-commit] pypy py3k: Remove py3k attribute from base object space. It's not necessary anymore because the flow object space is independent from the interpreter now. Message-ID: <20130306235515.921281C106A@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r62152:8b8e895b4fcb Date: 2013-03-07 00:53 +0100 http://bitbucket.org/pypy/pypy/changeset/8b8e895b4fcb/ Log: Remove py3k attribute from base object space. It's not necessary anymore because the flow object space is independent from the interpreter now. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -295,8 +295,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - py3k = True # are we interpreting py3k bytecode? - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -534,7 +534,6 @@ self.setdictscope(w_locals) def POP_EXCEPT(self, oparg, next_instr): - assert self.space.py3k block = self.pop_block() block.cleanup(self) return @@ -1327,14 +1326,12 @@ # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. - if frame.space.py3k: - # this is popped by POP_EXCEPT, which is present only in py3k - w_last_exception = W_OperationError(frame.last_exception) - w_last_exception = frame.space.wrap(w_last_exception) - frame.pushvalue(w_last_exception) - block = ExceptHandlerBlock(self.valuestackdepth, - 0, frame.lastblock) - frame.lastblock = block + # this is popped by POP_EXCEPT, which is present only in py3k + w_last_exception = W_OperationError(frame.last_exception) + w_last_exception = frame.space.wrap(w_last_exception) + frame.pushvalue(w_last_exception) + block = ExceptHandlerBlock(self.valuestackdepth, 0, frame.lastblock) + frame.lastblock = block frame.pushvalue(frame.space.wrap(unroller)) frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) From noreply at buildbot.pypy.org Thu Mar 7 01:12:36 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 01:12:36 +0100 (CET) Subject: [pypy-commit] pypy default: these are redundant Message-ID: <20130307001236.788A81C029E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62153:47b22d98ea8d Date: 2013-03-06 19:11 -0500 http://bitbucket.org/pypy/pypy/changeset/47b22d98ea8d/ Log: these are redundant diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1070,7 +1070,7 @@ def __set_param(self, idx, param): cvt = converters.get(type(param)) if cvt is not None: - cvt = param = cvt(param) + param = cvt(param) param = adapt(param) @@ -1124,8 +1124,6 @@ self.__set_param(i, param) def _next(self, cursor): - self.__con._check_closed() - self.__con._check_thread() if self._exhausted: raise StopIteration item = self._item From noreply at buildbot.pypy.org Thu Mar 7 01:26:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 01:26:26 +0100 (CET) Subject: [pypy-commit] pypy default: check return value of sqlite3_bind_xxx Message-ID: <20130307002626.BAC811C13DE@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62154:e14333f7fb32 Date: 2013-03-06 19:22 -0500 http://bitbucket.org/pypy/pypy/changeset/e14333f7fb32/ Log: check return value of sqlite3_bind_xxx diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1075,25 +1075,25 @@ param = adapt(param) if param is None: - sqlite.sqlite3_bind_null(self._statement, idx) + rc = sqlite.sqlite3_bind_null(self._statement, idx) elif type(param) in (bool, int, long): if -2147483648 <= param <= 2147483647: - sqlite.sqlite3_bind_int(self._statement, idx, param) + rc = sqlite.sqlite3_bind_int(self._statement, idx, param) else: - sqlite.sqlite3_bind_int64(self._statement, idx, param) + rc = sqlite.sqlite3_bind_int64(self._statement, idx, param) elif type(param) is float: - sqlite.sqlite3_bind_double(self._statement, idx, param) + rc = sqlite.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, str): self.__check_decodable(param) - sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif isinstance(param, unicode): param = param.encode("utf-8") - sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) is buffer: - sqlite.sqlite3_bind_blob(self._statement, idx, str(param), len(param), SQLITE_TRANSIENT) + rc = sqlite.sqlite3_bind_blob(self._statement, idx, str(param), len(param), SQLITE_TRANSIENT) else: - raise InterfaceError("parameter type %s is not supported" % - str(type(param))) + rc = -1 + return rc def _set_params(self, params): self._in_use = True @@ -1107,7 +1107,10 @@ "there are %d supplied." % (num_params_needed, num_params)) for i in range(num_params): - self.__set_param(i + 1, params[i]) + rc = self.__set_param(i + 1, params[i]) + if rc != SQLITE_OK: + raise InterfaceError("Error binding parameter %d - " + "probably unsupported type." % i) else: for i in range(1, num_params_needed + 1): param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) @@ -1121,7 +1124,11 @@ except KeyError: raise ProgrammingError("You did not supply a value for " "binding %d." % i) - self.__set_param(i, param) + rc = self.__set_param(i, param) + if rc != SQLITE_OK: + raise InterfaceError("Error binding parameter :%s - " + "probably unsupported type." % + param_name) def _next(self, cursor): if self._exhausted: From noreply at buildbot.pypy.org Thu Mar 7 01:53:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 01:53:44 +0100 (CET) Subject: [pypy-commit] pypy default: improve sqlite parameter type checking, test Message-ID: <20130307005344.05CA71C3AB1@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62155:f22a27ebaeed Date: 2013-03-06 19:52 -0500 http://bitbucket.org/pypy/pypy/changeset/f22a27ebaeed/ Log: improve sqlite parameter type checking, test diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1099,7 +1099,9 @@ self._in_use = True num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) - if not isinstance(params, dict): + if isinstance(params, (tuple, list)) or \ + not isinstance(params, dict) and \ + hasattr(params, '__len__') and hasattr(params, '__getitem__'): num_params = len(params) if num_params != num_params_needed: raise ProgrammingError("Incorrect number of bindings supplied. " @@ -1111,7 +1113,7 @@ if rc != SQLITE_OK: raise InterfaceError("Error binding parameter %d - " "probably unsupported type." % i) - else: + elif isinstance(params, dict): for i in range(1, num_params_needed + 1): param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) if param_name is None: @@ -1129,6 +1131,8 @@ raise InterfaceError("Error binding parameter :%s - " "probably unsupported type." % param_name) + else: + raise ValueError("parameters are of unsupported type") def _next(self, cursor): if self._exhausted: 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 @@ -126,3 +126,20 @@ con.commit() except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") + +def test_statement_param_checking(): + con = _sqlite3.connect(':memory:') + con.execute('create table foo(x)') + con.execute('insert into foo(x) values (?)', [2]) + con.execute('insert into foo(x) values (?)', (2,)) + class seq(object): + def __len__(self): + return 1 + def __getitem__(self, key): + return 2 + con.execute('insert into foo(x) values (?)', seq()) + with pytest.raises(_sqlite3.ProgrammingError): + con.execute('insert into foo(x) values (?)', {2:2}) + with pytest.raises(ValueError) as e: + con.execute('insert into foo(x) values (?)', 2) + assert str(e.value) == 'parameters are of unsupported type' From noreply at buildbot.pypy.org Thu Mar 7 07:32:31 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 7 Mar 2013 07:32:31 +0100 (CET) Subject: [pypy-commit] pypy default: Fix struct definition in ll_termios. Message-ID: <20130307063231.E54B51C1067@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: Changeset: r62157:71045d55f113 Date: 2013-03-07 07:28 +0100 http://bitbucket.org/pypy/pypy/changeset/71045d55f113/ Log: Fix struct definition in ll_termios. diff --git a/rpython/rtyper/module/ll_termios.py b/rpython/rtyper/module/ll_termios.py --- a/rpython/rtyper/module/ll_termios.py +++ b/rpython/rtyper/module/ll_termios.py @@ -24,17 +24,28 @@ class CConfig: _compilation_info_ = eci NCCS = rffi_platform.DefinedConstantInteger('NCCS') + _HAVE_STRUCT_TERMIOS_C_ISPEED = rffi_platform.Defined( + '_HAVE_STRUCT_TERMIOS_C_ISPEED') + _HAVE_STRUCT_TERMIOS_C_OSPEED = rffi_platform.Defined( + '_HAVE_STRUCT_TERMIOS_C_OSPEED') -NCCS = rffi_platform.configure(CConfig)['NCCS'] +c_config = rffi_platform.configure(CConfig) +NCCS = c_config['NCCS'] TCFLAG_T = rffi.UINT CC_T = rffi.UCHAR SPEED_T = rffi.UINT INT = rffi.INT +_add = [] +if c_config['_HAVE_STRUCT_TERMIOS_C_ISPEED']: + _add.append(('c_ispeed', SPEED_T)) +if c_config['_HAVE_STRUCT_TERMIOS_C_OSPEED']: + _add.append(('c_ospeed', SPEED_T)) TERMIOSP = rffi.CStructPtr('termios', ('c_iflag', TCFLAG_T), ('c_oflag', TCFLAG_T), ('c_cflag', TCFLAG_T), ('c_lflag', TCFLAG_T), - ('c_cc', lltype.FixedSizeArray(CC_T, NCCS))) + ('c_line', CC_T), + ('c_cc', lltype.FixedSizeArray(CC_T, NCCS)), *_add) def c_external(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci) From noreply at buildbot.pypy.org Thu Mar 7 07:32:30 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 7 Mar 2013 07:32:30 +0100 (CET) Subject: [pypy-commit] pypy default: Random cleanups. Message-ID: <20130307063230.A58831C1058@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: Changeset: r62156:9cec3981c9a2 Date: 2013-03-07 07:15 +0100 http://bitbucket.org/pypy/pypy/changeset/9cec3981c9a2/ Log: Random cleanups. diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -7,8 +7,7 @@ from rpython.memory.gctransform.log import log from rpython.memory.gctransform.support import get_rtti, ll_call_destructor from rpython.memory.gctransform.transform import GCTransformer -from rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, \ - WEAKREFPTR +from rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, WEAKREFPTR from rpython.tool.sourcetools import func_with_new_name from rpython.translator.backendopt import graphanalyze from rpython.translator.backendopt.finalizer import FinalizerAnalyzer @@ -317,7 +316,8 @@ malloc_fast = func_with_new_name( malloc_fast_meth, "malloc_fast") - s_False = annmodel.SomeBool(); s_False.const = False + s_False = annmodel.SomeBool() + s_False.const = False self.malloc_fast_ptr = getfn( malloc_fast, [s_gc, s_typeid16, @@ -335,7 +335,8 @@ malloc_varsize_clear_fast = func_with_new_name( GCClass.malloc_varsize_clear.im_func, "malloc_varsize_clear_fast") - s_False = annmodel.SomeBool(); s_False.const = False + s_False = annmodel.SomeBool() + s_False.const = False self.malloc_varsize_clear_fast_ptr = getfn( malloc_varsize_clear_fast, [s_gc, s_typeid16, @@ -614,7 +615,7 @@ if self.collect_analyzer.analyze_direct_call(graph): raise Exception("'no_collect' function can trigger collection:" " %s" % func) - + if self.write_barrier_ptr: self.clean_sets = ( find_initializing_stores(self.collect_analyzer, graph)) @@ -1180,7 +1181,7 @@ if self.gcdata.gc.moving_gc and not keep_current_args: # moving GCs don't borrow, so the caller does not need to keep # the arguments alive - livevars = [var for var in hop.livevars_after_op()] + livevars = hop.livevars_after_op() else: livevars = hop.livevars_after_op() + hop.current_op_keeps_alive() return livevars From noreply at buildbot.pypy.org Thu Mar 7 08:50:34 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 08:50:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: simplify Message-ID: <20130307075034.9BC531C06F2@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62158:e569a7d9ad90 Date: 2013-03-06 23:42 -0800 http://bitbucket.org/pypy/pypy/changeset/e569a7d9ad90/ Log: simplify diff --git a/pypy/module/imp/test/support.py b/pypy/module/imp/test/support.py --- a/pypy/module/imp/test/support.py +++ b/pypy/module/imp/test/support.py @@ -10,12 +10,8 @@ if sys.platform == 'nt': testfn_unencodable = testfn + u"-\u5171\u0141\u2661\u0363\uDC80" elif sys.platform != 'darwin': - fsenc = sys.getfilesystemencoding() try: - '\xff'.decode(fsenc) + '\xff'.decode(sys.getfilesystemencoding()) except UnicodeDecodeError: - w_unenc = space.call_method(space.wrapbytes('-\xff'), 'decode', - space.wrap(fsenc), - space.wrap('surrogateescape')) - testfn_unencodable = testfn + space.unicode_w(w_unenc) + testfn_unencodable = testfn + u'-\udcff' cls.w_testfn_unencodable = space.wrap(testfn_unencodable) From noreply at buildbot.pypy.org Thu Mar 7 09:34:47 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 7 Mar 2013 09:34:47 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: start working on gcmap Message-ID: <20130307083447.BE5501C101B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62159:afa6402200b1 Date: 2013-03-07 10:34 +0200 http://bitbucket.org/pypy/pypy/changeset/afa6402200b1/ Log: start working on gcmap diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -352,7 +352,7 @@ self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): - return # XXX fix me + XXX mc = ARMv7Builder() if self.cpu.supports_floats: vfp_regs = r.all_vfp_regs @@ -1262,7 +1262,7 @@ else: raise AssertionError('Trying to pop to an invalid location') - def malloc_cond(self, nursery_free_adr, nursery_top_adr, size): + def malloc_cond(self, gcmap, nursery_free_adr, nursery_top_adr, size): assert size & (WORD-1) == 0 # must be correctly aligned self.mc.gen_load_int(r.r0.value, nursery_free_adr) @@ -1291,14 +1291,11 @@ self.mc.gen_load_int(r.ip.value, nursery_free_adr) self.mc.STR_ri(r.r1.value, r.ip.value) - def push_gcmap(self, mc, gcmap, push=False, mov=False, store=False): + def push_gcmap(self, mc, gcmap, push=False, store=False): ptr = rffi.cast(lltype.Signed, gcmap) if push: mc.gen_load_int(r.ip.value, ptr) mc.PUSH([r.ip.value]) - elif mov: - assert 0 - mc.MOV(RawEspLoc(0, REF), ptr) else: assert store ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1293,7 +1293,9 @@ assert len(arglocs) == 1 size = arglocs[0].value gc_ll_descr = self.cpu.gc_ll_descr + gcmap = regalloc.get_gcmap([r.r0, r.r1]) self.malloc_cond( + gcmap, gc_ll_descr.get_nursery_free_addr(), gc_ll_descr.get_nursery_top_addr(), size diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -15,13 +15,13 @@ check_imm_box ) from rpython.jit.backend.arm.jump import remap_frame_layout_mixed -from rpython.jit.backend.arm.arch import MY_COPY_OF_REGS from rpython.jit.backend.arm.arch import WORD, JITFRAME_FIXED_SIZE from rpython.jit.codewriter import longlong -from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr, - Box, BoxPtr, - INT, REF, FLOAT) -from rpython.jit.metainterp.history import JitCellToken, TargetToken +from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, + ConstPtr, BoxInt, + Box, BoxPtr, + INT, REF, FLOAT) +from rpython.jit.metainterp.history import TargetToken from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.llsupport.descr import ArrayDescr from rpython.jit.backend.llsupport.gcmap import allocate_gcmap @@ -32,7 +32,7 @@ from rpython.jit.backend.llsupport.descr import unpack_arraydescr from rpython.jit.backend.llsupport.descr import unpack_fielddescr from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr -from rpython.rlib.rarithmetic import r_longlong, r_uint +from rpython.rlib.rarithmetic import r_uint # xxx hack: set a default value for TargetToken._ll_loop_code. If 0, we know @@ -338,7 +338,6 @@ frame_depth = self.fm.get_frame_depth() gcmap = allocate_gcmap(self.assembler, frame_depth, JITFRAME_FIXED_SIZE) - debug_start("jit-backend-gcmap") for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: continue @@ -352,9 +351,6 @@ assert loc.is_stack() val = loc.value // WORD gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) - for i in range(len(gcmap)): - debug_print(str(gcmap[i])) - debug_stop('jit-backend-gcmap') return gcmap # ------------------------------------------------------------ @@ -1012,24 +1008,17 @@ self.possibly_free_var(t) return [imm(size)] - def get_mark_gc_roots(self, gcrootmap, use_copy_area=False): - shape = gcrootmap.get_basic_shape() - for v, val in self.frame_manager.bindings.items(): - if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)): - assert val.is_stack() - gcrootmap.add_frame_offset(shape, -val.value) - for v, reg in self.rm.reg_bindings.items(): - if reg is r.r0: - continue - if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)): - if use_copy_area: - assert reg in self.rm.REGLOC_TO_COPY_AREA_OFS - area_offset = self.rm.REGLOC_TO_COPY_AREA_OFS[reg] - gcrootmap.add_frame_offset(shape, area_offset) - else: - assert 0, 'sure??' - return gcrootmap.compress_callshape(shape, - self.assembler.datablockwrapper) + def prepare_op_call_malloc_nursery_varsize_small(self, op, fcond): + size_box = op.getarg(0) + assert isinstance(size_box, BoxInt) + size = size_box.getint() + + self.rm.force_allocate_reg(op.result, selected_reg=r.r0) + t = TempInt() + self.rm.force_allocate_reg(t, selected_reg=r.r1) + self.possibly_free_var(op.result) + self.possibly_free_var(t) + return [imm(size)] prepare_op_debug_merge_point = void prepare_op_jit_debug = void From noreply at buildbot.pypy.org Thu Mar 7 09:35:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 09:35:28 +0100 (CET) Subject: [pypy-commit] pypy default: more cleanups/fixes for _sqlite3 Message-ID: <20130307083528.DB7451C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62160:6c95beb61fa6 Date: 2013-03-07 02:33 -0500 http://bitbucket.org/pypy/pypy/changeset/6c95beb61fa6/ Log: more cleanups/fixes for _sqlite3 diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -29,6 +29,7 @@ from collections import OrderedDict from functools import wraps import datetime +import string import sys import weakref from threading import _get_ident as _thread_get_ident @@ -219,7 +220,7 @@ sqlite.sqlite3_total_changes.argtypes = [c_void_p] sqlite.sqlite3_total_changes.restype = c_int -sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_char_p, c_int, c_void_p] +sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] sqlite.sqlite3_result_blob.restype = None sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64] sqlite.sqlite3_result_int64.restype = None @@ -242,7 +243,7 @@ ########################################## # SQLite version information -sqlite_version = sqlite.sqlite3_libversion() +sqlite_version = sqlite.sqlite3_libversion().decode('utf-8') class Error(StandardError): pass @@ -289,9 +290,6 @@ self.cache = OrderedDict() def get(self, sql, row_factory): - if isinstance(sql, unicode): - sql = sql.encode('utf-8') - try: stat = self.cache[sql] except KeyError: @@ -315,6 +313,8 @@ self.__initialized = True self._db = c_void_p() + if isinstance(database, unicode): + database = database.encode('utf-8') if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: @@ -404,7 +404,7 @@ def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self._db) - error_message = sqlite.sqlite3_errmsg(self._db) + error_message = sqlite.sqlite3_errmsg(self._db).decode('utf-8') if error_code == SQLITE_OK: raise ValueError("error signalled but got SQLITE_OK") @@ -498,7 +498,7 @@ statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, "COMMIT", -1, + ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, byref(statement), next_char) try: if ret != SQLITE_OK: @@ -528,7 +528,7 @@ statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, "ROLLBACK", -1, + ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, byref(statement), next_char) try: if ret != SQLITE_OK: @@ -559,6 +559,9 @@ function_callback(callback, context, nargs, c_params) c_closure = _FUNC(closure) self.__func_cache[callback] = c_closure, closure + + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, c_closure, @@ -574,7 +577,6 @@ c_step_callback, c_final_callback, _, _ = self.__aggregates[cls] except KeyError: def step_callback(context, argc, c_params): - aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), @@ -584,8 +586,8 @@ try: aggregate = cls() except Exception: - msg = ("user-defined aggregate's '__init__' " - "method raised error") + msg = (b"user-defined aggregate's '__init__' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) @@ -598,12 +600,11 @@ try: aggregate.step(*params) except Exception: - msg = ("user-defined aggregate's 'step' " - "method raised error") + msg = (b"user-defined aggregate's 'step' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) def final_callback(context): - aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), @@ -614,8 +615,8 @@ try: val = aggregate.finalize() except Exception: - msg = ("user-defined aggregate's 'finalize' " - "method raised error") + msg = (b"user-defined aggregate's 'finalize' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) @@ -628,6 +629,8 @@ self.__aggregates[cls] = (c_step_callback, c_final_callback, step_callback, final_callback) + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, cast(None, _FUNC), @@ -640,7 +643,7 @@ @_check_closed_wrap def create_collation(self, name, callback): name = name.upper() - if not name.replace('_', '').isalnum(): + if not all(c in string.uppercase + string.digits + '_' for c in name): raise ProgrammingError("invalid character in collation name") if callback is None: @@ -651,14 +654,16 @@ raise TypeError("parameter must be callable") def collation_callback(context, len1, str1, len2, str2): - text1 = string_at(str1, len1) - text2 = string_at(str2, len2) + text1 = string_at(str1, len1).decode('utf-8') + text2 = string_at(str2, len2).decode('utf-8') return callback(text1, text2) c_collation_callback = _COLLATION(collation_callback) self.__collations[name] = c_collation_callback + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_collation(self._db, name, SQLITE_UTF8, None, @@ -724,9 +729,7 @@ if val is None: self.commit() else: - if isinstance(val, unicode): - val = str(val) - self.__begin_statement = 'BEGIN ' + val + self.__begin_statement = b"BEGIN " + val.encode('ascii') self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) @@ -874,10 +877,10 @@ def executescript(self, sql): self.__description = None self._reset = False - if type(sql) is unicode: - sql = sql.encode("utf-8") self.__check_cursor() statement = c_void_p() + if isinstance(sql, unicode): + sql = sql.encode('utf-8') c_sql = c_char_p(sql) self.__connection.commit() @@ -983,7 +986,7 @@ def __init__(self, connection, sql): self.__con = connection - if not isinstance(sql, str): + if not isinstance(sql, (str, unicode)): raise ValueError("sql must be a string") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): @@ -999,19 +1002,22 @@ self._statement = c_void_p() next_char = c_char_p() - sql_char = c_char_p(sql) - ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql_char, -1, byref(self._statement), byref(next_char)) + if isinstance(sql, unicode): + sql = sql.encode('utf-8') + + ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) if ret == SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.__con._db, "select 42", -1, byref(self._statement), byref(next_char)) + ret = sqlite.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) self._kind = Statement._DQL if ret != SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) - if _check_remaining_sql(next_char.value): + next_char = next_char.value.decode('utf-8') + if _check_remaining_sql(next_char): raise Warning("One and only one statement required: %r" % - (next_char.value,)) + next_char) def __del__(self): if self._statement: @@ -1037,6 +1043,7 @@ if self.__con._detect_types & PARSE_COLNAMES: colname = sqlite.sqlite3_column_name(self._statement, i) if colname is not None: + colname = colname.decode('utf-8') type_start = -1 key = None for pos in range(len(colname)): @@ -1049,6 +1056,7 @@ if converter is None and self.__con._detect_types & PARSE_DECLTYPES: decltype = sqlite.sqlite3_column_decltype(self._statement, i) if decltype is not None: + decltype = decltype.decode('utf-8') decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" if '(' in decltype: decltype = decltype[:decltype.index('(')] @@ -1090,7 +1098,8 @@ param = param.encode("utf-8") rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) is buffer: - rc = sqlite.sqlite3_bind_blob(self._statement, idx, str(param), len(param), SQLITE_TRANSIENT) + param = bytes(param) + rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) else: rc = -1 return rc @@ -1120,7 +1129,7 @@ raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " "only names)." % i) - param_name = param_name[1:] + param_name = param_name.decode('utf-8')[1:] try: param = params[param_name] except KeyError: @@ -1166,14 +1175,14 @@ elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_column_double(self._statement, i) elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_column_blob(self._statement, i) blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - blob = sqlite.sqlite3_column_blob(self._statement, i) val = buffer(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: + text = sqlite.sqlite3_column_text(self._statement, i) text_len = sqlite.sqlite3_column_bytes(self._statement, i) - text = sqlite.sqlite3_column_text(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) else: @@ -1182,7 +1191,7 @@ val = None else: blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = string_at(blob, blob_len) + val = bytes(string_at(blob, blob_len)) val = converter(val) row.append(val) @@ -1196,7 +1205,8 @@ return None desc = [] for i in xrange(sqlite.sqlite3_column_count(self._statement)): - name = sqlite.sqlite3_column_name(self._statement, i).split("[")[0].strip() + name = sqlite.sqlite3_column_name(self._statement, i) + name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc @@ -1289,15 +1299,14 @@ elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_value_blob(params[i]) blob_len = sqlite.sqlite3_value_bytes(params[i]) - blob = sqlite.sqlite3_value_blob(params[i]) val = buffer(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: val = sqlite.sqlite3_value_text(params[i]) - # XXX changed from con.text_factory - val = unicode(val, 'utf-8') + val = val.decode('utf-8') else: raise NotImplementedError _params.append(val) @@ -1310,7 +1319,6 @@ elif isinstance(val, (bool, int, long)): sqlite.sqlite3_result_int64(con, int(val)) elif isinstance(val, str): - # XXX ignoring unicode issue sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) elif isinstance(val, unicode): val = val.encode('utf-8') @@ -1318,7 +1326,7 @@ elif isinstance(val, float): sqlite.sqlite3_result_double(con, val) elif isinstance(val, buffer): - sqlite.sqlite3_result_blob(con, str(val), len(val), SQLITE_TRANSIENT) + sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) else: raise NotImplementedError @@ -1328,7 +1336,7 @@ try: val = real_cb(*params) except Exception: - msg = "user-defined function raised exception" + msg = b"user-defined function raised exception" sqlite.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) From noreply at buildbot.pypy.org Thu Mar 7 09:35:30 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 09:35:30 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130307083530.499691C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62161:254c727895bb Date: 2013-03-07 03:22 -0500 http://bitbucket.org/pypy/pypy/changeset/254c727895bb/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -29,6 +29,7 @@ from collections import OrderedDict from functools import wraps import datetime +import string import sys import weakref from threading import _get_ident as _thread_get_ident @@ -226,7 +227,7 @@ sqlite.sqlite3_total_changes.argtypes = [c_void_p] sqlite.sqlite3_total_changes.restype = c_int -sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_char_p, c_int, c_void_p] +sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] sqlite.sqlite3_result_blob.restype = None sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64] sqlite.sqlite3_result_int64.restype = None @@ -319,6 +320,7 @@ self.__initialized = True self._db = c_void_p() + database = database.encode('utf-8') if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: @@ -408,8 +410,7 @@ def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self._db) - error_message = sqlite.sqlite3_errmsg(self._db) - error_message = error_message.decode('utf-8') + error_message = sqlite.sqlite3_errmsg(self._db).decode('utf-8') if error_code == SQLITE_OK: raise ValueError("error signalled but got SQLITE_OK") @@ -503,7 +504,7 @@ statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, "COMMIT", -1, + ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, byref(statement), next_char) try: if ret != SQLITE_OK: @@ -533,7 +534,7 @@ statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, "ROLLBACK", -1, + ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, byref(statement), next_char) try: if ret != SQLITE_OK: @@ -564,6 +565,8 @@ function_callback(callback, context, nargs, c_params) c_closure = _FUNC(closure) self.__func_cache[callback] = c_closure, closure + + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, c_closure, @@ -579,7 +582,6 @@ c_step_callback, c_final_callback, _, _ = self.__aggregates[cls] except KeyError: def step_callback(context, argc, c_params): - aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), @@ -589,8 +591,8 @@ try: aggregate = cls() except Exception: - msg = ("user-defined aggregate's '__init__' " - "method raised error") + msg = (b"user-defined aggregate's '__init__' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) @@ -603,12 +605,11 @@ try: aggregate.step(*params) except Exception: - msg = ("user-defined aggregate's 'step' " - "method raised error") + msg = (b"user-defined aggregate's 'step' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) def final_callback(context): - aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), @@ -619,8 +620,8 @@ try: val = aggregate.finalize() except Exception: - msg = ("user-defined aggregate's 'finalize' " - "method raised error") + msg = (b"user-defined aggregate's 'finalize' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) @@ -633,6 +634,7 @@ self.__aggregates[cls] = (c_step_callback, c_final_callback, step_callback, final_callback) + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, cast(None, _FUNC), @@ -645,7 +647,7 @@ @_check_closed_wrap def create_collation(self, name, callback): name = name.upper() - if not name.replace('_', '').isalnum(): + if not all(c in string.ascii_uppercase + string.digits + '_' for c in name): raise ProgrammingError("invalid character in collation name") if callback is None: @@ -656,14 +658,15 @@ raise TypeError("parameter must be callable") def collation_callback(context, len1, str1, len2, str2): - text1 = string_at(str1, len1) - text2 = string_at(str2, len2) + text1 = string_at(str1, len1).decode('utf-8') + text2 = string_at(str2, len2).decode('utf-8') return callback(text1, text2) c_collation_callback = _COLLATION(collation_callback) self.__collations[name] = c_collation_callback + name = name.encode('utf-8') ret = sqlite.sqlite3_create_collation(self._db, name, SQLITE_UTF8, None, @@ -733,7 +736,7 @@ if val is None: self.commit() else: - self.__begin_statement = 'BEGIN ' + val + self.__begin_statement = b"BEGIN " + val.encode('utf-8') self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) @@ -748,7 +751,6 @@ class Cursor(object): __initialized = False - __connection = None __statement = None def __init__(self, con): @@ -770,11 +772,10 @@ self.__rowcount = -1 def __del__(self): - if self.__connection: - try: - self.__connection._cursors.remove(weakref.ref(self)) - except ValueError: - pass + try: + self.__connection._cursors.remove(weakref.ref(self)) + except (AttributeError, ValueError): + pass if self.__statement: self.__statement._reset() @@ -873,8 +874,8 @@ self.__connection._in_transaction = \ not sqlite.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) + self.__statement._reset() self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) - self.__statement._reset() finally: self.__locked = False @@ -883,10 +884,9 @@ def executescript(self, sql): self.__description = None self._reset = False - if type(sql) is str: - sql = sql.encode("utf-8") self.__check_cursor() statement = c_void_p() + sql = sql.encode('utf-8') c_sql = c_char_p(sql) self.__connection.commit() @@ -1008,11 +1008,12 @@ self._statement = c_void_p() next_char = c_char_p() - sql_char = sql - ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql_char, -1, byref(self._statement), byref(next_char)) + sql = sql.encode('utf-8') + + ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) if ret == SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.__con._db, "select 42", -1, byref(self._statement), byref(next_char)) + ret = sqlite.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) self._kind = Statement._DQL if ret != SQLITE_OK: @@ -1021,22 +1022,23 @@ next_char = next_char.value.decode('utf-8') if _check_remaining_sql(next_char): raise Warning("One and only one statement required: %r" % - (next_char,)) + next_char) def __del__(self): if self._statement: sqlite.sqlite3_finalize(self._statement) def _finalize(self): - sqlite.sqlite3_finalize(self._statement) - self._statement = None + if self._statement: + sqlite.sqlite3_finalize(self._statement) + self._statement = None self._in_use = False def _reset(self): - ret = sqlite.sqlite3_reset(self._statement) - self._in_use = False + if self._in_use and self._statement: + ret = sqlite.sqlite3_reset(self._statement) + self._in_use = False self._exhausted = False - return ret def _build_row_cast_map(self): self.__row_cast_map = [] @@ -1059,8 +1061,8 @@ if converter is None and self.__con._detect_types & PARSE_DECLTYPES: decltype = sqlite.sqlite3_column_decltype(self._statement, i) if decltype is not None: + decltype = decltype.decode('utf-8') decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" - decltype = decltype.decode('utf-8') if '(' in decltype: decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) @@ -1070,37 +1072,36 @@ def __set_param(self, idx, param): cvt = converters.get(type(param)) if cvt is not None: - cvt = param = cvt(param) + param = cvt(param) param = adapt(param) if param is None: - sqlite.sqlite3_bind_null(self._statement, idx) + rc = sqlite.sqlite3_bind_null(self._statement, idx) elif type(param) in (bool, int): if -2147483648 <= param <= 2147483647: - sqlite.sqlite3_bind_int(self._statement, idx, param) + rc = sqlite.sqlite3_bind_int(self._statement, idx, param) else: - sqlite.sqlite3_bind_int64(self._statement, idx, param) + rc = sqlite.sqlite3_bind_int64(self._statement, idx, param) elif type(param) is float: - sqlite.sqlite3_bind_double(self._statement, idx, param) + rc = sqlite.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, str): - param = param.encode('utf-8') - sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + param = param.encode("utf-8") + rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) in (bytes, memoryview): param = bytes(param) - sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) else: - raise InterfaceError("parameter type %s is not supported" % - type(param)) + rc = -1 + return rc def _set_params(self, params): - ret = sqlite.sqlite3_reset(self._statement) - if ret != SQLITE_OK: - raise self.__con._get_exception(ret) self._in_use = True num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) - if not isinstance(params, dict): + if isinstance(params, (tuple, list)) or \ + not isinstance(params, dict) and \ + hasattr(params, '__len__') and hasattr(params, '__getitem__'): num_params = len(params) if num_params != num_params_needed: raise ProgrammingError("Incorrect number of bindings supplied. " @@ -1108,25 +1109,32 @@ "there are %d supplied." % (num_params_needed, num_params)) for i in range(num_params): - self.__set_param(i + 1, params[i]) - else: + rc = self.__set_param(i + 1, params[i]) + if rc != SQLITE_OK: + raise InterfaceError("Error binding parameter %d - " + "probably unsupported type." % i) + elif isinstance(params, dict): for i in range(1, num_params_needed + 1): param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) if param_name is None: raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " "only names)." % i) - param_name = param_name[1:].decode('utf-8') + param_name = param_name.decode('utf-8')[1:] try: param = params[param_name] except KeyError: raise ProgrammingError("You did not supply a value for " "binding %d." % i) - self.__set_param(i, param) + rc = self.__set_param(i, param) + if rc != SQLITE_OK: + raise InterfaceError("Error binding parameter :%s - " + "probably unsupported type." % + param_name) + else: + raise ValueError("parameters are of unsupported type") def _next(self, cursor): - self.__con._check_closed() - self.__con._check_thread() if self._exhausted: raise StopIteration item = self._item @@ -1158,14 +1166,14 @@ elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_column_double(self._statement, i) elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_column_blob(self._statement, i) blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - blob = sqlite.sqlite3_column_blob(self._statement, i) val = bytes(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: + text = sqlite.sqlite3_column_text(self._statement, i) text_len = sqlite.sqlite3_column_bytes(self._statement, i) - text = sqlite.sqlite3_column_text(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) else: @@ -1174,7 +1182,7 @@ val = None else: blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = string_at(blob, blob_len) + val = bytes(string_at(blob, blob_len)) val = converter(val) row.append(val) @@ -1188,8 +1196,8 @@ return None desc = [] for i in range(sqlite.sqlite3_column_count(self._statement)): - col_name = sqlite.sqlite3_column_name(self._statement, i) - name = col_name.decode('utf-8').split("[")[0].strip() + name = sqlite.sqlite3_column_name(self._statement, i) + name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc @@ -1282,15 +1290,14 @@ elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_value_blob(params[i]) blob_len = sqlite.sqlite3_value_bytes(params[i]) - blob = sqlite.sqlite3_value_blob(params[i]) val = bytes(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: val = sqlite.sqlite3_value_text(params[i]) - # XXX changed from con.text_factory - val = str(val, 'utf-8') + val = val.decode('utf-8') else: raise NotImplementedError _params.append(val) @@ -1303,13 +1310,12 @@ elif isinstance(val, (bool, int)): sqlite.sqlite3_result_int64(con, int(val)) elif isinstance(val, str): - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) - elif isinstance(val, bytes): + val = val.encode('utf-8') sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) elif isinstance(val, float): sqlite.sqlite3_result_double(con, val) - elif isinstance(val, buffer): - sqlite.sqlite3_result_blob(con, str(val), len(val), SQLITE_TRANSIENT) + elif isinstance(val, (bytes, memoryview)): + sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) else: raise NotImplementedError @@ -1319,7 +1325,7 @@ try: val = real_cb(*params) except Exception: - msg = "user-defined function raised exception" + msg = b"user-defined function raised exception" sqlite.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) 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 @@ -126,3 +126,20 @@ con.commit() except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") + +def test_statement_param_checking(): + con = _sqlite3.connect(':memory:') + con.execute('create table foo(x)') + con.execute('insert into foo(x) values (?)', [2]) + con.execute('insert into foo(x) values (?)', (2,)) + class seq(object): + def __len__(self): + return 1 + def __getitem__(self, key): + return 2 + con.execute('insert into foo(x) values (?)', seq()) + with pytest.raises(_sqlite3.ProgrammingError): + con.execute('insert into foo(x) values (?)', {2:2}) + with pytest.raises(ValueError) as e: + con.execute('insert into foo(x) values (?)', 2) + assert str(e.value) == 'parameters are of unsupported type' From noreply at buildbot.pypy.org Thu Mar 7 09:35:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 09:35:31 +0100 (CET) Subject: [pypy-commit] pypy py3k: some fixes for _sqlite3 on py3k Message-ID: <20130307083531.83FA81C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62162:d9ffd98adc48 Date: 2013-03-07 03:25 -0500 http://bitbucket.org/pypy/pypy/changeset/d9ffd98adc48/ Log: some fixes for _sqlite3 on py3k diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -131,13 +131,6 @@ # SQLite C API -class TEXT: - @classmethod - def from_param(cls, value): - if isinstance(value, bytes): - return value - return value.encode('utf-8') - sqlite.sqlite3_value_int.argtypes = [c_void_p] sqlite.sqlite3_value_int.restype = c_int @@ -175,7 +168,7 @@ sqlite.sqlite3_bind_parameter_index.restype = c_int sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] sqlite.sqlite3_bind_parameter_name.restype = c_char_p -sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, TEXT, c_int, c_void_p] +sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p] sqlite.sqlite3_bind_text.restype = c_int sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] sqlite.sqlite3_busy_timeout.restype = c_int @@ -214,11 +207,11 @@ sqlite.sqlite3_last_insert_rowid.restype = c_int64 sqlite.sqlite3_libversion.argtypes = [] sqlite.sqlite3_libversion.restype = c_char_p -sqlite.sqlite3_open.argtypes = [TEXT, c_void_p] +sqlite.sqlite3_open.argtypes = [c_char_p, c_void_p] sqlite.sqlite3_open.restype = c_int sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] sqlite.sqlite3_prepare.restype = c_int -sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, TEXT, c_int, c_void_p, POINTER(c_char_p)] +sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] sqlite.sqlite3_prepare_v2.restype = c_int sqlite.sqlite3_step.argtypes = [c_void_p] sqlite.sqlite3_step.restype = c_int @@ -235,9 +228,9 @@ sqlite.sqlite3_result_null.restype = None sqlite.sqlite3_result_double.argtypes = [c_void_p, c_double] sqlite.sqlite3_result_double.restype = None -sqlite.sqlite3_result_error.argtypes = [c_void_p, TEXT, c_int] +sqlite.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int] sqlite.sqlite3_result_error.restype = None -sqlite.sqlite3_result_text.argtypes = [c_void_p, TEXT, c_int, c_void_p] +sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] sqlite.sqlite3_result_text.restype = None _HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") @@ -1333,14 +1326,14 @@ _FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) _STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) _FINAL = CFUNCTYPE(None, c_void_p) -sqlite.sqlite3_create_function.argtypes = [c_void_p, TEXT, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] +sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] sqlite.sqlite3_create_function.restype = c_int sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] sqlite.sqlite3_aggregate_context.restype = c_void_p _COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -sqlite.sqlite3_create_collation.argtypes = [c_void_p, TEXT, c_int, c_void_p, _COLLATION] +sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, _COLLATION] sqlite.sqlite3_create_collation.restype = c_int _PROGRESS = CFUNCTYPE(c_int, c_void_p) @@ -1426,9 +1419,4 @@ register_adapters_and_converters() -def OptimizedUnicode(s): - try: - val = str(s, "ascii").encode("ascii") - except UnicodeDecodeError: - val = str(s, "utf-8") - return val +OptimizedUnicode = unicode_text_factory From noreply at buildbot.pypy.org Thu Mar 7 09:35:32 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 09:35:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130307083532.D8FE51C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62163:c01b46a3cbfe Date: 2013-03-07 03:34 -0500 http://bitbucket.org/pypy/pypy/changeset/c01b46a3cbfe/ Log: merge heads diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -295,8 +295,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - py3k = True # are we interpreting py3k bytecode? - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -534,7 +534,6 @@ self.setdictscope(w_locals) def POP_EXCEPT(self, oparg, next_instr): - assert self.space.py3k block = self.pop_block() block.cleanup(self) return @@ -1327,14 +1326,12 @@ # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. - if frame.space.py3k: - # this is popped by POP_EXCEPT, which is present only in py3k - w_last_exception = W_OperationError(frame.last_exception) - w_last_exception = frame.space.wrap(w_last_exception) - frame.pushvalue(w_last_exception) - block = ExceptHandlerBlock(self.valuestackdepth, - 0, frame.lastblock) - frame.lastblock = block + # this is popped by POP_EXCEPT, which is present only in py3k + w_last_exception = W_OperationError(frame.last_exception) + w_last_exception = frame.space.wrap(w_last_exception) + frame.pushvalue(w_last_exception) + block = ExceptHandlerBlock(self.valuestackdepth, 0, frame.lastblock) + frame.lastblock = block frame.pushvalue(frame.space.wrap(unroller)) frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) diff --git a/pypy/module/imp/test/support.py b/pypy/module/imp/test/support.py --- a/pypy/module/imp/test/support.py +++ b/pypy/module/imp/test/support.py @@ -10,12 +10,8 @@ if sys.platform == 'nt': testfn_unencodable = testfn + u"-\u5171\u0141\u2661\u0363\uDC80" elif sys.platform != 'darwin': - fsenc = sys.getfilesystemencoding() try: - '\xff'.decode(fsenc) + '\xff'.decode(sys.getfilesystemencoding()) except UnicodeDecodeError: - w_unenc = space.call_method(space.wrapbytes('-\xff'), 'decode', - space.wrap(fsenc), - space.wrap('surrogateescape')) - testfn_unencodable = testfn + space.unicode_w(w_unenc) + testfn_unencodable = testfn + u'-\udcff' cls.w_testfn_unencodable = space.wrap(testfn_unencodable) From noreply at buildbot.pypy.org Thu Mar 7 09:35:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 09:35:34 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130307083534.11FE71C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62164:96d7103e2b00 Date: 2013-03-07 03:35 -0500 http://bitbucket.org/pypy/pypy/changeset/96d7103e2b00/ Log: merge heads diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -29,6 +29,7 @@ from collections import OrderedDict from functools import wraps import datetime +import string import sys import weakref from threading import _get_ident as _thread_get_ident @@ -219,7 +220,7 @@ sqlite.sqlite3_total_changes.argtypes = [c_void_p] sqlite.sqlite3_total_changes.restype = c_int -sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_char_p, c_int, c_void_p] +sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] sqlite.sqlite3_result_blob.restype = None sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64] sqlite.sqlite3_result_int64.restype = None @@ -242,7 +243,7 @@ ########################################## # SQLite version information -sqlite_version = sqlite.sqlite3_libversion() +sqlite_version = sqlite.sqlite3_libversion().decode('utf-8') class Error(StandardError): pass @@ -289,9 +290,6 @@ self.cache = OrderedDict() def get(self, sql, row_factory): - if isinstance(sql, unicode): - sql = sql.encode('utf-8') - try: stat = self.cache[sql] except KeyError: @@ -315,6 +313,8 @@ self.__initialized = True self._db = c_void_p() + if isinstance(database, unicode): + database = database.encode('utf-8') if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: @@ -404,7 +404,7 @@ def _get_exception(self, error_code=None): if error_code is None: error_code = sqlite.sqlite3_errcode(self._db) - error_message = sqlite.sqlite3_errmsg(self._db) + error_message = sqlite.sqlite3_errmsg(self._db).decode('utf-8') if error_code == SQLITE_OK: raise ValueError("error signalled but got SQLITE_OK") @@ -498,7 +498,7 @@ statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, "COMMIT", -1, + ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, byref(statement), next_char) try: if ret != SQLITE_OK: @@ -528,7 +528,7 @@ statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self._db, "ROLLBACK", -1, + ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, byref(statement), next_char) try: if ret != SQLITE_OK: @@ -559,6 +559,9 @@ function_callback(callback, context, nargs, c_params) c_closure = _FUNC(closure) self.__func_cache[callback] = c_closure, closure + + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, c_closure, @@ -574,7 +577,6 @@ c_step_callback, c_final_callback, _, _ = self.__aggregates[cls] except KeyError: def step_callback(context, argc, c_params): - aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), @@ -584,8 +586,8 @@ try: aggregate = cls() except Exception: - msg = ("user-defined aggregate's '__init__' " - "method raised error") + msg = (b"user-defined aggregate's '__init__' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) @@ -598,12 +600,11 @@ try: aggregate.step(*params) except Exception: - msg = ("user-defined aggregate's 'step' " - "method raised error") + msg = (b"user-defined aggregate's 'step' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) def final_callback(context): - aggregate_ptr = cast( sqlite.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), @@ -614,8 +615,8 @@ try: val = aggregate.finalize() except Exception: - msg = ("user-defined aggregate's 'finalize' " - "method raised error") + msg = (b"user-defined aggregate's 'finalize' " + b"method raised error") sqlite.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) @@ -628,6 +629,8 @@ self.__aggregates[cls] = (c_step_callback, c_final_callback, step_callback, final_callback) + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, cast(None, _FUNC), @@ -640,7 +643,7 @@ @_check_closed_wrap def create_collation(self, name, callback): name = name.upper() - if not name.replace('_', '').isalnum(): + if not all(c in string.uppercase + string.digits + '_' for c in name): raise ProgrammingError("invalid character in collation name") if callback is None: @@ -651,14 +654,16 @@ raise TypeError("parameter must be callable") def collation_callback(context, len1, str1, len2, str2): - text1 = string_at(str1, len1) - text2 = string_at(str2, len2) + text1 = string_at(str1, len1).decode('utf-8') + text2 = string_at(str2, len2).decode('utf-8') return callback(text1, text2) c_collation_callback = _COLLATION(collation_callback) self.__collations[name] = c_collation_callback + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_collation(self._db, name, SQLITE_UTF8, None, @@ -724,9 +729,7 @@ if val is None: self.commit() else: - if isinstance(val, unicode): - val = str(val) - self.__begin_statement = 'BEGIN ' + val + self.__begin_statement = b"BEGIN " + val.encode('ascii') self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) @@ -874,10 +877,10 @@ def executescript(self, sql): self.__description = None self._reset = False - if type(sql) is unicode: - sql = sql.encode("utf-8") self.__check_cursor() statement = c_void_p() + if isinstance(sql, unicode): + sql = sql.encode('utf-8') c_sql = c_char_p(sql) self.__connection.commit() @@ -983,7 +986,7 @@ def __init__(self, connection, sql): self.__con = connection - if not isinstance(sql, str): + if not isinstance(sql, (str, unicode)): raise ValueError("sql must be a string") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): @@ -999,19 +1002,22 @@ self._statement = c_void_p() next_char = c_char_p() - sql_char = c_char_p(sql) - ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql_char, -1, byref(self._statement), byref(next_char)) + if isinstance(sql, unicode): + sql = sql.encode('utf-8') + + ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) if ret == SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.__con._db, "select 42", -1, byref(self._statement), byref(next_char)) + ret = sqlite.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) self._kind = Statement._DQL if ret != SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) - if _check_remaining_sql(next_char.value): + next_char = next_char.value.decode('utf-8') + if _check_remaining_sql(next_char): raise Warning("One and only one statement required: %r" % - (next_char.value,)) + next_char) def __del__(self): if self._statement: @@ -1037,6 +1043,7 @@ if self.__con._detect_types & PARSE_COLNAMES: colname = sqlite.sqlite3_column_name(self._statement, i) if colname is not None: + colname = colname.decode('utf-8') type_start = -1 key = None for pos in range(len(colname)): @@ -1049,6 +1056,7 @@ if converter is None and self.__con._detect_types & PARSE_DECLTYPES: decltype = sqlite.sqlite3_column_decltype(self._statement, i) if decltype is not None: + decltype = decltype.decode('utf-8') decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" if '(' in decltype: decltype = decltype[:decltype.index('(')] @@ -1090,7 +1098,8 @@ param = param.encode("utf-8") rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) is buffer: - rc = sqlite.sqlite3_bind_blob(self._statement, idx, str(param), len(param), SQLITE_TRANSIENT) + param = bytes(param) + rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) else: rc = -1 return rc @@ -1120,7 +1129,7 @@ raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " "only names)." % i) - param_name = param_name[1:] + param_name = param_name.decode('utf-8')[1:] try: param = params[param_name] except KeyError: @@ -1166,14 +1175,14 @@ elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_column_double(self._statement, i) elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_column_blob(self._statement, i) blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - blob = sqlite.sqlite3_column_blob(self._statement, i) val = buffer(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: + text = sqlite.sqlite3_column_text(self._statement, i) text_len = sqlite.sqlite3_column_bytes(self._statement, i) - text = sqlite.sqlite3_column_text(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) else: @@ -1182,7 +1191,7 @@ val = None else: blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = string_at(blob, blob_len) + val = bytes(string_at(blob, blob_len)) val = converter(val) row.append(val) @@ -1196,7 +1205,8 @@ return None desc = [] for i in xrange(sqlite.sqlite3_column_count(self._statement)): - name = sqlite.sqlite3_column_name(self._statement, i).split("[")[0].strip() + name = sqlite.sqlite3_column_name(self._statement, i) + name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc @@ -1289,15 +1299,14 @@ elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_value_blob(params[i]) blob_len = sqlite.sqlite3_value_bytes(params[i]) - blob = sqlite.sqlite3_value_blob(params[i]) val = buffer(string_at(blob, blob_len)) elif typ == SQLITE_NULL: val = None elif typ == SQLITE_TEXT: val = sqlite.sqlite3_value_text(params[i]) - # XXX changed from con.text_factory - val = unicode(val, 'utf-8') + val = val.decode('utf-8') else: raise NotImplementedError _params.append(val) @@ -1310,7 +1319,6 @@ elif isinstance(val, (bool, int, long)): sqlite.sqlite3_result_int64(con, int(val)) elif isinstance(val, str): - # XXX ignoring unicode issue sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) elif isinstance(val, unicode): val = val.encode('utf-8') @@ -1318,7 +1326,7 @@ elif isinstance(val, float): sqlite.sqlite3_result_double(con, val) elif isinstance(val, buffer): - sqlite.sqlite3_result_blob(con, str(val), len(val), SQLITE_TRANSIENT) + sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) else: raise NotImplementedError @@ -1328,7 +1336,7 @@ try: val = real_cb(*params) except Exception: - msg = "user-defined function raised exception" + msg = b"user-defined function raised exception" sqlite.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) From noreply at buildbot.pypy.org Thu Mar 7 10:02:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 10:02:24 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for sqlite param container check Message-ID: <20130307090224.9939E1C10F8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62165:5103722a91c0 Date: 2013-03-07 04:00 -0500 http://bitbucket.org/pypy/pypy/changeset/5103722a91c0/ Log: test and fix for sqlite param container check diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1110,8 +1110,11 @@ num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) if isinstance(params, (tuple, list)) or \ not isinstance(params, dict) and \ - hasattr(params, '__len__') and hasattr(params, '__getitem__'): - num_params = len(params) + hasattr(params, '__getitem__'): + try: + num_params = len(params) + except TypeError: + num_params = -1 if num_params != num_params_needed: raise ProgrammingError("Incorrect number of bindings supplied. " "The current statement uses %d, and " 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 @@ -138,6 +138,9 @@ def __getitem__(self, key): return 2 con.execute('insert into foo(x) values (?)', seq()) + del seq.__len__ + with pytest.raises(_sqlite3.ProgrammingError): + con.execute('insert into foo(x) values (?)', seq()) with pytest.raises(_sqlite3.ProgrammingError): con.execute('insert into foo(x) values (?)', {2:2}) with pytest.raises(ValueError) as e: From noreply at buildbot.pypy.org Thu Mar 7 10:07:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:07:00 +0100 (CET) Subject: [pypy-commit] cffi default: Cancel again these changes: we can't pass 0 or None to mean NULL. Just Message-ID: <20130307090700.736BB1C101B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1183:d0f6755466f7 Date: 2013-03-07 10:02 +0100 http://bitbucket.org/cffi/cffi/changeset/d0f6755466f7/ Log: Cancel again these changes: we can't pass 0 or None to mean NULL. Just use NULL explicitly. (After discussion on IRC, notably with Amaury -- thanks) diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1120,11 +1120,6 @@ CTypeDescrObject *ctinit; if (!CData_Check(init)) { - if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) { - /* convert 0 to NULL */ - *(char **)data = NULL; - return 0; - } expected = "cdata pointer"; goto cannot_convert; } @@ -1609,15 +1604,7 @@ char *v_cdata, *w_cdata; assert(CData_Check(v)); - v_cdata = ((CDataObject *)v)->c_data; - if (!CData_Check(w)) { - if (PyIntOrLong_Check(w) && !PyObject_IsTrue(w) && - !(((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY)) { - /* comparing a non-primitive with 0 */ - w_cdata = NULL; - goto compare; - } pyres = Py_NotImplemented; goto done; } @@ -1627,8 +1614,9 @@ (((CDataObject *)w)->c_type->ct_flags & CT_PRIMITIVE_ANY))) goto Error; + v_cdata = ((CDataObject *)v)->c_data; w_cdata = ((CDataObject *)w)->c_data; - compare: + switch (op) { case Py_EQ: res = (v_cdata == w_cdata); break; case Py_NE: res = (v_cdata != w_cdata); break; @@ -2078,16 +2066,7 @@ ctitem = ctptr->ct_itemdescr; /* XXX some code duplication, how to avoid it? */ - if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) { - /* Convert 0 to NULL. Note that passing 0 is not ambigous, - despite the potential confusion: as a 'T*' argument, 0 means - NULL, but as a 'T[]' argument it would mean "array of size 0" - --- except that we specifically refuse to interpret numbers - as the array size when passing arguments. */ - *output_data = NULL; - return 0; - } - else if (PyBytes_Check(init)) { + if (PyBytes_Check(init)) { /* from a string: just returning the string here is fine. We assume that the C code won't modify the 'char *' data. */ if ((ctptr->ct_flags & CT_CAST_ANYTHING) || diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -398,19 +398,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -790,7 +779,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -803,14 +792,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1028,11 +1014,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -645,11 +645,12 @@ ``ffi.new(ctype, [initializer])``: this function builds and returns a new cdata object of the given ``ctype``. The ctype is usually some -constant string describing the C type. It must be a pointer or array -type. If it is a pointer, e.g. ``"int *"`` or ``struct foo *``, then -it allocates the memory for one ``int`` or ``struct foo``. If it is -an array, e.g. ``int[10]``, then it allocates the memory for ten -``int``. In both cases the returned cdata is of type ``ctype``. +constant string describing the C type. It must be a pointer, struct, +union, or array type. If it is a pointer, e.g. ``"int *"`` or ``struct +foo *``, then it allocates the memory for one ``int`` or ``struct foo``. +If it is a struct, union or array, e.g. ``int[10]``, then it allocates +the memory for the struct or array --- in this example, ten ``int``. In +all cases the returned cdata is exactly of type ``ctype``. The memory is initially filled with zeros. An initializer can be given too, as described later. @@ -714,15 +715,16 @@ Any operation that would in C return a pointer or array or struct type gives you a fresh cdata object. Unlike the "original" one, these fresh cdata objects don't have ownership: they are merely references to -existing memory. +existing memory. Only ``ffi.new()`` returns an object owning the +memory. -As an exception to the above rule, dereferencing a pointer that owns a -*struct* or *union* object returns a cdata struct or union object -that "co-owns" the same memory. Thus in this case there are two -objects that can keep the same memory alive. This is done for cases where -you really want to have a struct object but don't have any convenient -place to keep alive the original pointer object (returned by -``ffi.new()``). +.. versionchanged:: 0.6 + The above rule has no more exception: it used to be that + ``ffi.new("struct foo_s *")[0]`` would also keep the memory alive, + but this was removed in version 0.6. Now instead you can pass a + struct or union type directly to ``ffi.new()``, and get a cdata + object of type struct or union that owns the memory, by writing + simply ``ffi.new("struct foo_s")``. Example:: @@ -1184,8 +1186,9 @@ (It would be difficult because only structs and unions are internally stored as an indirect pointer to the data.) If ``field`` is given, returns the address of that field in the structure. The returned -pointer is only valid as long as the original object is. *New in -version 0.4.* +pointer is only valid as long as the original ``cdata`` object is; be +sure to keep it alive if it was obtained directly from ``ffi.new()``. +*New in version 0.4.* .. "versionadded:: 0.4" --- inlined in the previous paragraph @@ -1306,12 +1309,11 @@ | | a compatible type (i.e.| |``+``, ``-``, | | | same type or ``char*`` | |bool() | | | or ``void*``, or as an | | | -| | array instead) `(*)`; | | | -| | or ``0`` `(******)` | | | +| | array instead) `(*)` | | | +---------------+------------------------+ | | | ``void *``, | another with | | | | ``char *`` | any pointer or array | | | -| | type; or ``0`` | | | +| | type | | | +---------------+------------------------+ +----------------+ | pointers to | same as pointers | | ``[]``, ``+``, | | structure or | | | ``-``, bool(), | @@ -1391,11 +1393,6 @@ If you really want to get their value as a string, use ``ffi.string(ffi.cast("the_enum_type", x.field))``. -.. versionadded:: 0.6 - `(******)` ``0`` is interpreted like ``ffi.NULL`` in most places. - It is the way both gcc and MSVC work. (Of course non-null integers - are not transparently interpreted as pointers; only ``0`` is.) - Reference: verifier ------------------- diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1561,7 +1561,7 @@ p = ffi.new("char[]", b'\x10\x20\x30') assert lib.sum3chars(p) == b'\x60' -def test_passing_0_for_NULL(): +def test_passing_string_or_NULL(): ffi = FFI() ffi.cdef("int seeme1(char *); int seeme2(int *);") lib = ffi.verify(""" @@ -1573,12 +1573,12 @@ } """) assert lib.seeme1(b"foo") == 0 - assert lib.seeme1(0) == 1 - assert lib.seeme1(long(0)) == 1 + assert lib.seeme1(ffi.NULL) == 1 assert lib.seeme2([42, 43]) == 0 - assert lib.seeme2(0) == 1 - assert lib.seeme2(long(0)) == 1 + assert lib.seeme2(ffi.NULL) == 1 py.test.raises(TypeError, lib.seeme1, None) py.test.raises(TypeError, lib.seeme2, None) py.test.raises(TypeError, lib.seeme1, 0.0) py.test.raises(TypeError, lib.seeme2, 0.0) + py.test.raises(TypeError, lib.seeme1, 0) + py.test.raises(TypeError, lib.seeme2, 0) From noreply at buildbot.pypy.org Thu Mar 7 10:07:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:07:20 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Lock Message-ID: <20130307090720.7BCFD1C101B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62166:c7a41aeb7bd2 Date: 2013-03-04 17:38 +0100 http://bitbucket.org/pypy/pypy/changeset/c7a41aeb7bd2/ Log: Lock diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -275,6 +275,7 @@ _finalizer_queue = collections.deque() _finalizer_objects = weakref.WeakKeyDictionary() +_finalizer_lock = [None] class _UntranslatedFinalizingObject(object): call_finalizer = None @@ -327,14 +328,23 @@ def progress_through_finalizer_queue(): "NOT_RPYTHON" + try: + _finalizer_lock.pop() + except IndexError: # list is already empty + return while _finalizer_queue: obj, func = _finalizer_queue.popleft() try: func(obj) except FinalizeLater: _finalizer_queue.appendleft((obj, func)) - return False # interrupted - return True # completed + break + except Exception, e: + raise AssertionError("progress_through_finalizer_queue(): " + "%s raised %s: %s" % (func, + e.__class__.__name__, + e)) + _finalizer_lock.append(None) class RegisterFinalizerEntry(ExtRegistryEntry): _about_ = register_finalizer From noreply at buildbot.pypy.org Thu Mar 7 10:07:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:07:21 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: details Message-ID: <20130307090721.E18311C101B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r62167:a73a349ee7ec Date: 2013-03-06 23:46 +0100 http://bitbucket.org/pypy/pypy/changeset/a73a349ee7ec/ Log: details diff --git a/rpython/memory/gc/stmtls.py b/rpython/memory/gc/stmtls.py --- a/rpython/memory/gc/stmtls.py +++ b/rpython/memory/gc/stmtls.py @@ -73,7 +73,7 @@ free_non_gc_object(self) def _alloc_nursery(self, nursery_size): - nursery = llarena.arena_malloc(nursery_size, 1) + nursery = llarena.arena_malloc(nursery_size, 2) debug_print("nursery is at", nursery, "size", nursery_size) if not nursery: raise MemoryError("cannot allocate nursery") @@ -381,8 +381,9 @@ def trace_and_drag_out_of_nursery(self, obj): # This is called to fix the references inside 'obj', to ensure that - # they are global. If necessary, the referenced objects are copied - # out of the nursery first. This is called on the LOCAL copy of + # they are not pointing to the nursery any more. Any non-global, + # not-visited-yet object found is added to 'self.pending'. + # This is called on the LOCAL copy of # the roots, and on the freshly OLD copy of all other reached LOCAL # objects. This only looks inside 'obj': it does not depend on or # touch the flags of 'obj'. From noreply at buildbot.pypy.org Thu Mar 7 10:07:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:07:23 +0100 (CET) Subject: [pypy-commit] pypy default: Update to cffi/d0f6755466f7 Message-ID: <20130307090723.0F7A11C101B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62168:1d661d485129 Date: 2013-03-07 10:07 +0100 http://bitbucket.org/pypy/pypy/changeset/1d661d485129/ Log: Update to cffi/d0f6755466f7 diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -92,20 +92,15 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): - if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a " - "primitive cdata")) cdata2 = other._cdata - elif (misc.is_zero(space, w_other) and - not isinstance(self.ctype, W_CTypePrimitive)): - cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -154,10 +154,6 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - if misc.is_zero(space, w_ob): - NULL = lltype.nullptr(rffi.CCHARP.TO) - rffi.cast(rffi.CCHARPP, cdata)[0] = NULL - return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -261,15 +257,7 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if misc.is_zero(space, w_init): - # Convert 0 to NULL. Note that passing 0 is not ambigous, - # despite the potential confusion: as a 'T*' argument, 0 means - # NULL, but as a 'T[]' argument it would mean "array of size 0" - # --- except that we specifically refuse to interpret numbers - # as the array size when passing arguments. - rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) - return 3 - elif (space.isinstance_w(w_init, space.w_list) or + if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -203,11 +203,6 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" -def is_zero(space, w_ob): - return ((space.isinstance_w(w_ob, space.w_int) or - space.isinstance_w(w_ob, space.w_long)) - and not space.is_true(w_ob)) - # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,19 +387,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -779,7 +768,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -792,14 +781,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1017,11 +1003,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): From noreply at buildbot.pypy.org Thu Mar 7 10:18:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 10:18:22 +0100 (CET) Subject: [pypy-commit] pypy default: don't need next_char here Message-ID: <20130307091822.035DA1C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62169:984ec8c1fb81 Date: 2013-03-07 04:14 -0500 http://bitbucket.org/pypy/pypy/changeset/984ec8c1fb81/ Log: don't need next_char here diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -472,9 +472,8 @@ def _begin(self): statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -497,9 +496,8 @@ obj._reset() statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -527,9 +525,8 @@ cursor._reset = True statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) From noreply at buildbot.pypy.org Thu Mar 7 10:18:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 10:18:23 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130307091823.3FAB21C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62170:75a2ee7a0a13 Date: 2013-03-07 04:18 -0500 http://bitbucket.org/pypy/pypy/changeset/75a2ee7a0a13/ Log: merge heads diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -92,20 +92,15 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): - if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a " - "primitive cdata")) cdata2 = other._cdata - elif (misc.is_zero(space, w_other) and - not isinstance(self.ctype, W_CTypePrimitive)): - cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -154,10 +154,6 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - if misc.is_zero(space, w_ob): - NULL = lltype.nullptr(rffi.CCHARP.TO) - rffi.cast(rffi.CCHARPP, cdata)[0] = NULL - return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -261,15 +257,7 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if misc.is_zero(space, w_init): - # Convert 0 to NULL. Note that passing 0 is not ambigous, - # despite the potential confusion: as a 'T*' argument, 0 means - # NULL, but as a 'T[]' argument it would mean "array of size 0" - # --- except that we specifically refuse to interpret numbers - # as the array size when passing arguments. - rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) - return 3 - elif (space.isinstance_w(w_init, space.w_list) or + if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -203,11 +203,6 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" -def is_zero(space, w_ob): - return ((space.isinstance_w(w_ob, space.w_int) or - space.isinstance_w(w_ob, space.w_long)) - and not space.is_true(w_ob)) - # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,19 +387,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -779,7 +768,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -792,14 +781,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1017,11 +1003,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): From noreply at buildbot.pypy.org Thu Mar 7 10:38:04 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:38:04 +0100 (CET) Subject: [pypy-commit] cffi default: Document the removal of FILE, add demos. Message-ID: <20130307093804.EECDD1C12F3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1185:456ad2f4381b Date: 2013-03-07 10:37 +0100 http://bitbucket.org/cffi/cffi/changeset/456ad2f4381b/ Log: Document the removal of FILE, add demos. diff --git a/demo/file1.py b/demo/file1.py --- a/demo/file1.py +++ b/demo/file1.py @@ -1,10 +1,15 @@ import cffi import os +# +# To access FILE objects in C that correspond directly to file descriptors +# at the Python level, just define and use fdopen() and fclose(). +# ffi = cffi.FFI() ffi.cdef(""" +typedef ... FILE; // this line is optional: FILE is predefined if missing FILE *fdopen(int, const char *); int fclose(FILE *); void dumpme(FILE *); @@ -17,6 +22,7 @@ } """) +# ____________________________________________________________ pipe_in, pipe_out = os.pipe() diff --git a/demo/file2.py b/demo/file2.py new file mode 100644 --- /dev/null +++ b/demo/file2.py @@ -0,0 +1,35 @@ +import cffi +import sys, os + +# +# To exchange Python-file objects and C-level FILE objects, +# you need to go via file descriptors and be careful about flushing. +# + +ffi = cffi.FFI() + +ffi.cdef(""" +FILE *fdopen(int, const char *); +int fclose(FILE *); + +int fprintf(FILE *, const char *, ...); +""") + +lib = ffi.verify("") + + +def make_FILE(file_like_object): + fd = file_like_object.fileno() + fd = os.dup(fd) + f = lib.fdopen(fd, file_like_object.mode) + if not f: + os.close(fd) + raise ValueError("fdopen() failed") + return f + +# ____________________________________________________________ + + +F = make_FILE(sys.stdout) +lib.fprintf(F, "Hello, %s!\n", ffi.new("char[]", "world")) +lib.fclose(F) diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -395,11 +395,6 @@ * *New in version 0.6:* bool. In CFFI 0.4 or 0.5, you had to manually say ``typedef _Bool bool;``. Now such a line is optional. -* *New in version 0.4:* FILE. You can declare C functions taking a - ``FILE *`` argument and call them with a Python file object. If needed, - you can also do ``c_f = ffi.cast("FILE *", fileobj)`` and then pass around - ``c_f``. - * *New in version 0.6:* all `common Windows types`_ are defined if you run on Windows (``DWORD``, ``LPARAM``, etc.). @@ -407,7 +402,6 @@ .. "versionadded:: 0.4": _Bool .. "versionadded:: 0.6": bool -.. "versionadded:: 0.4": FILE .. "versionadded:: 0.6": Wintypes As we will see on `the verification step`_ below, the declarations can @@ -423,6 +417,13 @@ fail, notably with the error ``Multiple type specifiers with a type tag``. Please report it as a bug if it does.) +.. versionchanged:: 0.6 + Special FILE support was removed. See `demo/file1.py`_ and + `demo/file2.py`_. + +.. _`demo/file1.py`: https://bitbucket.org/cffi/cffi/src/default/demo/file1.py +.. _`demo/file2.py`: https://bitbucket.org/cffi/cffi/src/default/demo/file2.py + Loading libraries ----------------- From noreply at buildbot.pypy.org Thu Mar 7 10:38:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:38:03 +0100 (CET) Subject: [pypy-commit] cffi default: Kill the logic to support FILE. Found out that it seems reasonable Message-ID: <20130307093803.B2C031C0925@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1184:d23457c0c5d3 Date: 2013-03-07 10:25 +0100 http://bitbucket.org/cffi/cffi/changeset/d23457c0c5d3/ Log: Kill the logic to support FILE. Found out that it seems reasonable enough to use the standard cffi way. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -90,7 +90,6 @@ #define CT_CUSTOM_FIELD_POS 32768 #define CT_IS_LONGDOUBLE 65536 #define CT_IS_BOOL 131072 -#define CT_IS_FILE 262144 #define CT_PRIMITIVE_ANY (CT_PRIMITIVE_SIGNED | \ CT_PRIMITIVE_UNSIGNED | \ CT_PRIMITIVE_CHAR | \ @@ -211,10 +210,6 @@ #include "minibuffer.h" -#if PY_MAJOR_VERSION >= 3 -# include "file_emulator.h" -#endif - #ifdef HAVE_WCHAR_H # include "wchar_helper.h" #endif @@ -2085,12 +2080,6 @@ /* from a unicode, we add the null terminator */ length = _my_PyUnicode_SizeAsWideChar(init) + 1; } - else if ((ctitem->ct_flags & CT_IS_FILE) && PyFile_Check(init)) { - *output_data = (char *)PyFile_AsFile(init); - if (*output_data == NULL && PyErr_Occurred()) - return -1; - return 0; - } else { /* refuse to receive just an integer (and interpret it as the array size) */ @@ -2785,14 +2774,6 @@ return new_simple_cdata(cdsrc->c_data, ct); } } - if ((ct->ct_flags & CT_POINTER) && - (ct->ct_itemdescr->ct_flags & CT_IS_FILE) && - PyFile_Check(ob)) { - FILE *f = PyFile_AsFile(ob); - if (f == NULL && PyErr_Occurred()) - return NULL; - return new_simple_cdata((char *)f, ct); - } value = _my_PyLong_AsUnsignedLongLong(ob, 0); if (value == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) return NULL; @@ -3337,14 +3318,9 @@ static PyObject *b_new_struct_type(PyObject *self, PyObject *args) { char *name; - int flag; if (!PyArg_ParseTuple(args, "s:new_struct_type", &name)) return NULL; - - flag = CT_STRUCT; - if (strcmp(name, "_IO_FILE") == 0 || strcmp(name, "$FILE") == 0) - flag |= CT_IS_FILE; - return _b_struct_or_union_type("struct", name, flag); + return _b_struct_or_union_type("struct", name, CT_STRUCT); } static PyObject *b_new_union_type(PyObject *self, PyObject *args) @@ -4923,15 +4899,8 @@ static char *_cffi_to_c_pointer(PyObject *obj, CTypeDescrObject *ct) { char *result; - if (convert_from_object((char *)&result, ct, obj) < 0) { - if ((ct->ct_flags & CT_POINTER) && - (ct->ct_itemdescr->ct_flags & CT_IS_FILE) && - PyFile_Check(obj)) { - PyErr_Clear(); - return (char *)PyFile_AsFile(obj); - } + if (convert_from_object((char *)&result, ct, obj) < 0) return NULL; - } return result; } @@ -5130,8 +5099,6 @@ init_errno(); #if PY_MAJOR_VERSION >= 3 - if (init_file_emulator() < 0) - INITERROR; return m; #endif } diff --git a/c/file_emulator.h b/c/file_emulator.h deleted file mode 100644 --- a/c/file_emulator.h +++ /dev/null @@ -1,87 +0,0 @@ - -/* Emulation of PyFile_Check() and PyFile_AsFile() for Python 3. */ - -static PyObject *PyIOBase_TypeObj; - -static int init_file_emulator(void) -{ - PyObject *io = PyImport_ImportModule("_io"); - if (io == NULL) - return -1; - PyIOBase_TypeObj = PyObject_GetAttrString(io, "_IOBase"); - if (PyIOBase_TypeObj == NULL) - return -1; - return 0; -} - - -#define PyFile_Check(p) PyObject_IsInstance(p, PyIOBase_TypeObj) - - -static void _close_file_capsule(PyObject *ob_capsule) -{ - FILE *f = (FILE *)PyCapsule_GetPointer(ob_capsule, "FILE"); - if (f != NULL) - fclose(f); -} - - -static FILE *PyFile_AsFile(PyObject *ob_file) -{ - PyObject *ob, *ob_capsule = NULL, *ob_mode = NULL; - FILE *f = NULL; - int fd; - char *mode; - - ob = PyObject_CallMethod(ob_file, "flush", NULL); - if (ob == NULL) - goto fail; - Py_DECREF(ob); - - ob_capsule = PyObject_GetAttrString(ob_file, "__cffi_FILE"); - if (ob_capsule == NULL) { - PyErr_Clear(); - - fd = PyObject_AsFileDescriptor(ob_file); - if (fd < 0) - goto fail; - - ob_mode = PyObject_GetAttrString(ob_file, "mode"); - if (ob_mode == NULL) - goto fail; - mode = PyText_AsUTF8(ob_mode); - if (mode == NULL) - goto fail; - - fd = dup(fd); - if (fd < 0) { - PyErr_SetFromErrno(PyExc_OSError); - goto fail; - } - - f = fdopen(fd, mode); - if (f == NULL) { - close(fd); - PyErr_SetFromErrno(PyExc_OSError); - goto fail; - } - setbuf(f, NULL); /* non-buffered */ - Py_DECREF(ob_mode); - ob_mode = NULL; - - ob_capsule = PyCapsule_New(f, "FILE", _close_file_capsule); - if (ob_capsule == NULL) { - fclose(f); - goto fail; - } - - if (PyObject_SetAttrString(ob_file, "__cffi_FILE", ob_capsule) < 0) - goto fail; - } - return PyCapsule_GetPointer(ob_capsule, "FILE"); - - fail: - Py_XDECREF(ob_mode); - Py_XDECREF(ob_capsule); - return NULL; -} diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2508,6 +2508,7 @@ pass # win32 def test_FILE(): + """FILE is not supported natively any more.""" if sys.platform == "win32": py.test.skip("testing FILE not implemented") # @@ -2517,83 +2518,17 @@ BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") - fscanf = ll.load_function(BFunc2, "fscanf") # import posix fdr, fdw = posix.pipe() fr1 = posix.fdopen(fdr, 'rb', 256) fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1.write(b"X") - res = fputs(b"hello world\n", fw1) - assert res >= 0 - fw1.flush() # should not be needed - # - p = newp(new_array_type(BCharP, 100), None) - res = fscanf(fr1, b"%s\n", p) - assert res == 1 - assert string(p) == b"Xhello" + py.test.raises(TypeError, fputs, b"hello world\n", fw1) fr1.close() fw1.close() -def test_FILE_only_for_FILE_arg(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - B_NOT_FILE = new_struct_type("NOT_FILE") - B_NOT_FILEP = new_pointer_type(B_NOT_FILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') - # - e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value).startswith( - "initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not ") - -def test_FILE_object(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - BFILE = new_struct_type("$FILE") - BFILEP = new_pointer_type(BFILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP,), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - fileno = ll.load_function(BFunc2, "fileno") - # - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1p = cast(BFILEP, fw1) - fw1.write(b"X") - fw1.flush() - res = fputs(b"hello\n", fw1p) - assert res >= 0 - res = fileno(fw1p) - assert (res == fdw) == (sys.version_info < (3,)) - fw1.close() - # - data = posix.read(fdr, 256) - assert data == b"Xhello\n" - posix.close(fdr) - def test_GetLastError(): if sys.platform != "win32": py.test.skip("GetLastError(): only for Windows") diff --git a/cffi/commontypes.py b/cffi/commontypes.py --- a/cffi/commontypes.py +++ b/cffi/commontypes.py @@ -3,7 +3,7 @@ COMMON_TYPES = { - 'FILE': model.unknown_type('FILE', '_IO_FILE'), + 'FILE': model.unknown_type('FILE'), 'bool': '_Bool', } diff --git a/demo/file1.py b/demo/file1.py new file mode 100644 --- /dev/null +++ b/demo/file1.py @@ -0,0 +1,29 @@ +import cffi +import os + + +ffi = cffi.FFI() + +ffi.cdef(""" +FILE *fdopen(int, const char *); +int fclose(FILE *); +void dumpme(FILE *); +""") + +lib = ffi.verify(""" +void dumpme(FILE *f) { + char c = 'X'; + fwrite(&c, 1, 1, f); +} +""") + + + +pipe_in, pipe_out = os.pipe() + +file_out = lib.fdopen(pipe_out, "w") +lib.dumpme(file_out) +lib.fclose(file_out) + +x = os.read(pipe_in, 10) +assert x == 'X' diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -316,20 +316,3 @@ m = ffi.dlopen("m") x = m.sin(1.23) assert x == math.sin(1.23) - - def test_fputs_custom_FILE(self): - if self.Backend is CTypesBackend: - py.test.skip("FILE not supported with the ctypes backend") - filename = str(udir.join('fputs_custom_FILE')) - ffi = FFI(backend=self.Backend()) - ffi.cdef("int fputs(const char *, FILE *);") - C = ffi.dlopen(None) - with open(filename, 'wb') as f: - f.write(b'[') - C.fputs(b"hello from custom file", f) - f.write(b'][') - C.fputs(b"some more output", f) - f.write(b']') - with open(filename, 'rb') as f: - res = f.read() - assert res == b'[hello from custom file][some more output]' diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1339,7 +1339,14 @@ if sys.platform == 'win32': py.test.skip("MSVC: cannot assign to stdout") ffi = FFI() - ffi.cdef("int printf(const char *, ...); FILE *setstdout(FILE *);") + ffi.cdef(""" + FILE *fdopen(int, const char *); + int fclose(FILE *); + size_t fwrite(const void *ptr, size_t size, size_t nmemb, + FILE *stream); + int printf(const char *, ...); + FILE *setstdout(FILE *); + """) lib = ffi.verify(""" #include FILE *setstdout(FILE *f) { @@ -1350,13 +1357,13 @@ """) import os fdr, fdw = os.pipe() - fw1 = os.fdopen(fdw, 'wb', 256) + fw1 = lib.fdopen(fdw, 'wb') old_stdout = lib.setstdout(fw1) try: # - fw1.write(b"X") + lib.fwrite(b"X", 1, 1, fw1) r = lib.printf(b"hello, %d!\n", ffi.cast("int", 42)) - fw1.close() + lib.fclose(fw1) assert r == len("hello, 42!\n") # finally: @@ -1364,35 +1371,7 @@ # result = os.read(fdr, 256) os.close(fdr) - # the 'X' might remain in the user-level buffer of 'fw1' and - # end up showing up after the 'hello, 42!\n' - assert result == b"Xhello, 42!\n" or result == b"hello, 42!\nX" - -def test_FILE_stored_explicitly(): - ffi = FFI() - ffi.cdef("int myprintf(const char *, int); FILE *myfile;") - lib = ffi.verify(""" - #include - FILE *myfile; - int myprintf(const char *out, int value) { - return fprintf(myfile, out, value); - } - """) - import os - fdr, fdw = os.pipe() - fw1 = os.fdopen(fdw, 'wb', 256) - lib.myfile = ffi.cast("FILE *", fw1) - # - fw1.write(b"X") - r = lib.myprintf(b"hello, %d!\n", ffi.cast("int", 42)) - fw1.close() - assert r == len("hello, 42!\n") - # - result = os.read(fdr, 256) - os.close(fdr) - # the 'X' might remain in the user-level buffer of 'fw1' and - # end up showing up after the 'hello, 42!\n' - assert result == b"Xhello, 42!\n" or result == b"hello, 42!\nX" + assert result == b"Xhello, 42!\n" def test_global_array_with_missing_length(): ffi = FFI() From noreply at buildbot.pypy.org Thu Mar 7 10:43:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:43:56 +0100 (CET) Subject: [pypy-commit] pypy default: Update to cffi/d23457c0c5d3. Message-ID: <20130307094356.0B28B1C0925@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62171:87cc13e1bc5e Date: 2013-03-07 10:42 +0100 http://bitbucket.org/pypy/pypy/changeset/87cc13e1bc5e/ Log: Update to cffi/d23457c0c5d3. diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,8 +174,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file', 'cache_array_type'] - _immutable_fields_ = ['is_file', 'cache_array_type?'] + _attrs_ = ['cache_array_type'] + _immutable_fields_ = ['cache_array_type?'] kind = "pointer" cache_array_type = None @@ -186,8 +186,6 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE" or - ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -239,22 +237,6 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def cast(self, w_ob): - if self.is_file: - value = self.prepare_file(w_ob) - if value: - return cdataobj.W_CData(self.space, value, self) - return W_CTypePtrBase.cast(self, w_ob) - - def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) - else: - return lltype.nullptr(rffi.CCHARP.TO) - def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -263,20 +245,14 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 - elif self.is_file: - result = self.prepare_file(w_init) - if result: - rffi.cast(rffi.CCHARPP, cdata)[0] = result - return 2 - return 0 else: - return 0 + return False itemsize = self.ctitem.size if itemsize <= 0: if isinstance(self.ctitem, ctypevoid.W_CTypeVoid): itemsize = 1 else: - return 0 + return False try: datasize = ovfcheck(length * itemsize) except OverflowError: @@ -290,7 +266,7 @@ lltype.free(result, flavor='raw') raise rffi.cast(rffi.CCHARPP, cdata)[0] = result - return 1 + return True def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag @@ -298,7 +274,7 @@ ob = space.interpclass_w(w_ob) result = (not isinstance(ob, cdataobj.W_CData) and self._prepare_pointer_call_argument(w_ob, cdata)) - if result == 0: + if not result: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) return result @@ -328,36 +304,3 @@ if attrchar == 'i': # item return self.space.wrap(self.ctitem) return W_CTypePtrBase._fget(self, attrchar) - -# ____________________________________________________________ - - -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -class CffiFileObj(object): - _immutable_ = True - - def __init__(self, fd, mode): - self.llf = rffi_fdopen(fd, mode) - if not self.llf: - raise OSError(rposix.get_errno(), "fdopen failed") - rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) - - def close(self): - rffi_fclose(self.llf) - - -def prepare_file_argument(space, fileobj): - fileobj.direct_flush() - if fileobj.cffi_fileobj is None: - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) - except OSError, e: - raise wrap_oserror(space, e) - return fileobj.cffi_fileobj.llf 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 @@ -2497,6 +2497,7 @@ pass # win32 def test_FILE(): + """FILE is not supported natively any more.""" if sys.platform == "win32": py.test.skip("testing FILE not implemented") # @@ -2506,83 +2507,17 @@ BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") - fscanf = ll.load_function(BFunc2, "fscanf") # import posix fdr, fdw = posix.pipe() fr1 = posix.fdopen(fdr, 'rb', 256) fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1.write(b"X") - res = fputs(b"hello world\n", fw1) - assert res >= 0 - fw1.flush() # should not be needed - # - p = newp(new_array_type(BCharP, 100), None) - res = fscanf(fr1, b"%s\n", p) - assert res == 1 - assert string(p) == b"Xhello" + py.test.raises(TypeError, fputs, b"hello world\n", fw1) fr1.close() fw1.close() -def test_FILE_only_for_FILE_arg(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - B_NOT_FILE = new_struct_type("NOT_FILE") - B_NOT_FILEP = new_pointer_type(B_NOT_FILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') - # - e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value).startswith( - "initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not ") - -def test_FILE_object(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - BFILE = new_struct_type("$FILE") - BFILEP = new_pointer_type(BFILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP,), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - fileno = ll.load_function(BFunc2, "fileno") - # - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1p = cast(BFILEP, fw1) - fw1.write(b"X") - fw1.flush() - res = fputs(b"hello\n", fw1p) - assert res >= 0 - res = fileno(fw1p) - assert (res == fdw) == (sys.version_info < (3,)) - fw1.close() - # - data = posix.read(fdr, 256) - assert data == b"Xhello\n" - posix.close(fdr) - def test_GetLastError(): if sys.platform != "win32": py.test.skip("GetLastError(): only for Windows") diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,21 +1,8 @@ from pypy.objspace.fake.checkmodule import checkmodule -from pypy.module._cffi_backend import ctypeptr -from rpython.rtyper.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - # prepare_file_argument() is not working without translating the _file - # module too - def dummy_prepare_file_argument(space, fileobj): - return lltype.nullptr(rffi.CCHARP.TO) - old = ctypeptr.prepare_file_argument - try: - ctypeptr.prepare_file_argument = dummy_prepare_file_argument - # - checkmodule('_cffi_backend') - # - finally: - ctypeptr.prepare_file_argument = old + checkmodule('_cffi_backend') diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,7 +32,6 @@ encoding = None errors = None fd = -1 - cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -149,14 +148,8 @@ del openstreams[stream] except KeyError: pass - # close the stream. If cffi_fileobj is None, we close the - # underlying fileno too. Otherwise, we leave that to - # cffi_fileobj.close(). - cffifo = self.cffi_fileobj - self.cffi_fileobj = None - stream.close1(cffifo is None) - if cffifo is not None: - cffifo.close() + # close the stream. + stream.close1(True) def direct_fileno(self): self.getstream() # check if the file is still open From noreply at buildbot.pypy.org Thu Mar 7 10:43:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 10:43:57 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130307094357.44D5C1C0925@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62172:b0543cd42158 Date: 2013-03-07 10:43 +0100 http://bitbucket.org/pypy/pypy/changeset/b0543cd42158/ Log: merge heads diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -472,9 +472,8 @@ def _begin(self): statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -497,9 +496,8 @@ obj._reset() statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -527,9 +525,8 @@ cursor._reset = True statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) From noreply at buildbot.pypy.org Thu Mar 7 11:51:41 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 7 Mar 2013 11:51:41 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, lwassermann) compare to None with is Message-ID: <20130307105141.E52DA1C06F2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r129:4a288f53c7fc Date: 2013-03-07 11:01 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4a288f53c7fc/ Log: (tfel, lwassermann) compare to None with is diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -124,7 +124,7 @@ except Return, nlr: s_new_frame = nlr.s_target_context nlr.s_target_context.push(nlr.value) - if s_new_frame == None: + if s_new_frame is None: # which means that we tried to call a primitive method return s_frame.pop() else: diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -44,11 +44,17 @@ class Stream(object): """ Simple input stream """ - def __init__(self, inputfile): - try: - self.data = inputfile.read() - finally: - inputfile.close() + def __init__(self, inputfile=None, data=None): + if inputfile is None and data is None: + raise RuntimeError("need to supply either inputfile or data") + + if inputfile: + try: + self.data = inputfile.read() + finally: + inputfile.close() + else: + self.data = data self.reset() def peek(self): @@ -360,7 +366,7 @@ def find_asSymbol(self, space, reader): w_dnu = self.special(constants.SO_DOES_NOT_UNDERSTAND) - assert w_dnu.as_string() == "doesNotUnderstand:" + # assert w_dnu.as_string() == "doesNotUnderstand:" w_Symbol = w_dnu.getclass(space) w_obj = None # bit annoying that we have to hunt through the image :-( From noreply at buildbot.pypy.org Thu Mar 7 11:51:43 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 7 Mar 2013 11:51:43 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, lwassermann) reintroduce the assertion Message-ID: <20130307105143.03DF01C06F2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r130:8e362f43daa6 Date: 2013-03-07 11:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8e362f43daa6/ Log: (tfel, lwassermann) reintroduce the assertion diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -366,7 +366,8 @@ def find_asSymbol(self, space, reader): w_dnu = self.special(constants.SO_DOES_NOT_UNDERSTAND) - # assert w_dnu.as_string() == "doesNotUnderstand:" + assert isinstance(w_dnu, model.W_BytesObject) + assert w_dnu.as_string() == "doesNotUnderstand:" w_Symbol = w_dnu.getclass(space) w_obj = None # bit annoying that we have to hunt through the image :-( From noreply at buildbot.pypy.org Thu Mar 7 11:51:44 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 7 Mar 2013 11:51:44 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, cfbolz) Hack: Fix translation error by preventing specialization of c_loop based on the fact that ContextPartShadow is access directly Message-ID: <20130307105144.309161C06F2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r131:9ab4a274460b Date: 2013-03-07 11:50 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/9ab4a274460b/ Log: (tfel, cfbolz) Hack: Fix translation error by preventing specialization of c_loop based on the fact that ContextPartShadow is access directly diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -605,6 +605,7 @@ contextsize = w_home.as_methodcontext_get_shadow(space).myblocksize() w_result = model.W_PointersObject(space.w_BlockContext, contextsize) s_result = BlockContextShadow(space, w_result) + s_result_non_fresh = s_result # XXX: find a better solution to translation err s_result = jit.hint(s_result, access_directly=True, fresh_virtualizable=True) w_result.store_shadow(s_result) s_result.store_expected_argument_count(argcnt) @@ -612,7 +613,7 @@ s_result.store_w_home(w_home) s_result.store_pc(initialip) s_result.init_stack_and_temps() - return s_result + return s_result_non_fresh def fetch(self, n0): if n0 == constants.BLKCTX_HOME_INDEX: @@ -710,6 +711,7 @@ s_new_context = MethodContextShadow(space, None) s_new_context._w_self_size = size + s_new_context_non_fresh = s_new_context # XXX: find a better solution to translation err s_new_context = jit.hint(s_new_context, access_directly=True, fresh_virtualizable=True) if closure is not None: @@ -728,7 +730,7 @@ if closure is not None: for i0 in range(closure.size()): s_new_context.settemp(i0+argc, closure.at0(i0)) - return s_new_context + return s_new_context_non_fresh def fetch(self, n0): if n0 == constants.MTHDCTX_METHOD: From noreply at buildbot.pypy.org Thu Mar 7 11:59:46 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 11:59:46 +0100 (CET) Subject: [pypy-commit] pypy default: small tweaks Message-ID: <20130307105946.EBF331C06F2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62173:38ea2aa0bcfc Date: 2013-03-07 05:50 -0500 http://bitbucket.org/pypy/pypy/changeset/38ea2aa0bcfc/ Log: small tweaks diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -243,7 +243,7 @@ ########################################## # SQLite version information -sqlite_version = sqlite.sqlite3_libversion().decode('utf-8') +sqlite_version = sqlite.sqlite3_libversion() class Error(StandardError): pass @@ -1206,7 +1206,8 @@ desc = [] for i in xrange(sqlite.sqlite3_column_count(self._statement)): name = sqlite.sqlite3_column_name(self._statement, i) - name = name.decode('utf-8').split("[")[0].strip() + if name is not None: + name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc From noreply at buildbot.pypy.org Thu Mar 7 11:59:48 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 11:59:48 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130307105948.367001C06F2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62174:812c43918111 Date: 2013-03-07 05:59 -0500 http://bitbucket.org/pypy/pypy/changeset/812c43918111/ Log: merge heads diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,8 +174,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file', 'cache_array_type'] - _immutable_fields_ = ['is_file', 'cache_array_type?'] + _attrs_ = ['cache_array_type'] + _immutable_fields_ = ['cache_array_type?'] kind = "pointer" cache_array_type = None @@ -186,8 +186,6 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE" or - ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -239,22 +237,6 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def cast(self, w_ob): - if self.is_file: - value = self.prepare_file(w_ob) - if value: - return cdataobj.W_CData(self.space, value, self) - return W_CTypePtrBase.cast(self, w_ob) - - def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) - else: - return lltype.nullptr(rffi.CCHARP.TO) - def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -263,20 +245,14 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 - elif self.is_file: - result = self.prepare_file(w_init) - if result: - rffi.cast(rffi.CCHARPP, cdata)[0] = result - return 2 - return 0 else: - return 0 + return False itemsize = self.ctitem.size if itemsize <= 0: if isinstance(self.ctitem, ctypevoid.W_CTypeVoid): itemsize = 1 else: - return 0 + return False try: datasize = ovfcheck(length * itemsize) except OverflowError: @@ -290,7 +266,7 @@ lltype.free(result, flavor='raw') raise rffi.cast(rffi.CCHARPP, cdata)[0] = result - return 1 + return True def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag @@ -298,7 +274,7 @@ ob = space.interpclass_w(w_ob) result = (not isinstance(ob, cdataobj.W_CData) and self._prepare_pointer_call_argument(w_ob, cdata)) - if result == 0: + if not result: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) return result @@ -328,36 +304,3 @@ if attrchar == 'i': # item return self.space.wrap(self.ctitem) return W_CTypePtrBase._fget(self, attrchar) - -# ____________________________________________________________ - - -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -class CffiFileObj(object): - _immutable_ = True - - def __init__(self, fd, mode): - self.llf = rffi_fdopen(fd, mode) - if not self.llf: - raise OSError(rposix.get_errno(), "fdopen failed") - rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) - - def close(self): - rffi_fclose(self.llf) - - -def prepare_file_argument(space, fileobj): - fileobj.direct_flush() - if fileobj.cffi_fileobj is None: - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) - except OSError, e: - raise wrap_oserror(space, e) - return fileobj.cffi_fileobj.llf 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 @@ -2497,6 +2497,7 @@ pass # win32 def test_FILE(): + """FILE is not supported natively any more.""" if sys.platform == "win32": py.test.skip("testing FILE not implemented") # @@ -2506,83 +2507,17 @@ BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") - fscanf = ll.load_function(BFunc2, "fscanf") # import posix fdr, fdw = posix.pipe() fr1 = posix.fdopen(fdr, 'rb', 256) fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1.write(b"X") - res = fputs(b"hello world\n", fw1) - assert res >= 0 - fw1.flush() # should not be needed - # - p = newp(new_array_type(BCharP, 100), None) - res = fscanf(fr1, b"%s\n", p) - assert res == 1 - assert string(p) == b"Xhello" + py.test.raises(TypeError, fputs, b"hello world\n", fw1) fr1.close() fw1.close() -def test_FILE_only_for_FILE_arg(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - B_NOT_FILE = new_struct_type("NOT_FILE") - B_NOT_FILEP = new_pointer_type(B_NOT_FILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') - # - e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value).startswith( - "initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not ") - -def test_FILE_object(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - BFILE = new_struct_type("$FILE") - BFILEP = new_pointer_type(BFILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP,), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - fileno = ll.load_function(BFunc2, "fileno") - # - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1p = cast(BFILEP, fw1) - fw1.write(b"X") - fw1.flush() - res = fputs(b"hello\n", fw1p) - assert res >= 0 - res = fileno(fw1p) - assert (res == fdw) == (sys.version_info < (3,)) - fw1.close() - # - data = posix.read(fdr, 256) - assert data == b"Xhello\n" - posix.close(fdr) - def test_GetLastError(): if sys.platform != "win32": py.test.skip("GetLastError(): only for Windows") diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,21 +1,8 @@ from pypy.objspace.fake.checkmodule import checkmodule -from pypy.module._cffi_backend import ctypeptr -from rpython.rtyper.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - # prepare_file_argument() is not working without translating the _file - # module too - def dummy_prepare_file_argument(space, fileobj): - return lltype.nullptr(rffi.CCHARP.TO) - old = ctypeptr.prepare_file_argument - try: - ctypeptr.prepare_file_argument = dummy_prepare_file_argument - # - checkmodule('_cffi_backend') - # - finally: - ctypeptr.prepare_file_argument = old + checkmodule('_cffi_backend') diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,7 +32,6 @@ encoding = None errors = None fd = -1 - cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -149,14 +148,8 @@ del openstreams[stream] except KeyError: pass - # close the stream. If cffi_fileobj is None, we close the - # underlying fileno too. Otherwise, we leave that to - # cffi_fileobj.close(). - cffifo = self.cffi_fileobj - self.cffi_fileobj = None - stream.close1(cffifo is None) - if cffifo is not None: - cffifo.close() + # close the stream. + stream.close1(True) def direct_fileno(self): self.getstream() # check if the file is still open From noreply at buildbot.pypy.org Thu Mar 7 12:28:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 12:28:55 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130307112855.3DC1C1C10F8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62175:1d7ef38982ad Date: 2013-03-07 06:28 -0500 http://bitbucket.org/pypy/pypy/changeset/1d7ef38982ad/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -243,7 +243,7 @@ ########################################## # SQLite version information -sqlite_version = sqlite.sqlite3_libversion().decode('utf-8') +sqlite_version = sqlite.sqlite3_libversion().decode('ascii') class Error(Exception): pass @@ -471,9 +471,8 @@ def _begin(self): statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -496,9 +495,8 @@ obj._reset() statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -526,9 +524,8 @@ cursor._reset = True statement = c_void_p() - next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, - byref(statement), next_char) + byref(statement), None) try: if ret != SQLITE_OK: raise self._get_exception(ret) @@ -1094,8 +1091,11 @@ num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) if isinstance(params, (tuple, list)) or \ not isinstance(params, dict) and \ - hasattr(params, '__len__') and hasattr(params, '__getitem__'): - num_params = len(params) + hasattr(params, '__getitem__'): + try: + num_params = len(params) + except TypeError: + num_params = -1 if num_params != num_params_needed: raise ProgrammingError("Incorrect number of bindings supplied. " "The current statement uses %d, and " @@ -1190,7 +1190,8 @@ desc = [] for i in range(sqlite.sqlite3_column_count(self._statement)): name = sqlite.sqlite3_column_name(self._statement, i) - name = name.decode('utf-8').split("[")[0].strip() + if name is not None: + name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -92,20 +92,15 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): - if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a " - "primitive cdata")) cdata2 = other._cdata - elif (misc.is_zero(space, w_other) and - not isinstance(self.ctype, W_CTypePrimitive)): - cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -156,10 +156,6 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - if misc.is_zero(space, w_ob): - NULL = lltype.nullptr(rffi.CCHARP.TO) - rffi.cast(rffi.CCHARPP, cdata)[0] = NULL - return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -180,8 +176,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file', 'cache_array_type'] - _immutable_fields_ = ['is_file', 'cache_array_type?'] + _attrs_ = ['cache_array_type'] + _immutable_fields_ = ['cache_array_type?'] kind = "pointer" cache_array_type = None @@ -192,8 +188,6 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE" or - ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -245,52 +239,23 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def cast(self, w_ob): - if self.is_file: - value = self.prepare_file(w_ob) - if value: - return cdataobj.W_CData(self.space, value, self) - return W_CTypePtrBase.cast(self, w_ob) - - def prepare_file(self, w_ob): - from pypy.module._io.interp_iobase import W_IOBase - ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_IOBase): - return prepare_iofile_argument(self.space, w_ob) - else: - return lltype.nullptr(rffi.CCHARP.TO) - def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if misc.is_zero(space, w_init): - # Convert 0 to NULL. Note that passing 0 is not ambigous, - # despite the potential confusion: as a 'T*' argument, 0 means - # NULL, but as a 'T[]' argument it would mean "array of size 0" - # --- except that we specifically refuse to interpret numbers - # as the array size when passing arguments. - rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) - return 3 - elif (space.isinstance_w(w_init, space.w_list) or + if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif (space.isinstance_w(w_init, space.w_unicode) or space.isinstance_w(w_init, space.w_bytes)): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 - elif self.is_file: - result = self.prepare_file(w_init) - if result: - rffi.cast(rffi.CCHARPP, cdata)[0] = result - return 2 - return 0 else: - return 0 + return False itemsize = self.ctitem.size if itemsize <= 0: if isinstance(self.ctitem, ctypevoid.W_CTypeVoid): itemsize = 1 else: - return 0 + return False try: datasize = ovfcheck(length * itemsize) except OverflowError: @@ -304,7 +269,7 @@ lltype.free(result, flavor='raw') raise rffi.cast(rffi.CCHARPP, cdata)[0] = result - return 1 + return True def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag @@ -312,7 +277,7 @@ ob = space.interpclass_w(w_ob) result = (not isinstance(ob, cdataobj.W_CData) and self._prepare_pointer_call_argument(w_ob, cdata)) - if result == 0: + if not result: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) return result @@ -342,42 +307,3 @@ if attrchar == 'i': # item return self.space.wrap(self.ctitem) return W_CTypePtrBase._fget(self, attrchar) - -# ____________________________________________________________ - - -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -class CffiFileObj(object): - _immutable_ = True - - def __init__(self, fd, mode): - self.llf = rffi_fdopen(fd, mode) - if not self.llf: - raise OSError(rposix.get_errno(), "fdopen failed") - rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) - - def close(self): - rffi_fclose(self.llf) - - -def prepare_iofile_argument(space, w_fileobj): - fileobj = space.interpclass_w(w_fileobj) - from pypy.module._io.interp_iobase import W_IOBase - assert isinstance(fileobj, W_IOBase) - space.call_method(w_fileobj, "flush") - if fileobj.cffi_fileobj is None: - fd = space.int_w(space.call_method(w_fileobj, "fileno")) - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - fd = os.dup(fd) - mode = space.str_w(space.getattr(w_fileobj, space.wrap("mode"))) - try: - fileobj.cffi_fileobj = CffiFileObj(fd, mode) - except OSError, e: - raise wrap_oserror(space, e) - return fileobj.cffi_fileobj.llf - diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -209,9 +209,6 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" -def is_zero(space, w_ob): - return space.isinstance_w(w_ob, space.w_int) and not space.is_true(w_ob) - # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,19 +387,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -779,7 +768,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -792,14 +781,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1017,11 +1003,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): @@ -2503,15 +2488,16 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] -import io -fdopen_funcs = [io.open] -try: - import posix - fdopen_funcs.append(posix.fdopen) -except (ImportError, AttributeError): # win32, or py3k - pass +# XXX hack +if sys.version_info >= (3,): + try: + import posix, io + posix.fdopen = io.open + except ImportError: + pass # win32 def test_FILE(): + """FILE is not supported natively any more.""" if sys.platform == "win32": py.test.skip("testing FILE not implemented") # @@ -2521,83 +2507,16 @@ BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - fscanf = ll.load_function(BFunc2, "fscanf") - # - for fdopen in fdopen_funcs: - fdr, fdw = posix.pipe() - fr1 = fdopen(fdr, 'rb', 256) - fw1 = fdopen(fdw, 'wb', 256) - # - fw1.write(b"X") - res = fputs(b"hello world\n", fw1) - assert res >= 0 - fw1.flush() # should not be needed - # - p = newp(new_array_type(BCharP, 100), None) - res = fscanf(fr1, b"%s\n", p) - assert res == 1 - assert string(p) == b"Xhello" - fr1.close() - fw1.close() - -def test_FILE_only_for_FILE_arg(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - B_NOT_FILE = new_struct_type("NOT_FILE") - B_NOT_FILEP = new_pointer_type(B_NOT_FILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") # - for fdopen in fdopen_funcs: - fdr, fdw = posix.pipe() - fr1 = fdopen(fdr, 'r') - fw1 = fdopen(fdw, 'w') - # - e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value).startswith( - "initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not ") - -def test_FILE_object(): - if sys.platform == "win32": - py.test.skip("testing FILE not implemented") - # - BFILE = new_struct_type("$FILE") - BFILEP = new_pointer_type(BFILE) - BChar = new_primitive_type("char") - BCharP = new_pointer_type(BChar) - BInt = new_primitive_type("int") - BFunc = new_function_type((BCharP, BFILEP), BInt, False) - BFunc2 = new_function_type((BFILEP,), BInt, False) - ll = find_and_load_library('c') - fputs = ll.load_function(BFunc, "fputs") - fileno = ll.load_function(BFunc2, "fileno") - # - for fdopen in fdopen_funcs: - fdr, fdw = posix.pipe() - fw1 = fdopen(fdw, 'wb', 256) - # - fw1p = cast(BFILEP, fw1) - fw1.write(b"X") - fw1.flush() - res = fputs(b"hello\n", fw1p) - assert res >= 0 - res = fileno(fw1p) - if fdopen is not io.open and 'PY_DOT_PY' not in globals(): - assert res == fdw - fw1.close() - # - data = posix.read(fdr, 256) - assert data == b"Xhello\n" - posix.close(fdr) + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) + py.test.raises(TypeError, fputs, b"hello world\n", fw1) + fr1.close() + fw1.close() def test_GetLastError(): if sys.platform != "win32": diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,20 +1,7 @@ from pypy.objspace.fake.checkmodule import checkmodule -from pypy.module._cffi_backend import ctypeptr -from rpython.rtyper.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - # W_CTypePointer.prepare_file() is not working without translating - # the _io module too - def dummy_prepare_file(self, w_ob): - return lltype.nullptr(rffi.CCHARP.TO) - old = ctypeptr.W_CTypePointer.prepare_file - try: - ctypeptr.W_CTypePointer.prepare_file = dummy_prepare_file - # - checkmodule('_cffi_backend') - # - finally: - ctypeptr.W_CTypePointer.prepare_file = old + checkmodule('_cffi_backend') diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -37,8 +37,6 @@ raise unsupported(space, "File or stream is not seekable") class W_IOBase(Wrappable): - cffi_fileobj = None # pypy/module/_cffi_backend - def __init__(self, space): # XXX: IOBase thinks it has to maintain its own internal state in # `__IOBase_closed` and call flush() by itself, but it is redundant @@ -108,12 +106,6 @@ def close_w(self, space): if self._CLOSED(): return - - cffifo = self.cffi_fileobj - self.cffi_fileobj = None - if cffifo is not None: - cffifo.close() - try: space.call_method(self, "flush") finally: 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 @@ -138,6 +138,9 @@ def __getitem__(self, key): return 2 con.execute('insert into foo(x) values (?)', seq()) + del seq.__len__ + with pytest.raises(_sqlite3.ProgrammingError): + con.execute('insert into foo(x) values (?)', seq()) with pytest.raises(_sqlite3.ProgrammingError): con.execute('insert into foo(x) values (?)', {2:2}) with pytest.raises(ValueError) as e: diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -7,8 +7,7 @@ from rpython.memory.gctransform.log import log from rpython.memory.gctransform.support import get_rtti, ll_call_destructor from rpython.memory.gctransform.transform import GCTransformer -from rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, \ - WEAKREFPTR +from rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, WEAKREFPTR from rpython.tool.sourcetools import func_with_new_name from rpython.translator.backendopt import graphanalyze from rpython.translator.backendopt.finalizer import FinalizerAnalyzer @@ -317,7 +316,8 @@ malloc_fast = func_with_new_name( malloc_fast_meth, "malloc_fast") - s_False = annmodel.SomeBool(); s_False.const = False + s_False = annmodel.SomeBool() + s_False.const = False self.malloc_fast_ptr = getfn( malloc_fast, [s_gc, s_typeid16, @@ -335,7 +335,8 @@ malloc_varsize_clear_fast = func_with_new_name( GCClass.malloc_varsize_clear.im_func, "malloc_varsize_clear_fast") - s_False = annmodel.SomeBool(); s_False.const = False + s_False = annmodel.SomeBool() + s_False.const = False self.malloc_varsize_clear_fast_ptr = getfn( malloc_varsize_clear_fast, [s_gc, s_typeid16, @@ -614,7 +615,7 @@ if self.collect_analyzer.analyze_direct_call(graph): raise Exception("'no_collect' function can trigger collection:" " %s" % func) - + if self.write_barrier_ptr: self.clean_sets = ( find_initializing_stores(self.collect_analyzer, graph)) @@ -1180,7 +1181,7 @@ if self.gcdata.gc.moving_gc and not keep_current_args: # moving GCs don't borrow, so the caller does not need to keep # the arguments alive - livevars = [var for var in hop.livevars_after_op()] + livevars = hop.livevars_after_op() else: livevars = hop.livevars_after_op() + hop.current_op_keeps_alive() return livevars diff --git a/rpython/rtyper/module/ll_termios.py b/rpython/rtyper/module/ll_termios.py --- a/rpython/rtyper/module/ll_termios.py +++ b/rpython/rtyper/module/ll_termios.py @@ -24,17 +24,28 @@ class CConfig: _compilation_info_ = eci NCCS = rffi_platform.DefinedConstantInteger('NCCS') + _HAVE_STRUCT_TERMIOS_C_ISPEED = rffi_platform.Defined( + '_HAVE_STRUCT_TERMIOS_C_ISPEED') + _HAVE_STRUCT_TERMIOS_C_OSPEED = rffi_platform.Defined( + '_HAVE_STRUCT_TERMIOS_C_OSPEED') -NCCS = rffi_platform.configure(CConfig)['NCCS'] +c_config = rffi_platform.configure(CConfig) +NCCS = c_config['NCCS'] TCFLAG_T = rffi.UINT CC_T = rffi.UCHAR SPEED_T = rffi.UINT INT = rffi.INT +_add = [] +if c_config['_HAVE_STRUCT_TERMIOS_C_ISPEED']: + _add.append(('c_ispeed', SPEED_T)) +if c_config['_HAVE_STRUCT_TERMIOS_C_OSPEED']: + _add.append(('c_ospeed', SPEED_T)) TERMIOSP = rffi.CStructPtr('termios', ('c_iflag', TCFLAG_T), ('c_oflag', TCFLAG_T), ('c_cflag', TCFLAG_T), ('c_lflag', TCFLAG_T), - ('c_cc', lltype.FixedSizeArray(CC_T, NCCS))) + ('c_line', CC_T), + ('c_cc', lltype.FixedSizeArray(CC_T, NCCS)), *_add) def c_external(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci) From noreply at buildbot.pypy.org Thu Mar 7 12:31:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 12:31:22 +0100 (CET) Subject: [pypy-commit] pypy default: Fix for issue1198. Message-ID: <20130307113122.8B4911C10F8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62176:db608eb643ed Date: 2013-03-07 12:31 +0100 http://bitbucket.org/pypy/pypy/changeset/db608eb643ed/ Log: Fix for issue1198. diff --git a/rpython/translator/c/gcc/trackgcroot.py b/rpython/translator/c/gcc/trackgcroot.py --- a/rpython/translator/c/gcc/trackgcroot.py +++ b/rpython/translator/c/gcc/trackgcroot.py @@ -1099,6 +1099,7 @@ '___assert_rtn': None, 'L___assert_rtn$stub': None, 'L___eprintf$stub': None, + '__stack_chk_fail': None, } for _name in FunctionGcRootTracker.BASE_FUNCTIONS_NOT_RETURNING: FUNCTIONS_NOT_RETURNING[_name] = None @@ -1160,6 +1161,7 @@ '___assert_rtn': None, 'L___assert_rtn$stub': None, 'L___eprintf$stub': None, + '__stack_chk_fail': None, } for _name in FunctionGcRootTracker.BASE_FUNCTIONS_NOT_RETURNING: FUNCTIONS_NOT_RETURNING[_name] = None From noreply at buildbot.pypy.org Thu Mar 7 13:25:37 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 7 Mar 2013 13:25:37 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, lwassermann) Update targetimageloading to accept benchmark argument and jit args, and run the actual image if no benchmark is passed Message-ID: <20130307122537.A70121C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r132:eae827dda441 Date: 2013-03-07 13:02 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/eae827dda441/ Log: (tfel, lwassermann) Update targetimageloading to accept benchmark argument and jit args, and run the actual image if no benchmark is passed diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -1,80 +1,115 @@ import sys import os -from spyvm import model, interpreter, primitives, shadow -# from spyvm import classtable -# from spyvm.test.test_interpreter import * -from spyvm import squeakimage -from spyvm import constants -def tinyBenchmarks(space, image_name): - interp = interpreter.Interpreter(space, image_name=image_name) - return interp +from rpython.rlib.streamio import open_file_as_stream +from rpython.rlib import jit +from spyvm import model, interpreter, squeakimage, objspace, wrapper, model +from spyvm.tool.analyseimage import create_image -def run_benchmarks(interp, number, benchmark): - counter = 0 + +def _run_benchmark(interp, number, benchmark): w_object = model.W_SmallInteger(number) try: - interp.perform(w_object, "tinyBenchmarks") + interp.perform(w_object, benchmark) except interpreter.ReturnFromTopLevel, e: w_result = e.object - assert isinstance(w_result, model.W_BytesObject) print w_result.as_string() return 0 return -1 -from spyvm import objspace + +def _run_image(interp): + ap = wrapper.ProcessWrapper(space, wrapper.scheduler(space).active_process()) + w_ctx = ap.suspended_context() + assert isinstance(w_ctx, model.W_PointersObject) + ap.store_suspended_context(space.w_nil) + interp.interpret_with_w_frame(w_ctx) + return 0 + + space = objspace.ObjSpace() + +def _usage(argv): + print """ + Usage: %s + -j|--jit [jitargs] + -n|--number [smallint] + -m|--method [benchmark on smallint] + [image path, default: Squeak.image] + """ % argv[0] + + +def _arg_missing(argv, idx, arg): + if len(argv) == idx + 1: + raise RuntimeError("Error: missing argument after %s" % arg) + + def entry_point(argv): - if len(argv) > 1: - filename = argv[1] - if len(argv) > 3: - number = int(argv[2]) - benchmark = argv[3] + idx = 1 + image = None + number = 0 + benchmark = None + + while idx < len(argv): + arg = argv[idx] + if arg in ["-h", "--help"]: + _usage(argv) + return 0 + elif arg in ["-j", "--jit"]: + _arg_missing(argv, idx, arg) + jitarg = argv[idx + 1] + idx += 1 + jit.set_user_param(interpreter.Interpreter.jit_driver, jitarg) + elif arg in ["-n", "--number"]: + _arg_missing(argv, idx, arg) + number = int(argv[idx + 1]) + idx += 1 + elif arg in ["-m", "--method"]: + _arg_missing(argv, idx, arg) + benchmark = argv[idx + 1] + idx += 1 + elif image is None: + image = argv[idx] else: - number = 0 - benchmark = "tinyBenchmarks" + _usage(argv) + return -1 + idx += 1 + + if image is None: + image = "Squeak.image" + + try: + f = open_file_as_stream(image) + except OSError as e: + os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), image)) + return 1 + try: + imagedata = f.readall() + finally: + f.close() + + image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata)) + image = create_image(space, image_reader) + interp = interpreter.Interpreter(space, image) + if benchmark is not None: + return _run_benchmark(interp, number, benchmark) else: - print "usage:", argv[0], "" - return -1 - reader = squeakimage.reader_for_image(space, squeakimage.Stream(DummyFile(filename))) - reader.initialize() - image = squeakimage.SqueakImage() - image.from_reader(space, reader) - interp = interpreter.Interpreter(space, image, filename) - run_benchmarks(interp, number, benchmark) - return 0 + return _run_image(interp) # _____ Define and setup target ___ + def target(*args): return entry_point, None + def jitpolicy(self): from rpython.jit.codewriter.policy import JitPolicy return JitPolicy() -class DummyFile: - def __init__(self,filename): - import os - fd = os.open(filename, os.O_RDONLY, 0777) - try: - content = [] - while 1: - s = os.read(fd, 4096) - if not s: - break - content.append(s) - self.content = "".join(content) - finally: - os.close(fd) - def read(self): - return self.content - def close(self): - pass - if __name__ == "__main__": entry_point(sys.argv) From noreply at buildbot.pypy.org Thu Mar 7 14:14:11 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 7 Mar 2013 14:14:11 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: reduced the default smalltalk max stack size to 100 Message-ID: <20130307131411.7EB7B1C0925@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r133:a22cedb502be Date: 2013-03-07 14:10 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a22cedb502be/ Log: reduced the default smalltalk max stack size to 100 diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -33,7 +33,7 @@ get_printable_location=get_printable_location ) - def __init__(self, space, image=None, image_name="", max_stack_depth=500): + def __init__(self, space, image=None, image_name="", max_stack_depth=100): self.space = space self.image = image self.image_name = image_name From noreply at buildbot.pypy.org Thu Mar 7 14:14:12 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 7 Mar 2013 14:14:12 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Added shorthandprinting for the contexts. The hook in c_loop is commented out Message-ID: <20130307131412.A23CF1C1058@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r134:a6dbd607b975 Date: 2013-03-07 14:13 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a6dbd607b975/ Log: Added shorthandprinting for the contexts. The hook in c_loop is commented out diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -72,6 +72,8 @@ s_new_context.push(nlr.value) def c_loop(self, s_context): + # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) + # print padding + s_context.short_str() while True: pc = s_context._pc method = s_context.s_method() diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -690,6 +690,10 @@ # A blockcontext doesn't have any temps return 0 + def short_str(self): + return 'BlockContext of %s (%i)' % (self.w_method().get_identifier_string(), + self.pc() + 1) + class MethodContextShadow(ContextPartShadow): _attr_ = ['w_closure_or_nil', '_w_receiver', '__w_method'] @@ -836,6 +840,10 @@ retval += "\nStack : " + str(self.stack()) return retval + def short_str(self): + block = '[] of' if self.is_closure_context() else '' + return '%s %s (%i)' % (block, self.w_method().get_identifier_string(), self.pc() + 1) + class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", "literals[*]", "bytecodeoffset", From noreply at buildbot.pypy.org Thu Mar 7 16:40:29 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 7 Mar 2013 16:40:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: add loopTest2 and loopTest3 Message-ID: <20130307154029.B0BF31C06F2@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r135:2657435de309 Date: 2013-03-07 16:38 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2657435de309/ Log: add loopTest2 and loopTest3 diff --git a/images/minitest.image b/images/minitest.image index 5753d32adc6e5ca83c6b7bf990258090ca1812d7..11fbf4e52f946020cefb4e771afc7a950f001596 GIT binary patch [cut] From noreply at buildbot.pypy.org Thu Mar 7 17:51:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 17:51:37 +0100 (CET) Subject: [pypy-commit] cffi default: Add warnings about keeping alive the library object. Message-ID: <20130307165137.3D20E1C06F2@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1186:c28026358db5 Date: 2013-03-07 17:51 +0100 http://bitbucket.org/cffi/cffi/changeset/c28026358db5/ Log: Add warnings about keeping alive the library object. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -459,6 +459,10 @@ For the optional ``flags`` argument, see ``man dlopen`` (ignored on Windows). It defaults to ``ffi.RTLD_NOW``. +This function returns a "library" object that gets closed when it goes +out of scope. Make sure you keep the library object around as long as +needed. + .. _below: @@ -622,6 +626,10 @@ check. Be sure to have other means of clearing the ``tmpdir`` whenever you change your sources. +This function returns a "library" object that gets closed when it goes +out of scope. Make sure you keep the library object around as long as +needed. + Working with pointers, structures and arrays -------------------------------------------- From noreply at buildbot.pypy.org Thu Mar 7 18:26:12 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 7 Mar 2013 18:26:12 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed return value printing in targetimageloadingsmalltalk for benchmarks Message-ID: <20130307172612.EF7B51C1067@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r137:68c5b9f0b45b Date: 2013-03-07 18:19 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/68c5b9f0b45b/ Log: fixed return value printing in targetimageloadingsmalltalk for benchmarks diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -11,10 +11,12 @@ def _run_benchmark(interp, number, benchmark): w_object = model.W_SmallInteger(number) try: - interp.perform(w_object, benchmark) + w_result = interp.perform(w_object, benchmark) except interpreter.ReturnFromTopLevel, e: w_result = e.object + if w_result: assert isinstance(w_result, model.W_BytesObject) + print '\n' print w_result.as_string() return 0 return -1 From noreply at buildbot.pypy.org Thu Mar 7 18:26:11 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 7 Mar 2013 18:26:11 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: updated test/jit Message-ID: <20130307172611.C17D31C0925@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r136:e320b3ab9f74 Date: 2013-03-07 18:18 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/e320b3ab9f74/ Log: updated test/jit diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -4,7 +4,7 @@ # view jit. # -import sys +import sys, os from rpython import conftest class o: view = False @@ -15,8 +15,9 @@ from spyvm import model, interpreter, primitives, shadow -from spyvm import objspace +from spyvm import objspace, squeakimage from spyvm.tool.analyseimage import create_squeakimage, create_testimage +from rpython.rlib.streamio import open_file_as_stream mockclass = objspace.bootstrap_class @@ -46,7 +47,7 @@ # Tests # -# sys.setrecursionlimit(100000) +sys.setrecursionlimit(5000) class TestLLtype(LLJitMixin): @@ -54,19 +55,12 @@ from spyvm import objspace space = objspace.ObjSpace() + image = create_testimage(space) interp = interpreter.Interpreter(space, image) - - - counter = 0 - - w_selector = interp.perform(space.wrap_string("loopTest"), "asSymbol") - w_object = model.W_SmallInteger(0) - s_class = w_object.shadow_of_my_class(space) - s_method = s_class.lookup(w_selector) - s_frame = s_method.create_frame(space, w_object, []) - + w_selector = interp.perform(space.wrap_string('loopTest'), "asSymbol") + assert isinstance(w_selector, model.W_BytesObject) def interp_w(): - interp.loop(s_frame.w_self()) + interp.perform(model.W_SmallInteger(1000), w_selector) self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True, inline=True) From noreply at buildbot.pypy.org Thu Mar 7 18:26:14 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 7 Mar 2013 18:26:14 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added can_enter_jit hint Message-ID: <20130307172614.194BF1C0925@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r138:4ad14e0d4c7c Date: 2013-03-07 18:19 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4ad14e0d4c7c/ Log: added can_enter_jit hint diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -74,10 +74,15 @@ def c_loop(self, s_context): # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) # print padding + s_context.short_str() + old_pc = 0 while True: pc = s_context._pc method = s_context.s_method() - + if pc < old_pc: + self.jit_driver.can_enter_jit( + pc=pc, self=self, method=method, + s_context=s_context) + old_pc = pc self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, s_context=s_context) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -532,6 +532,7 @@ self._temps_and_stack[ptr] = w_v self._stack_ptr = ptr + 1 + @jit.unroll_safe def push_all(self, lst): for elt in lst: self.push(elt) From noreply at buildbot.pypy.org Thu Mar 7 18:26:15 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 7 Mar 2013 18:26:15 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: small changes to .hgignore Message-ID: <20130307172615.51FA81C0925@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r139:126749d90704 Date: 2013-03-07 18:25 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/126749d90704/ Log: small changes to .hgignore diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,3 +1,7 @@ syntax: glob *.py[co] *~ +pypy-c-jit-62116-b027d4428675-linux +images/Squeak* +targetimageloadingsmalltalk-c +images/package-cache From noreply at buildbot.pypy.org Thu Mar 7 20:44:11 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 20:44:11 +0100 (CET) Subject: [pypy-commit] pypy py3k: passthru unicode in dict iter reprs Message-ID: <20130307194411.1A87C1C101B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62177:34a402b65a45 Date: 2013-03-07 11:39 -0800 http://bitbucket.org/pypy/pypy/changeset/34a402b65a45/ Log: passthru unicode in dict iter reprs diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1065,10 +1065,10 @@ def repr__DictViewKeys(space, w_dictview): + typename = space.type(w_dictview).getname(space).decode('utf-8') w_seq = space.call_function(space.w_list, w_dictview) - w_repr = space.repr(w_seq) - return space.wrap("%s(%s)" % (space.type(w_dictview).getname(space), - space.str_w(w_repr))) + seq_repr = space.unicode_w(space.repr(w_seq)) + return space.wrap(u"%s(%s)" % (typename, seq_repr)) repr__DictViewItems = repr__DictViewKeys repr__DictViewValues = repr__DictViewKeys diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import py import sys from pypy.interpreter.error import OperationError @@ -719,6 +720,8 @@ assert isinstance(r, str) assert (r == "dict_values(['ABC', 10])" or r == "dict_values([10, 'ABC'])") + d = {'日本': '日本国'} + assert repr(d.items()) == "dict_items([('日本', '日本国')])" def test_keys_set_operations(self): d1 = {'a': 1, 'b': 2} From noreply at buildbot.pypy.org Thu Mar 7 20:52:29 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 20:52:29 +0100 (CET) Subject: [pypy-commit] pypy default: improve sqlite3 statement arg checking, test Message-ID: <20130307195229.6B9C51C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62178:9a1dee0e3eb5 Date: 2013-03-07 14:38 -0500 http://bitbucket.org/pypy/pypy/changeset/9a1dee0e3eb5/ Log: improve sqlite3 statement arg checking, test diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -800,6 +800,8 @@ try: self.__description = None self._reset = False + if not isinstance(sql, (str, unicode)): + raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -845,6 +847,8 @@ try: self.__description = None self._reset = False + if not isinstance(sql, (str, unicode)): + raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -878,6 +882,8 @@ statement = c_void_p() if isinstance(sql, unicode): sql = sql.encode('utf-8') + elif not isinstance(sql, str): + raise ValueError("script argument must be unicode or string.") c_sql = c_char_p(sql) self.__connection.commit() 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 @@ -127,6 +127,21 @@ except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") +def test_statement_arg_checking(): + con = _sqlite3.connect(':memory:') + with pytest.raises(_sqlite3.Warning) as e: + con(123) + assert str(e.value) == 'SQL is of wrong type. Must be string or unicode.' + with pytest.raises(ValueError) as e: + con.execute(123) + assert str(e.value) == 'operation parameter must be str or unicode' + with pytest.raises(ValueError) as e: + con.executemany(123, 123) + assert str(e.value) == 'operation parameter must be str or unicode' + with pytest.raises(ValueError) as e: + con.executescript(123) + assert str(e.value) == 'script argument must be unicode or string.' + def test_statement_param_checking(): con = _sqlite3.connect(':memory:') con.execute('create table foo(x)') From noreply at buildbot.pypy.org Thu Mar 7 20:52:30 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 20:52:30 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130307195230.EFC351C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62179:e65d20740bfa Date: 2013-03-07 14:51 -0500 http://bitbucket.org/pypy/pypy/changeset/e65d20740bfa/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -800,6 +800,8 @@ try: self.__description = None self._reset = False + if not isinstance(sql, str): + raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -845,6 +847,8 @@ try: self.__description = None self._reset = False + if not isinstance(sql, str): + raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -876,7 +880,10 @@ self._reset = False self.__check_cursor() statement = c_void_p() - sql = sql.encode('utf-8') + if isinstance(sql, str): + sql = sql.encode('utf-8') + else: + raise ValueError("script argument must be unicode or string.") c_sql = c_char_p(sql) self.__connection.commit() 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 @@ -127,6 +127,21 @@ except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") +def test_statement_arg_checking(): + con = _sqlite3.connect(':memory:') + with pytest.raises(_sqlite3.Warning) as e: + con(123) + assert str(e.value) == 'SQL is of wrong type. Must be string or unicode.' + with pytest.raises(ValueError) as e: + con.execute(123) + assert str(e.value) == 'operation parameter must be str or unicode' + with pytest.raises(ValueError) as e: + con.executemany(123, 123) + assert str(e.value) == 'operation parameter must be str or unicode' + with pytest.raises(ValueError) as e: + con.executescript(123) + assert str(e.value) == 'script argument must be unicode or string.' + def test_statement_param_checking(): con = _sqlite3.connect(':memory:') con.execute('create table foo(x)') diff --git a/rpython/translator/c/gcc/trackgcroot.py b/rpython/translator/c/gcc/trackgcroot.py --- a/rpython/translator/c/gcc/trackgcroot.py +++ b/rpython/translator/c/gcc/trackgcroot.py @@ -1099,6 +1099,7 @@ '___assert_rtn': None, 'L___assert_rtn$stub': None, 'L___eprintf$stub': None, + '__stack_chk_fail': None, } for _name in FunctionGcRootTracker.BASE_FUNCTIONS_NOT_RETURNING: FUNCTIONS_NOT_RETURNING[_name] = None @@ -1160,6 +1161,7 @@ '___assert_rtn': None, 'L___assert_rtn$stub': None, 'L___eprintf$stub': None, + '__stack_chk_fail': None, } for _name in FunctionGcRootTracker.BASE_FUNCTIONS_NOT_RETURNING: FUNCTIONS_NOT_RETURNING[_name] = None From noreply at buildbot.pypy.org Thu Mar 7 20:52:32 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 20:52:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130307195232.51D171C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62180:cca78b78a0ed Date: 2013-03-07 14:52 -0500 http://bitbucket.org/pypy/pypy/changeset/cca78b78a0ed/ Log: merge heads diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1065,10 +1065,10 @@ def repr__DictViewKeys(space, w_dictview): + typename = space.type(w_dictview).getname(space).decode('utf-8') w_seq = space.call_function(space.w_list, w_dictview) - w_repr = space.repr(w_seq) - return space.wrap("%s(%s)" % (space.type(w_dictview).getname(space), - space.str_w(w_repr))) + seq_repr = space.unicode_w(space.repr(w_seq)) + return space.wrap(u"%s(%s)" % (typename, seq_repr)) repr__DictViewItems = repr__DictViewKeys repr__DictViewValues = repr__DictViewKeys diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import py import sys from pypy.interpreter.error import OperationError @@ -719,6 +720,8 @@ assert isinstance(r, str) assert (r == "dict_values(['ABC', 10])" or r == "dict_values([10, 'ABC'])") + d = {'日本': '日本国'} + assert repr(d.items()) == "dict_items([('日本', '日本国')])" def test_keys_set_operations(self): d1 = {'a': 1, 'b': 2} From noreply at buildbot.pypy.org Thu Mar 7 20:55:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 20:55:49 +0100 (CET) Subject: [pypy-commit] pypy default: comments Message-ID: <20130307195549.E6BF61C1058@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62181:8ce8657b8be1 Date: 2013-03-07 14:55 -0500 http://bitbucket.org/pypy/pypy/changeset/8ce8657b8be1/ Log: comments diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -5,6 +5,9 @@ # (nondist/sandbox/collections/pydeque.py rev 1.1, Raymond Hettinger) # +# Note that PyPy also contains a built-in module '_collections' which will hide +# this one if compiled in. + import operator try: from thread import get_ident as _thread_ident diff --git a/lib_pypy/cStringIO.py b/lib_pypy/cStringIO.py --- a/lib_pypy/cStringIO.py +++ b/lib_pypy/cStringIO.py @@ -2,7 +2,7 @@ # StringIO-based cStringIO implementation. # -# Note that PyPy contains also a built-in module 'cStringIO' which will hide +# Note that PyPy also contains a built-in module 'cStringIO' which will hide # this one if compiled in. from StringIO import * From noreply at buildbot.pypy.org Thu Mar 7 21:57:42 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 21:57:42 +0100 (CET) Subject: [pypy-commit] pypy default: reindent this sillyness Message-ID: <20130307205742.4C0E91C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62182:9b6d55d58379 Date: 2013-03-07 12:42 -0800 http://bitbucket.org/pypy/pypy/changeset/9b6d55d58379/ Log: reindent this sillyness diff --git a/pypy/module/__builtin__/test/test_apply.py b/pypy/module/__builtin__/test/test_apply.py --- a/pypy/module/__builtin__/test/test_apply.py +++ b/pypy/module/__builtin__/test/test_apply.py @@ -1,24 +1,24 @@ # This is a very trivial series of tests. If apply is subtlely broken, # we will have to find out some other way. - + class AppTestApply: - def test_trivial_listonly(self): - def mymin(*args): - return min(list(args)) + def test_trivial_listonly(self): + def mymin(*args): + return min(list(args)) - assert apply(mymin, [-1,-2,-3,-4]) == -4 + assert apply(mymin, [-1,-2,-3,-4]) == -4 - def test_trivial_dictonly(self): - def mymin(*arr, **kwargs): - return min(list(arr) + kwargs.values()) - assert apply(mymin, - [], {'null' : 0, 'one': 1, 'two' : 2}) == ( - 0) - def test_trivial(self): - def mymin(*arr, **kwargs): - return min(list(arr) + kwargs.values()) - assert apply(mymin, - [-1,-2,-3,-4], - {'null' : 0, 'one': 1, 'two' : 2}) == ( - (-4)) + def test_trivial_dictonly(self): + def mymin(*arr, **kwargs): + return min(list(arr) + kwargs.values()) + assert apply(mymin, + [], {'null' : 0, 'one': 1, 'two' : 2}) == ( + 0) + def test_trivial(self): + def mymin(*arr, **kwargs): + return min(list(arr) + kwargs.values()) + assert apply(mymin, + [-1,-2,-3,-4], + {'null' : 0, 'one': 1, 'two' : 2}) == ( + (-4)) diff --git a/pypy/module/__builtin__/test/test_classobj.py b/pypy/module/__builtin__/test/test_classobj.py --- a/pypy/module/__builtin__/test/test_classobj.py +++ b/pypy/module/__builtin__/test/test_classobj.py @@ -393,14 +393,14 @@ def test_unary_method(self): class A: def __pos__(self): - return -1 + return -1 a = A() assert +a == -1 def test_cmp(self): class A: def __lt__(self, other): - return True + return True a = A() b = A() assert a < b @@ -430,7 +430,7 @@ def __add__(self, other): return 1 + other def __coerce__(self, other): - return self, int(other) + return self, int(other) a = A() assert a + 1 == 2 @@ -441,7 +441,7 @@ l = [] class A: def __coerce__(self, other): - l.append(other) + l.append(other) a = A() raises(TypeError, "a + 1") @@ -468,8 +468,8 @@ def __init__(self): self.l = [] def __iadd__(self, other): - self.l.append(other) - return self + self.l.append(other) + return self a1 = a = A() a += 1 assert a is a1 @@ -531,11 +531,11 @@ a = A() raises(TypeError, hash, a) bigint = sys.maxint + 1 - class A: # can return long + class A: # can return long def __hash__(self): return long(bigint) a = A() - assert hash(a) == -bigint + assert hash(a) == -bigint def test_index(self): import sys @@ -724,11 +724,11 @@ class X: def __iter__(self): return Y() - + class Y: def next(self): return 3 - + for i in X(): assert i == 3 break @@ -750,7 +750,7 @@ skip("assignment to __del__ doesn't give a warning in CPython") import warnings - + warnings.simplefilter('error', RuntimeWarning) try: class X: @@ -1096,4 +1096,3 @@ a = A() assert a.x == 42 assert self.has_mapdict(a) - diff --git a/pypy/module/__builtin__/test/test_filter.py b/pypy/module/__builtin__/test/test_filter.py --- a/pypy/module/__builtin__/test/test_filter.py +++ b/pypy/module/__builtin__/test/test_filter.py @@ -1,9 +1,9 @@ -# trivial functions for testing +# trivial functions for testing class AppTestFilter: def test_filter_no_arguments(self): raises(TypeError, filter) - + def test_filter_no_function_no_seq(self): raises(TypeError, filter, None) @@ -14,22 +14,22 @@ raises(TypeError, filter, lambda x: x>3, [1], [2]) def test_filter_no_function_list(self): - assert filter(None, [1, 2, 3]) == [1, 2, 3] + assert filter(None, [1, 2, 3]) == [1, 2, 3] def test_filter_no_function_tuple(self): - assert filter(None, (1, 2, 3)) == (1, 2, 3) + assert filter(None, (1, 2, 3)) == (1, 2, 3) def test_filter_no_function_string(self): - assert filter(None, 'mystring') == 'mystring' + assert filter(None, 'mystring') == 'mystring' def test_filter_no_function_with_bools(self): - assert filter(None, (True, False, True)) == (True, True) - + assert filter(None, (True, False, True)) == (True, True) + def test_filter_list(self): - assert filter(lambda x: x>3, [1, 2, 3, 4, 5]) == [4, 5] + assert filter(lambda x: x>3, [1, 2, 3, 4, 5]) == [4, 5] def test_filter_tuple(self): - assert filter(lambda x: x>3, (1, 2, 3, 4, 5)) == (4, 5) + assert filter(lambda x: x>3, (1, 2, 3, 4, 5)) == (4, 5) def test_filter_string(self): - assert filter(lambda x: x>'a', 'xyzabcd') == 'xyzbcd' + assert filter(lambda x: x>'a', 'xyzabcd') == 'xyzbcd' diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -1,216 +1,216 @@ class AppTestMap: - def test_trivial_map_one_seq(self): - assert map(lambda x: x+2, [1, 2, 3, 4]) == [3, 4, 5, 6] + def test_trivial_map_one_seq(self): + assert map(lambda x: x+2, [1, 2, 3, 4]) == [3, 4, 5, 6] - def test_trivial_map_one_seq_2(self): - assert map(str, [1, 2, 3, 4]) == ['1', '2', '3', '4'] + def test_trivial_map_one_seq_2(self): + assert map(str, [1, 2, 3, 4]) == ['1', '2', '3', '4'] - def test_trivial_map_two_seq(self): - assert map(lambda x,y: x+y, - [1, 2, 3, 4],[1, 2, 3, 4]) == ( - [2, 4, 6, 8]) + def test_trivial_map_two_seq(self): + assert map(lambda x,y: x+y, + [1, 2, 3, 4],[1, 2, 3, 4]) == ( + [2, 4, 6, 8]) - def test_trivial_map_sizes_dont_match_and_should(self): - raises(TypeError, map, lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3]) + def test_trivial_map_sizes_dont_match_and_should(self): + raises(TypeError, map, lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3]) - def test_trivial_map_no_arguments(self): - raises(TypeError, map) + def test_trivial_map_no_arguments(self): + raises(TypeError, map) - def test_trivial_map_no_function_no_seq(self): - raises(TypeError, map, None) + def test_trivial_map_no_function_no_seq(self): + raises(TypeError, map, None) - def test_trivial_map_no_fuction_one_seq(self): - assert map(None, [1, 2, 3]) == [1, 2, 3] + def test_trivial_map_no_fuction_one_seq(self): + assert map(None, [1, 2, 3]) == [1, 2, 3] - def test_trivial_map_no_function(self): - assert map(None, [1,2,3], [4,5,6], [7,8], [1]) == ( - [(1, 4, 7, 1), (2, 5, 8, None), (3, 6, None, None)]) + def test_trivial_map_no_function(self): + assert map(None, [1,2,3], [4,5,6], [7,8], [1]) == ( + [(1, 4, 7, 1), (2, 5, 8, None), (3, 6, None, None)]) - def test_map_identity1(self): - a = ['1', 2, 3, 'b', None] - b = a[:] - assert map(lambda x: x, a) == a - assert a == b + def test_map_identity1(self): + a = ['1', 2, 3, 'b', None] + b = a[:] + assert map(lambda x: x, a) == a + assert a == b - def test_map_None(self): - a = ['1', 2, 3, 'b', None] - b = a[:] - assert map(None, a) == a - assert a == b + def test_map_None(self): + a = ['1', 2, 3, 'b', None] + b = a[:] + assert map(None, a) == a + assert a == b - def test_map_badoperation(self): - a = ['1', 2, 3, 'b', None] - raises(TypeError, map, lambda x: x+1, a) + def test_map_badoperation(self): + a = ['1', 2, 3, 'b', None] + raises(TypeError, map, lambda x: x+1, a) - def test_map_multiply_identity(self): - a = ['1', 2, 3, 'b', None] - b = [ 2, 3, 4, 5, 6] - assert map(None, a, b) == [('1', 2), (2, 3), (3, 4), ('b', 5), (None, 6)] + def test_map_multiply_identity(self): + a = ['1', 2, 3, 'b', None] + b = [ 2, 3, 4, 5, 6] + assert map(None, a, b) == [('1', 2), (2, 3), (3, 4), ('b', 5), (None, 6)] - def test_map_add(self): - a = [1, 2, 3, 4] - b = [0, 1, 1, 1] - assert map(lambda x, y: x+y, a, b) == [1, 3, 4, 5] + def test_map_add(self): + a = [1, 2, 3, 4] + b = [0, 1, 1, 1] + assert map(lambda x, y: x+y, a, b) == [1, 3, 4, 5] - def test_map_first_item(self): - a = [1, 2, 3, 4, 5] - b = [] - assert map(lambda x, y: x, a, b) == a + def test_map_first_item(self): + a = [1, 2, 3, 4, 5] + b = [] + assert map(lambda x, y: x, a, b) == a - def test_map_iterables(self): - class A(object): - def __init__(self, n): - self.n = n - def __iter__(self): - return B(self.n) - class B(object): - def __init__(self, n): - self.n = n - def next(self): - self.n -= 1 - if self.n == 0: raise StopIteration - return self.n - result = map(None, A(3), A(8)) - # this also checks that B.next() is not called any more after it - # raised StopIteration once - assert result == [(2, 7), (1, 6), (None, 5), (None, 4), - (None, 3), (None, 2), (None, 1)] + def test_map_iterables(self): + class A(object): + def __init__(self, n): + self.n = n + def __iter__(self): + return B(self.n) + class B(object): + def __init__(self, n): + self.n = n + def next(self): + self.n -= 1 + if self.n == 0: raise StopIteration + return self.n + result = map(None, A(3), A(8)) + # this also checks that B.next() is not called any more after it + # raised StopIteration once + assert result == [(2, 7), (1, 6), (None, 5), (None, 4), + (None, 3), (None, 2), (None, 1)] class AppTestZip: - def test_one_list(self): - assert zip([1,2,3]) == [(1,), (2,), (3,)] + def test_one_list(self): + assert zip([1,2,3]) == [(1,), (2,), (3,)] - def test_three_lists(self): - assert zip([1,2,3], [1,2], [1,2,3]) == [(1,1,1), (2,2,2)] + def test_three_lists(self): + assert zip([1,2,3], [1,2], [1,2,3]) == [(1,1,1), (2,2,2)] - def test_bad_length_hint(self): - class Foo(object): - def __length_hint__(self): - return NotImplemented - def __iter__(self): - if False: - yield None - assert zip(Foo()) == [] + def test_bad_length_hint(self): + class Foo(object): + def __length_hint__(self): + return NotImplemented + def __iter__(self): + if False: + yield None + assert zip(Foo()) == [] class AppTestReduce: - def test_None(self): - raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None) + def test_None(self): + raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None) - def test_sum(self): - assert reduce(lambda x, y: x+y, [1,2,3,4], 0) == 10 - assert reduce(lambda x, y: x+y, [1,2,3,4]) == 10 + def test_sum(self): + assert reduce(lambda x, y: x+y, [1,2,3,4], 0) == 10 + assert reduce(lambda x, y: x+y, [1,2,3,4]) == 10 - def test_minus(self): - assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0 - assert reduce(lambda x, y: x-y, [2, 8], 10) == 0 + def test_minus(self): + assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0 + assert reduce(lambda x, y: x-y, [2, 8], 10) == 0 class AppTestFilter: - def test_None(self): - assert filter(None, ['a', 'b', 1, 0, None]) == ['a', 'b', 1] + def test_None(self): + assert filter(None, ['a', 'b', 1, 0, None]) == ['a', 'b', 1] - def test_return_type(self): - txt = "This is a test text" - assert filter(None, txt) == txt - tup = ("a", None, 0, [], 1) - assert filter(None, tup) == ("a", 1) + def test_return_type(self): + txt = "This is a test text" + assert filter(None, txt) == txt + tup = ("a", None, 0, [], 1) + assert filter(None, tup) == ("a", 1) - def test_function(self): - assert filter(lambda x: x != "a", "a small text") == " smll text" - assert filter(lambda x: x < 20, [3, 33, 5, 55]) == [3, 5] + def test_function(self): + assert filter(lambda x: x != "a", "a small text") == " smll text" + assert filter(lambda x: x < 20, [3, 33, 5, 55]) == [3, 5] - def test_filter_tuple_calls_getitem(self): - class T(tuple): - def __getitem__(self, i): - return i * 10 - assert filter(lambda x: x != 20, T("abcd")) == (0, 10, 30) + def test_filter_tuple_calls_getitem(self): + class T(tuple): + def __getitem__(self, i): + return i * 10 + assert filter(lambda x: x != 20, T("abcd")) == (0, 10, 30) class AppTestXRange: - def test_xrange(self): - x = xrange(2, 9, 3) - assert x[1] == 5 - assert len(x) == 3 - assert list(x) == [2, 5, 8] - # test again, to make sure that xrange() is not its own iterator - assert list(x) == [2, 5, 8] + def test_xrange(self): + x = xrange(2, 9, 3) + assert x[1] == 5 + assert len(x) == 3 + assert list(x) == [2, 5, 8] + # test again, to make sure that xrange() is not its own iterator + assert list(x) == [2, 5, 8] - def test_xrange_iter(self): - x = xrange(2, 9, 3) - it = iter(x) - assert iter(it) is it - assert it.next() == 2 - assert it.next() == 5 - assert it.next() == 8 - raises(StopIteration, it.next) - # test again, to make sure that xrange() is not its own iterator - assert iter(x).next() == 2 + def test_xrange_iter(self): + x = xrange(2, 9, 3) + it = iter(x) + assert iter(it) is it + assert it.next() == 2 + assert it.next() == 5 + assert it.next() == 8 + raises(StopIteration, it.next) + # test again, to make sure that xrange() is not its own iterator + assert iter(x).next() == 2 - def test_xrange_object_with___int__(self): - class A(object): - def __int__(self): - return 5 + def test_xrange_object_with___int__(self): + class A(object): + def __int__(self): + return 5 - assert list(xrange(A())) == [0, 1, 2, 3, 4] - assert list(xrange(0, A())) == [0, 1, 2, 3, 4] - assert list(xrange(0, 10, A())) == [0, 5] + assert list(xrange(A())) == [0, 1, 2, 3, 4] + assert list(xrange(0, A())) == [0, 1, 2, 3, 4] + assert list(xrange(0, 10, A())) == [0, 5] - def test_xrange_float(self): - assert list(xrange(0.1, 2.0, 1.1)) == [0, 1] + def test_xrange_float(self): + assert list(xrange(0.1, 2.0, 1.1)) == [0, 1] - def test_xrange_long(self): - import sys - a = long(10 * sys.maxint) - raises(OverflowError, xrange, a) - raises(OverflowError, xrange, 0, a) - raises(OverflowError, xrange, 0, 1, a) + def test_xrange_long(self): + import sys + a = long(10 * sys.maxint) + raises(OverflowError, xrange, a) + raises(OverflowError, xrange, 0, a) + raises(OverflowError, xrange, 0, 1, a) - def test_xrange_reduce(self): - x = xrange(2, 9, 3) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_xrange_reduce(self): + x = xrange(2, 9, 3) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_xrange_iter_reduce(self): - x = iter(xrange(2, 9, 3)) - x.next() - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_xrange_iter_reduce(self): + x = iter(xrange(2, 9, 3)) + x.next() + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_xrange_iter_reduce_one(self): - x = iter(xrange(2, 9)) - x.next() - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_xrange_iter_reduce_one(self): + x = iter(xrange(2, 9)) + x.next() + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_lib_python_xrange_optimization(self): - x = xrange(1) - assert type(reversed(x)) == type(iter(x)) + def test_lib_python_xrange_optimization(self): + x = xrange(1) + assert type(reversed(x)) == type(iter(x)) class AppTestReversed: - def test_reversed(self): - r = reversed("hello") - assert iter(r) is r - assert r.next() == "o" - assert r.next() == "l" - assert r.next() == "l" - assert r.next() == "e" - assert r.next() == "h" - raises(StopIteration, r.next) - assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] - raises(TypeError, reversed, reversed("hello")) + def test_reversed(self): + r = reversed("hello") + assert iter(r) is r + assert r.next() == "o" + assert r.next() == "l" + assert r.next() == "l" + assert r.next() == "e" + assert r.next() == "h" + raises(StopIteration, r.next) + assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] + raises(TypeError, reversed, reversed("hello")) class AppTestApply: - def test_apply(self): - def f(*args, **kw): - return args, kw - args = (1,3) - kw = {'a': 1, 'b': 4} - assert apply(f) == ((), {}) - assert apply(f, args) == (args, {}) - assert apply(f, args, kw) == (args, kw) + def test_apply(self): + def f(*args, **kw): + return args, kw + args = (1,3) + kw = {'a': 1, 'b': 4} + assert apply(f) == ((), {}) + assert apply(f, args) == (args, {}) + assert apply(f, args, kw) == (args, kw) class AppTestAllAny: """ @@ -262,16 +262,16 @@ assert any([x > 42 for x in S]) == False class AppTestMinMax: - def test_min(self): - assert min(1, 2) == 1 - assert min(1, 2, key=lambda x: -x) == 2 - assert min([1, 2, 3]) == 1 - raises(TypeError, min, 1, 2, bar=2) - raises(TypeError, min, 1, 2, key=lambda x: x, bar=2) + def test_min(self): + assert min(1, 2) == 1 + assert min(1, 2, key=lambda x: -x) == 2 + assert min([1, 2, 3]) == 1 + raises(TypeError, min, 1, 2, bar=2) + raises(TypeError, min, 1, 2, key=lambda x: x, bar=2) - def test_max(self): - assert max(1, 2) == 2 - assert max(1, 2, key=lambda x: -x) == 1 - assert max([1, 2, 3]) == 3 - raises(TypeError, max, 1, 2, bar=2) - raises(TypeError, max, 1, 2, key=lambda x: x, bar=2) + def test_max(self): + assert max(1, 2) == 2 + assert max(1, 2, key=lambda x: -x) == 1 + assert max([1, 2, 3]) == 3 + raises(TypeError, max, 1, 2, bar=2) + raises(TypeError, max, 1, 2, key=lambda x: x, bar=2) diff --git a/pypy/module/__builtin__/test/test_minmax.py b/pypy/module/__builtin__/test/test_minmax.py --- a/pypy/module/__builtin__/test/test_minmax.py +++ b/pypy/module/__builtin__/test/test_minmax.py @@ -1,85 +1,85 @@ class AppTestMin: - def test_min_notseq(self): - raises(TypeError, min, 1) + def test_min_notseq(self): + raises(TypeError, min, 1) - def test_min_usual(self): - assert min(1, 2, 3) == 1 + def test_min_usual(self): + assert min(1, 2, 3) == 1 - def test_min_floats(self): - assert min(0.1, 2.7, 14.7) == 0.1 + def test_min_floats(self): + assert min(0.1, 2.7, 14.7) == 0.1 - def test_min_chars(self): - assert min('a', 'b', 'c') == 'a' + def test_min_chars(self): + assert min('a', 'b', 'c') == 'a' - def test_min_strings(self): - assert min('aaa', 'bbb', 'c') == 'aaa' + def test_min_strings(self): + assert min('aaa', 'bbb', 'c') == 'aaa' - def test_min_mixed(self): - assert min('1', 2, 3, 'aa') == 2 + def test_min_mixed(self): + assert min('1', 2, 3, 'aa') == 2 - def test_min_noargs(self): - raises(TypeError, min) + def test_min_noargs(self): + raises(TypeError, min) - def test_min_empty(self): - raises(ValueError, min, []) + def test_min_empty(self): + raises(ValueError, min, []) class AppTestMax: - def test_max_notseq(self): - raises(TypeError, max, 1) + def test_max_notseq(self): + raises(TypeError, max, 1) - def test_max_usual(self): - assert max(1, 2, 3) == 3 + def test_max_usual(self): + assert max(1, 2, 3) == 3 - def test_max_floats(self): - assert max(0.1, 2.7, 14.7) == 14.7 + def test_max_floats(self): + assert max(0.1, 2.7, 14.7) == 14.7 - def test_max_chars(self): - assert max('a', 'b', 'c') == 'c' + def test_max_chars(self): + assert max('a', 'b', 'c') == 'c' - def test_max_strings(self): - assert max('aaa', 'bbb', 'c') == 'c' + def test_max_strings(self): + assert max('aaa', 'bbb', 'c') == 'c' - def test_max_mixed(self): - assert max('1', 2, 3, 'aa') == 'aa' + def test_max_mixed(self): + assert max('1', 2, 3, 'aa') == 'aa' - def test_max_noargs(self): - raises(TypeError, max) + def test_max_noargs(self): + raises(TypeError, max) - def test_max_empty(self): - raises(ValueError, max, []) + def test_max_empty(self): + raises(ValueError, max, []) class AppTestMaxTuple: - def test_max_usual(self): - assert max((1, 2, 3)) == 3 + def test_max_usual(self): + assert max((1, 2, 3)) == 3 - def test_max_floats(self): - assert max((0.1, 2.7, 14.7)) == 14.7 + def test_max_floats(self): + assert max((0.1, 2.7, 14.7)) == 14.7 - def test_max_chars(self): - assert max(('a', 'b', 'c')) == 'c' + def test_max_chars(self): + assert max(('a', 'b', 'c')) == 'c' - def test_max_strings(self): - assert max(('aaa', 'bbb', 'c')) == 'c' + def test_max_strings(self): + assert max(('aaa', 'bbb', 'c')) == 'c' - def test_max_mixed(self): - assert max(('1', 2, 3, 'aa')) == 'aa' + def test_max_mixed(self): + assert max(('1', 2, 3, 'aa')) == 'aa' class AppTestMinList: - def test_min_usual(self): - assert min([1, 2, 3]) == 1 + def test_min_usual(self): + assert min([1, 2, 3]) == 1 - def test_min_floats(self): - assert min([0.1, 2.7, 14.7]) == 0.1 + def test_min_floats(self): + assert min([0.1, 2.7, 14.7]) == 0.1 - def test_min_chars(self): - assert min(['a', 'b', 'c']) == 'a' + def test_min_chars(self): + assert min(['a', 'b', 'c']) == 'a' - def test_min_strings(self): - assert min(['aaa', 'bbb', 'c']) == 'aaa' + def test_min_strings(self): + assert min(['aaa', 'bbb', 'c']) == 'aaa' - def test_min_mixed(self): - assert min(['1', 2, 3, 'aa']) == 2 + def test_min_mixed(self): + assert min(['1', 2, 3, 'aa']) == 2 diff --git a/pypy/module/__builtin__/test/test_range.py b/pypy/module/__builtin__/test/test_range.py --- a/pypy/module/__builtin__/test/test_range.py +++ b/pypy/module/__builtin__/test/test_range.py @@ -1,112 +1,112 @@ class AppTestRange: - def test_range_toofew(self): - raises(TypeError, range) + def test_range_toofew(self): + raises(TypeError, range) - def test_range_toomany(self): - raises(TypeError, range, 1, 2, 3, 4) + def test_range_toomany(self): + raises(TypeError, range, 1, 2, 3, 4) - def test_range_one(self): - assert range(1) == [0] + def test_range_one(self): + assert range(1) == [0] - def test_range_posstartisstop(self): - assert range(1, 1) == [] + def test_range_posstartisstop(self): + assert range(1, 1) == [] - def test_range_negstartisstop(self): - assert range(-1, -1) == [] + def test_range_negstartisstop(self): + assert range(-1, -1) == [] - def test_range_zero(self): - assert range(0) == [] + def test_range_zero(self): + assert range(0) == [] - def test_range_twoargs(self): - assert range(1, 2) == [1] - - def test_range_decreasingtwoargs(self): - assert range(3, 1) == [] + def test_range_twoargs(self): + assert range(1, 2) == [1] - def test_range_negatives(self): - assert range(-3) == [] + def test_range_decreasingtwoargs(self): + assert range(3, 1) == [] - def test_range_decreasing_negativestep(self): - assert range(5, -2, -1) == [5, 4, 3, 2, 1, 0 , -1] + def test_range_negatives(self): + assert range(-3) == [] - def test_range_posfencepost1(self): - assert range (1, 10, 3) == [1, 4, 7] + def test_range_decreasing_negativestep(self): + assert range(5, -2, -1) == [5, 4, 3, 2, 1, 0 , -1] - def test_range_posfencepost2(self): - assert range (1, 11, 3) == [1, 4, 7, 10] + def test_range_posfencepost1(self): + assert range (1, 10, 3) == [1, 4, 7] - def test_range_posfencepost3(self): - assert range (1, 12, 3) == [1, 4, 7, 10] + def test_range_posfencepost2(self): + assert range (1, 11, 3) == [1, 4, 7, 10] - def test_range_negfencepost1(self): - assert range (-1, -10, -3) == [-1, -4, -7] + def test_range_posfencepost3(self): + assert range (1, 12, 3) == [1, 4, 7, 10] - def test_range_negfencepost2(self): - assert range (-1, -11, -3) == [-1, -4, -7, -10] + def test_range_negfencepost1(self): + assert range (-1, -10, -3) == [-1, -4, -7] - def test_range_negfencepost3(self): - assert range (-1, -12, -3) == [-1, -4, -7, -10] + def test_range_negfencepost2(self): + assert range (-1, -11, -3) == [-1, -4, -7, -10] - def test_range_decreasing_negativelargestep(self): - assert range(5, -2, -3) == [5, 2, -1] + def test_range_negfencepost3(self): + assert range (-1, -12, -3) == [-1, -4, -7, -10] - def test_range_increasing_positivelargestep(self): - assert range(-5, 2, 3) == [-5, -2, 1] + def test_range_decreasing_negativelargestep(self): + assert range(5, -2, -3) == [5, 2, -1] - def test_range_zerostep(self): - raises(ValueError, range, 1, 5, 0) + def test_range_increasing_positivelargestep(self): + assert range(-5, 2, 3) == [-5, -2, 1] - def test_range_float(self): - raises(TypeError, range, 0.1) - raises(TypeError, range, 0.1, 0) - raises(TypeError, range, 0, 0.1) - raises(TypeError, range, 0.1, 0, 0) - raises(TypeError, range, 0, 0.1, 0) - raises(TypeError, range, 0, 0, 0.1) + def test_range_zerostep(self): + raises(ValueError, range, 1, 5, 0) - def test_range_wrong_type(self): - raises(TypeError, range, "42") + def test_range_float(self): + raises(TypeError, range, 0.1) + raises(TypeError, range, 0.1, 0) + raises(TypeError, range, 0, 0.1) + raises(TypeError, range, 0.1, 0, 0) + raises(TypeError, range, 0, 0.1, 0) + raises(TypeError, range, 0, 0, 0.1) - def test_range_object_with___int__(self): - class A(object): - def __int__(self): - return 5 + def test_range_wrong_type(self): + raises(TypeError, range, "42") - assert range(A()) == [0, 1, 2, 3, 4] - assert range(0, A()) == [0, 1, 2, 3, 4] - assert range(0, 10, A()) == [0, 5] + def test_range_object_with___int__(self): + class A(object): + def __int__(self): + return 5 - def test_range_long(self): - import sys - assert range(-2**100) == [] - assert range(0, -2**100) == [] - assert range(0, 2**100, -1) == [] - assert range(0, 2**100, -1) == [] + assert range(A()) == [0, 1, 2, 3, 4] + assert range(0, A()) == [0, 1, 2, 3, 4] + assert range(0, 10, A()) == [0, 5] - a = long(10 * sys.maxint) - assert range(a, a+2) == [a, a+1] - assert range(a+2, a, -1L) == [a+2, a+1] - assert range(a+4, a, -2) == [a+4, a+2] - assert range(a, a*5, a) == [a, 2*a, 3*a, 4*a] + def test_range_long(self): + import sys + assert range(-2**100) == [] + assert range(0, -2**100) == [] + assert range(0, 2**100, -1) == [] + assert range(0, 2**100, -1) == [] - def test_range_cases(self): - import sys - for start in [10, 10 * sys.maxint]: - for stop in [start-4, start-1, start, start+1, start+4]: - for step in [1, 2, 3, 4]: - lst = range(start, stop, step) - expected = [] - a = start - while a < stop: - expected.append(a) - a += step - assert lst == expected - for step in [-1, -2, -3, -4]: - lst = range(start, stop, step) - expected = [] - a = start - while a > stop: - expected.append(a) - a += step - assert lst == expected + a = long(10 * sys.maxint) + assert range(a, a+2) == [a, a+1] + assert range(a+2, a, -1L) == [a+2, a+1] + assert range(a+4, a, -2) == [a+4, a+2] + assert range(a, a*5, a) == [a, 2*a, 3*a, 4*a] + + def test_range_cases(self): + import sys + for start in [10, 10 * sys.maxint]: + for stop in [start-4, start-1, start, start+1, start+4]: + for step in [1, 2, 3, 4]: + lst = range(start, stop, step) + expected = [] + a = start + while a < stop: + expected.append(a) + a += step + assert lst == expected + for step in [-1, -2, -3, -4]: + lst = range(start, stop, step) + expected = [] + a = start + while a > stop: + expected.append(a) + a += step + assert lst == expected diff --git a/pypy/module/__builtin__/test/test_reduce.py b/pypy/module/__builtin__/test/test_reduce.py --- a/pypy/module/__builtin__/test/test_reduce.py +++ b/pypy/module/__builtin__/test/test_reduce.py @@ -1,33 +1,32 @@ class AppTestReduce: - def test_None(self): - raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None) + def test_None(self): + raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None) - def test_sum(self): - assert reduce(lambda x, y: x+y, [1,2,3,4], 0) == 10 - assert reduce(lambda x, y: x+y, [1,2,3,4]) == 10 - - def test_minus(self): - assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0 - assert reduce(lambda x, y: x-y, [2, 8], 10) == 0 + def test_sum(self): + assert reduce(lambda x, y: x+y, [1,2,3,4], 0) == 10 + assert reduce(lambda x, y: x+y, [1,2,3,4]) == 10 - def test_from_cpython(self): - class SequenceClass(object): - def __init__(self, n): - self.n = n - def __getitem__(self, i): - if 0 <= i < self.n: - return i - else: - raise IndexError + def test_minus(self): + assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0 + assert reduce(lambda x, y: x-y, [2, 8], 10) == 0 - from operator import add - assert reduce(add, SequenceClass(5)) == 10 - assert reduce(add, SequenceClass(5), 42) == 52 - raises(TypeError, reduce, add, SequenceClass(0)) - assert reduce(add, SequenceClass(0), 42) == 42 - assert reduce(add, SequenceClass(1)) == 0 - assert reduce(add, SequenceClass(1), 42) == 42 - - d = {"one": 1, "two": 2, "three": 3} - assert reduce(add, d) == "".join(d.keys()) - + def test_from_cpython(self): + class SequenceClass(object): + def __init__(self, n): + self.n = n + def __getitem__(self, i): + if 0 <= i < self.n: + return i + else: + raise IndexError + + from operator import add + assert reduce(add, SequenceClass(5)) == 10 + assert reduce(add, SequenceClass(5), 42) == 52 + raises(TypeError, reduce, add, SequenceClass(0)) + assert reduce(add, SequenceClass(0), 42) == 42 + assert reduce(add, SequenceClass(1)) == 0 + assert reduce(add, SequenceClass(1), 42) == 42 + + d = {"one": 1, "two": 2, "three": 3} + assert reduce(add, d) == "".join(d.keys()) diff --git a/pypy/module/__builtin__/test/test_zip.py b/pypy/module/__builtin__/test/test_zip.py --- a/pypy/module/__builtin__/test/test_zip.py +++ b/pypy/module/__builtin__/test/test_zip.py @@ -1,36 +1,36 @@ class AppTestZip: - def test_zip_no_arguments(self): - import sys - if sys.version_info < (2,4): - # Test 2.3 behaviour - raises(TypeError, zip) - return - # Test 2.4 behaviour - assert zip() == [] - assert zip(*[]) == [] - - def test_one_list(self): - assert zip([1, 2, 3]) == [(1,), (2,), (3,)] + def test_zip_no_arguments(self): + import sys + if sys.version_info < (2,4): + # Test 2.3 behaviour + raises(TypeError, zip) + return + # Test 2.4 behaviour + assert zip() == [] + assert zip(*[]) == [] - def test_three_lists_same_size(self): - assert zip([1, 2, 3], [3, 4, 5], [6, 7, 8]) == ( - [(1, 3, 6), (2, 4, 7), (3, 5, 8)]) + def test_one_list(self): + assert zip([1, 2, 3]) == [(1,), (2,), (3,)] - def test_three_lists_different_sizes(self): - assert zip([1, 2], [3, 4, 5, 6], [6, 7, 8]) == ( - [(1, 3, 6), (2, 4, 7)]) + def test_three_lists_same_size(self): + assert zip([1, 2, 3], [3, 4, 5], [6, 7, 8]) == ( + [(1, 3, 6), (2, 4, 7), (3, 5, 8)]) - def test_tuples(self): - assert zip((1, 2, 3)) == [(1,), (2,), (3,)] + def test_three_lists_different_sizes(self): + assert zip([1, 2], [3, 4, 5, 6], [6, 7, 8]) == ( + [(1, 3, 6), (2, 4, 7)]) - def test_string(self): - assert zip('hello') == [('h',), ('e',), ('l',), ('l',), ('o',)] + def test_tuples(self): + assert zip((1, 2, 3)) == [(1,), (2,), (3,)] - def test_strings(self): - assert zip('hello', 'bye') == ( - [('h', 'b'), ('e', 'y'), ('l', 'e')]) + def test_string(self): + assert zip('hello') == [('h',), ('e',), ('l',), ('l',), ('o',)] - def test_mixed_types(self): - assert zip('hello', [1,2,3,4], (7,8,9,10)) == ( - [('h', 1, 7), ('e', 2, 8), ('l', 3, 9), ('l', 4, 10)]) + def test_strings(self): + assert zip('hello', 'bye') == ( + [('h', 'b'), ('e', 'y'), ('l', 'e')]) + + def test_mixed_types(self): + assert zip('hello', [1,2,3,4], (7,8,9,10)) == ( + [('h', 1, 7), ('e', 2, 8), ('l', 3, 9), ('l', 4, 10)]) From noreply at buildbot.pypy.org Thu Mar 7 21:57:43 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 21:57:43 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130307205743.9974A1C13E9@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62183:e5ccc3682887 Date: 2013-03-07 12:57 -0800 http://bitbucket.org/pypy/pypy/changeset/e5ccc3682887/ Log: merge default diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -5,6 +5,9 @@ # (nondist/sandbox/collections/pydeque.py rev 1.1, Raymond Hettinger) # +# Note that PyPy also contains a built-in module '_collections' which will hide +# this one if compiled in. + import operator try: from _thread import get_ident as _thread_ident diff --git a/pypy/module/__builtin__/test/test_filter.py b/pypy/module/__builtin__/test/test_filter.py --- a/pypy/module/__builtin__/test/test_filter.py +++ b/pypy/module/__builtin__/test/test_filter.py @@ -1,4 +1,4 @@ -# trivial functions for testing +# trivial functions for testing class AppTestFilter: def test_filter_no_arguments(self): diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -1,70 +1,70 @@ class AppTestMap: - def test_trivial_map_one_seq(self): - assert list(map(lambda x: x+2, [1, 2, 3, 4])) == [3, 4, 5, 6] + def test_trivial_map_one_seq(self): + assert list(map(lambda x: x+2, [1, 2, 3, 4])) == [3, 4, 5, 6] - def test_trivial_map_one_seq_2(self): - assert list(map(str, [1, 2, 3, 4])) == ['1', '2', '3', '4'] + def test_trivial_map_one_seq_2(self): + assert list(map(str, [1, 2, 3, 4])) == ['1', '2', '3', '4'] - def test_trivial_map_two_seq(self): - assert list(map(lambda x,y: x+y, - [1, 2, 3, 4],[1, 2, 3, 4])) == ( - [2, 4, 6, 8]) + def test_trivial_map_two_seq(self): + assert list(map(lambda x,y: x+y, + [1, 2, 3, 4],[1, 2, 3, 4])) == ( + [2, 4, 6, 8]) - def test_trivial_map_sizes_dont_match(self): - assert list(map(lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3])) == ( - [2, 4, 6]) + def test_trivial_map_sizes_dont_match(self): + assert list(map(lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3])) == ( + [2, 4, 6]) - def test_trivial_map_no_arguments(self): - raises(TypeError, map) + def test_trivial_map_no_arguments(self): + raises(TypeError, map) - def test_trivial_map_no_function_no_seq(self): - raises(TypeError, map, None) + def test_trivial_map_no_function_no_seq(self): + raises(TypeError, map, None) - def test_trivial_map_no_fuction(self): - m = map(None, [1, 2, 3]) # Don't crash here... - raises(TypeError, next, m) # ...but only on first item. + def test_trivial_map_no_fuction(self): + m = map(None, [1, 2, 3]) # Don't crash here... + raises(TypeError, next, m) # ...but only on first item. - def test_map_identity1(self): - a = ['1', 2, 3, 'b', None] - b = a[:] - assert list(map(lambda x: x, a)) == a - assert a == b + def test_map_identity1(self): + a = ['1', 2, 3, 'b', None] + b = a[:] + assert list(map(lambda x: x, a)) == a + assert a == b - def test_map_badoperation(self): - a = ['1', 2, 3, 'b', None] - raises(TypeError, list, map, lambda x: x+1, a) + def test_map_badoperation(self): + a = ['1', 2, 3, 'b', None] + raises(TypeError, list, map, lambda x: x+1, a) - def test_map_add(self): - a = [1, 2, 3, 4] - b = [0, 1, 1, 1] - assert list(map(lambda x, y: x+y, a, b)) == [1, 3, 4, 5] + def test_map_add(self): + a = [1, 2, 3, 4] + b = [0, 1, 1, 1] + assert list(map(lambda x, y: x+y, a, b)) == [1, 3, 4, 5] - def test_map_first_item(self): - a = [1, 2, 3, 4, 5] - b = [6, 7, 8, 9, 10] - assert list(map(lambda x, y: x, a, b)) == a + def test_map_first_item(self): + a = [1, 2, 3, 4, 5] + b = [6, 7, 8, 9, 10] + assert list(map(lambda x, y: x, a, b)) == a - def test_map_iterables(self): - class A(object): - def __init__(self, n): - self.n = n - def __iter__(self): - return B(self.n) - class B(object): - def __init__(self, n): - self.n = n - def __next__(self): - self.n -= 1 - if self.n == 0: raise StopIteration - return self.n - result = map(lambda *x:x, A(3), A(8)) - # this also checks that B.next() is not called any more after it - # raised StopIteration once - assert list(result) == [(2, 7), (1, 6)] + def test_map_iterables(self): + class A(object): + def __init__(self, n): + self.n = n + def __iter__(self): + return B(self.n) + class B(object): + def __init__(self, n): + self.n = n + def __next__(self): + self.n -= 1 + if self.n == 0: raise StopIteration + return self.n + result = map(lambda *x:x, A(3), A(8)) + # this also checks that B.next() is not called any more after it + # raised StopIteration once + assert list(result) == [(2, 7), (1, 6)] - def test_repr(self): - assert repr(map(1, [2])).startswith(' stop: - expected.append(a) - a += step - assert lst == expected + def test_range_cases(self): + import sys + for start in [10, 10 * sys.maxsize]: + for stop in [start-4, start-1, start, start+1, start+4]: + for step in [1, 2, 3, 4]: + lst = list(range(start, stop, step)) + expected = [] + a = start + while a < stop: + expected.append(a) + a += step + assert lst == expected + for step in [-1, -2, -3, -4]: + lst = list(range(start, stop, step)) + expected = [] + a = start + while a > stop: + expected.append(a) + a += step + assert lst == expected - def test_range_contains(self): - assert 3 in range(5) - assert 3 not in range(3) - assert 3 not in range(4, 5) - assert 3 in range(1, 5, 2) - assert 3 not in range(0, 5, 2) - assert '3' not in range(5) + def test_range_contains(self): + assert 3 in range(5) + assert 3 not in range(3) + assert 3 not in range(4, 5) + assert 3 in range(1, 5, 2) + assert 3 not in range(0, 5, 2) + assert '3' not in range(5) - def test_range_count(self): - assert range(5).count(3) == 1 - assert type(range(5).count(3)) is int - assert range(0, 5, 2).count(3) == 0 - assert range(5).count(3.0) == 1 - assert range(5).count('3') == 0 + def test_range_count(self): + assert range(5).count(3) == 1 + assert type(range(5).count(3)) is int + assert range(0, 5, 2).count(3) == 0 + assert range(5).count(3.0) == 1 + assert range(5).count('3') == 0 - def test_range_getitem(self): - assert range(6)[3] == 3 - assert range(6)[-1] == 5 - raises(IndexError, range(6).__getitem__, 6) + def test_range_getitem(self): + assert range(6)[3] == 3 + assert range(6)[-1] == 5 + raises(IndexError, range(6).__getitem__, 6) - def test_range_slice(self): - # range objects don't implement equality in 3.2, use the repr - assert repr(range(6)[2:5]) == 'range(2, 5)' - assert repr(range(6)[-1:-3:-2]) == 'range(5, 3, -2)' + def test_range_slice(self): + # range objects don't implement equality in 3.2, use the repr + assert repr(range(6)[2:5]) == 'range(2, 5)' + assert repr(range(6)[-1:-3:-2]) == 'range(5, 3, -2)' - def test_large_range(self): - import sys - def _range_len(x): - try: - length = len(x) - except OverflowError: - step = x[1] - x[0] - length = 1 + ((x[-1] - x[0]) // step) - return length - a = -sys.maxsize - b = sys.maxsize - expected_len = b - a - x = range(a, b) - assert a in x - assert b not in x - raises(OverflowError, len, x) - assert _range_len(x) == expected_len + def test_large_range(self): + import sys + def _range_len(x): + try: + length = len(x) + except OverflowError: + step = x[1] - x[0] + length = 1 + ((x[-1] - x[0]) // step) + return length + a = -sys.maxsize + b = sys.maxsize + expected_len = b - a + x = range(a, b) + assert a in x + assert b not in x + raises(OverflowError, len, x) + assert _range_len(x) == expected_len - def test_range_reduce(self): - x = range(2, 9, 3) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_range_reduce(self): + x = range(2, 9, 3) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_range_iter_reduce(self): - x = iter(range(2, 9, 3)) - next(x) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_range_iter_reduce(self): + x = iter(range(2, 9, 3)) + next(x) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_range_iter_reduce_one(self): - x = iter(range(2, 9)) - next(x) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_range_iter_reduce_one(self): + x = iter(range(2, 9)) + next(x) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_lib_python_range_optimization(self): - x = range(1) - assert type(reversed(x)) == type(iter(x)) + def test_lib_python_range_optimization(self): + x = range(1) + assert type(reversed(x)) == type(iter(x)) class AppTestReversed: - def test_reversed(self): - r = reversed("hello") - assert iter(r) is r - assert r.__next__() == "o" - assert r.__next__() == "l" - assert r.__next__() == "l" - assert r.__next__() == "e" - assert r.__next__() == "h" - raises(StopIteration, r.__next__) - assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] - raises(TypeError, reversed, reversed("hello")) + def test_reversed(self): + r = reversed("hello") + assert iter(r) is r + assert r.__next__() == "o" + assert r.__next__() == "l" + assert r.__next__() == "l" + assert r.__next__() == "e" + assert r.__next__() == "h" + raises(StopIteration, r.__next__) + assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] + raises(TypeError, reversed, reversed("hello")) class AppTestAllAny: """ @@ -434,16 +434,16 @@ assert any([x > 42 for x in S]) == False class AppTestMinMax: - def test_min(self): - assert min(1, 2) == 1 - assert min(1, 2, key=lambda x: -x) == 2 - assert min([1, 2, 3]) == 1 - raises(TypeError, min, 1, 2, bar=2) - raises(TypeError, min, 1, 2, key=lambda x: x, bar=2) + def test_min(self): + assert min(1, 2) == 1 + assert min(1, 2, key=lambda x: -x) == 2 + assert min([1, 2, 3]) == 1 + raises(TypeError, min, 1, 2, bar=2) + raises(TypeError, min, 1, 2, key=lambda x: x, bar=2) - def test_max(self): - assert max(1, 2) == 2 - assert max(1, 2, key=lambda x: -x) == 1 - assert max([1, 2, 3]) == 3 - raises(TypeError, max, 1, 2, bar=2) - raises(TypeError, max, 1, 2, key=lambda x: x, bar=2) + def test_max(self): + assert max(1, 2) == 2 + assert max(1, 2, key=lambda x: -x) == 1 + assert max([1, 2, 3]) == 3 + raises(TypeError, max, 1, 2, bar=2) + raises(TypeError, max, 1, 2, key=lambda x: x, bar=2) diff --git a/pypy/module/__builtin__/test/test_minmax.py b/pypy/module/__builtin__/test/test_minmax.py --- a/pypy/module/__builtin__/test/test_minmax.py +++ b/pypy/module/__builtin__/test/test_minmax.py @@ -1,73 +1,73 @@ class AppTestMin: - def test_min_notseq(self): - raises(TypeError, min, 1) + def test_min_notseq(self): + raises(TypeError, min, 1) - def test_min_usual(self): - assert min(1, 2, 3) == 1 + def test_min_usual(self): + assert min(1, 2, 3) == 1 - def test_min_floats(self): - assert min(0.1, 2.7, 14.7) == 0.1 + def test_min_floats(self): + assert min(0.1, 2.7, 14.7) == 0.1 - def test_min_chars(self): - assert min('a', 'b', 'c') == 'a' + def test_min_chars(self): + assert min('a', 'b', 'c') == 'a' - def test_min_strings(self): - assert min('aaa', 'bbb', 'c') == 'aaa' + def test_min_strings(self): + assert min('aaa', 'bbb', 'c') == 'aaa' - def test_min_noargs(self): - raises(TypeError, min) + def test_min_noargs(self): + raises(TypeError, min) - def test_min_empty(self): - raises(ValueError, min, []) + def test_min_empty(self): + raises(ValueError, min, []) class AppTestMax: - def test_max_notseq(self): - raises(TypeError, max, 1) + def test_max_notseq(self): + raises(TypeError, max, 1) - def test_max_usual(self): - assert max(1, 2, 3) == 3 + def test_max_usual(self): + assert max(1, 2, 3) == 3 - def test_max_floats(self): - assert max(0.1, 2.7, 14.7) == 14.7 + def test_max_floats(self): + assert max(0.1, 2.7, 14.7) == 14.7 - def test_max_chars(self): - assert max('a', 'b', 'c') == 'c' + def test_max_chars(self): + assert max('a', 'b', 'c') == 'c' - def test_max_strings(self): - assert max('aaa', 'bbb', 'c') == 'c' + def test_max_strings(self): + assert max('aaa', 'bbb', 'c') == 'c' - def test_max_noargs(self): - raises(TypeError, max) + def test_max_noargs(self): + raises(TypeError, max) - def test_max_empty(self): - raises(ValueError, max, []) + def test_max_empty(self): + raises(ValueError, max, []) class AppTestMaxTuple: - def test_max_usual(self): - assert max((1, 2, 3)) == 3 + def test_max_usual(self): + assert max((1, 2, 3)) == 3 - def test_max_floats(self): - assert max((0.1, 2.7, 14.7)) == 14.7 + def test_max_floats(self): + assert max((0.1, 2.7, 14.7)) == 14.7 - def test_max_chars(self): - assert max(('a', 'b', 'c')) == 'c' + def test_max_chars(self): + assert max(('a', 'b', 'c')) == 'c' - def test_max_strings(self): - assert max(('aaa', 'bbb', 'c')) == 'c' + def test_max_strings(self): + assert max(('aaa', 'bbb', 'c')) == 'c' class AppTestMinList: - def test_min_usual(self): - assert min([1, 2, 3]) == 1 + def test_min_usual(self): + assert min([1, 2, 3]) == 1 - def test_min_floats(self): - assert min([0.1, 2.7, 14.7]) == 0.1 + def test_min_floats(self): + assert min([0.1, 2.7, 14.7]) == 0.1 - def test_min_chars(self): - assert min(['a', 'b', 'c']) == 'a' + def test_min_chars(self): + assert min(['a', 'b', 'c']) == 'a' - def test_min_strings(self): - assert min(['aaa', 'bbb', 'c']) == 'aaa' + def test_min_strings(self): + assert min(['aaa', 'bbb', 'c']) == 'aaa' diff --git a/pypy/module/__builtin__/test/test_zip.py b/pypy/module/__builtin__/test/test_zip.py --- a/pypy/module/__builtin__/test/test_zip.py +++ b/pypy/module/__builtin__/test/test_zip.py @@ -1,39 +1,39 @@ class AppTestZip: - def test_zip_no_arguments(self): - import sys - if sys.version_info < (2,4): - # Test 2.3 behaviour - raises(TypeError, zip) - else: - # Test 2.4 behaviour - assert list(zip()) == [] - assert list(zip(*[])) == [] - - def test_one_list(self): - assert list(zip([1, 2, 3])) == [(1,), (2,), (3,)] + def test_zip_no_arguments(self): + import sys + if sys.version_info < (2,4): + # Test 2.3 behaviour + raises(TypeError, zip) + else: + # Test 2.4 behaviour + assert list(zip()) == [] + assert list(zip(*[])) == [] - def test_three_lists_same_size(self): - assert list(zip([1, 2, 3], [3, 4, 5], [6, 7, 8])) == ( - [(1, 3, 6), (2, 4, 7), (3, 5, 8)]) + def test_one_list(self): + assert list(zip([1, 2, 3])) == [(1,), (2,), (3,)] - def test_three_lists_different_sizes(self): - assert list(zip([1, 2], [3, 4, 5, 6], [6, 7, 8])) == ( - [(1, 3, 6), (2, 4, 7)]) + def test_three_lists_same_size(self): + assert list(zip([1, 2, 3], [3, 4, 5], [6, 7, 8])) == ( + [(1, 3, 6), (2, 4, 7), (3, 5, 8)]) - def test_tuples(self): - assert list(zip((1, 2, 3))) == [(1,), (2,), (3,)] + def test_three_lists_different_sizes(self): + assert list(zip([1, 2], [3, 4, 5, 6], [6, 7, 8])) == ( + [(1, 3, 6), (2, 4, 7)]) - def test_string(self): - assert list(zip('hello')) == [('h',), ('e',), ('l',), ('l',), ('o',)] + def test_tuples(self): + assert list(zip((1, 2, 3))) == [(1,), (2,), (3,)] - def test_strings(self): - assert list(zip('hello', 'bye')) == ( - [('h', 'b'), ('e', 'y'), ('l', 'e')]) + def test_string(self): + assert list(zip('hello')) == [('h',), ('e',), ('l',), ('l',), ('o',)] - def test_mixed_types(self): - assert list(zip('hello', [1,2,3,4], (7,8,9,10))) == ( - [('h', 1, 7), ('e', 2, 8), ('l', 3, 9), ('l', 4, 10)]) + def test_strings(self): + assert list(zip('hello', 'bye')) == ( + [('h', 'b'), ('e', 'y'), ('l', 'e')]) + + def test_mixed_types(self): + assert list(zip('hello', [1,2,3,4], (7,8,9,10))) == ( + [('h', 1, 7), ('e', 2, 8), ('l', 3, 9), ('l', 4, 10)]) class AppTestZip2: def test_zip(self): @@ -45,11 +45,11 @@ for x in obj_list: assert next(it) == (x, ) raises(StopIteration, next, it) - + it = zip([1, 2, 3], [4], [5, 6]) assert next(it) == (1, 4, 5) raises(StopIteration, next, it) - + it = zip([], [], [1], []) raises(StopIteration, next, it) @@ -78,4 +78,3 @@ assert str(e).find("#" + str(x + 1) + " ") >= 0 else: fail("TypeError expected") - From noreply at buildbot.pypy.org Thu Mar 7 22:12:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 22:12:06 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for sqlite cursor iteration, simplify/optimize Message-ID: <20130307211206.CD3881C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62184:7e1f21fd7d13 Date: 2013-03-07 15:27 -0500 http://bitbucket.org/pypy/pypy/changeset/7e1f21fd7d13/ Log: test and fix for sqlite cursor iteration, simplify/optimize diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -919,24 +919,24 @@ "Cursor needed to be reset because of commit/rollback " "and can no longer be fetched from.") - # do all statements - def fetchone(self): + def __iter__(self): + return self + + def __next__(self): self.__check_cursor() self.__check_reset() + if not self.__statement: + raise StopIteration + return self.__statement._next(self) - if self.__statement is None: - return None + if sys.version_info[0] < 3: + next = __next__ + del __next__ - try: - return self.__statement._next(self) - except StopIteration: - return None + def fetchone(self): + return next(self, None) def fetchmany(self, size=None): - self.__check_cursor() - self.__check_reset() - if self.__statement is None: - return [] if size is None: size = self.arraysize lst = [] @@ -947,15 +947,8 @@ return lst def fetchall(self): - self.__check_cursor() - self.__check_reset() - if self.__statement is None: - return [] return list(self) - def __iter__(self): - return iter(self.fetchone, None) - def __get_connection(self): return self.__connection connection = property(__get_connection) 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 @@ -52,6 +52,16 @@ # raises ProgrammingError because should check closed before check args pytest.raises(_sqlite3.ProgrammingError, "con()") +def test_cursor_iter(): + con = _sqlite3.connect(':memory:') + cur = con.cursor() + with pytest.raises(StopIteration): + next(cur) + cur = con.execute('select 1') + next(cur) + with pytest.raises(StopIteration): + next(cur) + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') From noreply at buildbot.pypy.org Thu Mar 7 22:12:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 22:12:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130307211208.2E9C81C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62185:11bcfe197e41 Date: 2013-03-07 16:09 -0500 http://bitbucket.org/pypy/pypy/changeset/11bcfe197e41/ Log: merge default diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -5,6 +5,9 @@ # (nondist/sandbox/collections/pydeque.py rev 1.1, Raymond Hettinger) # +# Note that PyPy also contains a built-in module '_collections' which will hide +# this one if compiled in. + import operator try: from _thread import get_ident as _thread_ident diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -919,24 +919,24 @@ "Cursor needed to be reset because of commit/rollback " "and can no longer be fetched from.") - # do all statements - def fetchone(self): + def __iter__(self): + return self + + def __next__(self): self.__check_cursor() self.__check_reset() + if not self.__statement: + raise StopIteration + return self.__statement._next(self) - if self.__statement is None: - return None + if sys.version_info[0] < 3: + next = __next__ + del __next__ - try: - return self.__statement._next(self) - except StopIteration: - return None + def fetchone(self): + return next(self, None) def fetchmany(self, size=None): - self.__check_cursor() - self.__check_reset() - if self.__statement is None: - return [] if size is None: size = self.arraysize lst = [] @@ -947,15 +947,8 @@ return lst def fetchall(self): - self.__check_cursor() - self.__check_reset() - if self.__statement is None: - return [] return list(self) - def __iter__(self): - return iter(self.fetchone, None) - def __get_connection(self): return self.__connection connection = property(__get_connection) 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 @@ -52,6 +52,16 @@ # raises ProgrammingError because should check closed before check args pytest.raises(_sqlite3.ProgrammingError, "con()") +def test_cursor_iter(): + con = _sqlite3.connect(':memory:') + cur = con.cursor() + with pytest.raises(StopIteration): + next(cur) + cur = con.execute('select 1') + next(cur) + with pytest.raises(StopIteration): + next(cur) + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') From noreply at buildbot.pypy.org Thu Mar 7 22:12:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 22:12:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130307211209.6C3A61C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62186:46a5efb3dae1 Date: 2013-03-07 16:11 -0500 http://bitbucket.org/pypy/pypy/changeset/46a5efb3dae1/ Log: merge heads diff --git a/pypy/module/__builtin__/test/test_filter.py b/pypy/module/__builtin__/test/test_filter.py --- a/pypy/module/__builtin__/test/test_filter.py +++ b/pypy/module/__builtin__/test/test_filter.py @@ -1,4 +1,4 @@ -# trivial functions for testing +# trivial functions for testing class AppTestFilter: def test_filter_no_arguments(self): diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -1,70 +1,70 @@ class AppTestMap: - def test_trivial_map_one_seq(self): - assert list(map(lambda x: x+2, [1, 2, 3, 4])) == [3, 4, 5, 6] + def test_trivial_map_one_seq(self): + assert list(map(lambda x: x+2, [1, 2, 3, 4])) == [3, 4, 5, 6] - def test_trivial_map_one_seq_2(self): - assert list(map(str, [1, 2, 3, 4])) == ['1', '2', '3', '4'] + def test_trivial_map_one_seq_2(self): + assert list(map(str, [1, 2, 3, 4])) == ['1', '2', '3', '4'] - def test_trivial_map_two_seq(self): - assert list(map(lambda x,y: x+y, - [1, 2, 3, 4],[1, 2, 3, 4])) == ( - [2, 4, 6, 8]) + def test_trivial_map_two_seq(self): + assert list(map(lambda x,y: x+y, + [1, 2, 3, 4],[1, 2, 3, 4])) == ( + [2, 4, 6, 8]) - def test_trivial_map_sizes_dont_match(self): - assert list(map(lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3])) == ( - [2, 4, 6]) + def test_trivial_map_sizes_dont_match(self): + assert list(map(lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3])) == ( + [2, 4, 6]) - def test_trivial_map_no_arguments(self): - raises(TypeError, map) + def test_trivial_map_no_arguments(self): + raises(TypeError, map) - def test_trivial_map_no_function_no_seq(self): - raises(TypeError, map, None) + def test_trivial_map_no_function_no_seq(self): + raises(TypeError, map, None) - def test_trivial_map_no_fuction(self): - m = map(None, [1, 2, 3]) # Don't crash here... - raises(TypeError, next, m) # ...but only on first item. + def test_trivial_map_no_fuction(self): + m = map(None, [1, 2, 3]) # Don't crash here... + raises(TypeError, next, m) # ...but only on first item. - def test_map_identity1(self): - a = ['1', 2, 3, 'b', None] - b = a[:] - assert list(map(lambda x: x, a)) == a - assert a == b + def test_map_identity1(self): + a = ['1', 2, 3, 'b', None] + b = a[:] + assert list(map(lambda x: x, a)) == a + assert a == b - def test_map_badoperation(self): - a = ['1', 2, 3, 'b', None] - raises(TypeError, list, map, lambda x: x+1, a) + def test_map_badoperation(self): + a = ['1', 2, 3, 'b', None] + raises(TypeError, list, map, lambda x: x+1, a) - def test_map_add(self): - a = [1, 2, 3, 4] - b = [0, 1, 1, 1] - assert list(map(lambda x, y: x+y, a, b)) == [1, 3, 4, 5] + def test_map_add(self): + a = [1, 2, 3, 4] + b = [0, 1, 1, 1] + assert list(map(lambda x, y: x+y, a, b)) == [1, 3, 4, 5] - def test_map_first_item(self): - a = [1, 2, 3, 4, 5] - b = [6, 7, 8, 9, 10] - assert list(map(lambda x, y: x, a, b)) == a + def test_map_first_item(self): + a = [1, 2, 3, 4, 5] + b = [6, 7, 8, 9, 10] + assert list(map(lambda x, y: x, a, b)) == a - def test_map_iterables(self): - class A(object): - def __init__(self, n): - self.n = n - def __iter__(self): - return B(self.n) - class B(object): - def __init__(self, n): - self.n = n - def __next__(self): - self.n -= 1 - if self.n == 0: raise StopIteration - return self.n - result = map(lambda *x:x, A(3), A(8)) - # this also checks that B.next() is not called any more after it - # raised StopIteration once - assert list(result) == [(2, 7), (1, 6)] + def test_map_iterables(self): + class A(object): + def __init__(self, n): + self.n = n + def __iter__(self): + return B(self.n) + class B(object): + def __init__(self, n): + self.n = n + def __next__(self): + self.n -= 1 + if self.n == 0: raise StopIteration + return self.n + result = map(lambda *x:x, A(3), A(8)) + # this also checks that B.next() is not called any more after it + # raised StopIteration once + assert list(result) == [(2, 7), (1, 6)] - def test_repr(self): - assert repr(map(1, [2])).startswith(' stop: - expected.append(a) - a += step - assert lst == expected + def test_range_cases(self): + import sys + for start in [10, 10 * sys.maxsize]: + for stop in [start-4, start-1, start, start+1, start+4]: + for step in [1, 2, 3, 4]: + lst = list(range(start, stop, step)) + expected = [] + a = start + while a < stop: + expected.append(a) + a += step + assert lst == expected + for step in [-1, -2, -3, -4]: + lst = list(range(start, stop, step)) + expected = [] + a = start + while a > stop: + expected.append(a) + a += step + assert lst == expected - def test_range_contains(self): - assert 3 in range(5) - assert 3 not in range(3) - assert 3 not in range(4, 5) - assert 3 in range(1, 5, 2) - assert 3 not in range(0, 5, 2) - assert '3' not in range(5) + def test_range_contains(self): + assert 3 in range(5) + assert 3 not in range(3) + assert 3 not in range(4, 5) + assert 3 in range(1, 5, 2) + assert 3 not in range(0, 5, 2) + assert '3' not in range(5) - def test_range_count(self): - assert range(5).count(3) == 1 - assert type(range(5).count(3)) is int - assert range(0, 5, 2).count(3) == 0 - assert range(5).count(3.0) == 1 - assert range(5).count('3') == 0 + def test_range_count(self): + assert range(5).count(3) == 1 + assert type(range(5).count(3)) is int + assert range(0, 5, 2).count(3) == 0 + assert range(5).count(3.0) == 1 + assert range(5).count('3') == 0 - def test_range_getitem(self): - assert range(6)[3] == 3 - assert range(6)[-1] == 5 - raises(IndexError, range(6).__getitem__, 6) + def test_range_getitem(self): + assert range(6)[3] == 3 + assert range(6)[-1] == 5 + raises(IndexError, range(6).__getitem__, 6) - def test_range_slice(self): - # range objects don't implement equality in 3.2, use the repr - assert repr(range(6)[2:5]) == 'range(2, 5)' - assert repr(range(6)[-1:-3:-2]) == 'range(5, 3, -2)' + def test_range_slice(self): + # range objects don't implement equality in 3.2, use the repr + assert repr(range(6)[2:5]) == 'range(2, 5)' + assert repr(range(6)[-1:-3:-2]) == 'range(5, 3, -2)' - def test_large_range(self): - import sys - def _range_len(x): - try: - length = len(x) - except OverflowError: - step = x[1] - x[0] - length = 1 + ((x[-1] - x[0]) // step) - return length - a = -sys.maxsize - b = sys.maxsize - expected_len = b - a - x = range(a, b) - assert a in x - assert b not in x - raises(OverflowError, len, x) - assert _range_len(x) == expected_len + def test_large_range(self): + import sys + def _range_len(x): + try: + length = len(x) + except OverflowError: + step = x[1] - x[0] + length = 1 + ((x[-1] - x[0]) // step) + return length + a = -sys.maxsize + b = sys.maxsize + expected_len = b - a + x = range(a, b) + assert a in x + assert b not in x + raises(OverflowError, len, x) + assert _range_len(x) == expected_len - def test_range_reduce(self): - x = range(2, 9, 3) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_range_reduce(self): + x = range(2, 9, 3) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_range_iter_reduce(self): - x = iter(range(2, 9, 3)) - next(x) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_range_iter_reduce(self): + x = iter(range(2, 9, 3)) + next(x) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_range_iter_reduce_one(self): - x = iter(range(2, 9)) - next(x) - callable, args = x.__reduce__() - y = callable(*args) - assert list(y) == list(x) + def test_range_iter_reduce_one(self): + x = iter(range(2, 9)) + next(x) + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) - def test_lib_python_range_optimization(self): - x = range(1) - assert type(reversed(x)) == type(iter(x)) + def test_lib_python_range_optimization(self): + x = range(1) + assert type(reversed(x)) == type(iter(x)) class AppTestReversed: - def test_reversed(self): - r = reversed("hello") - assert iter(r) is r - assert r.__next__() == "o" - assert r.__next__() == "l" - assert r.__next__() == "l" - assert r.__next__() == "e" - assert r.__next__() == "h" - raises(StopIteration, r.__next__) - assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] - raises(TypeError, reversed, reversed("hello")) + def test_reversed(self): + r = reversed("hello") + assert iter(r) is r + assert r.__next__() == "o" + assert r.__next__() == "l" + assert r.__next__() == "l" + assert r.__next__() == "e" + assert r.__next__() == "h" + raises(StopIteration, r.__next__) + assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] + raises(TypeError, reversed, reversed("hello")) class AppTestAllAny: """ @@ -434,16 +434,16 @@ assert any([x > 42 for x in S]) == False class AppTestMinMax: - def test_min(self): - assert min(1, 2) == 1 - assert min(1, 2, key=lambda x: -x) == 2 - assert min([1, 2, 3]) == 1 - raises(TypeError, min, 1, 2, bar=2) - raises(TypeError, min, 1, 2, key=lambda x: x, bar=2) + def test_min(self): + assert min(1, 2) == 1 + assert min(1, 2, key=lambda x: -x) == 2 + assert min([1, 2, 3]) == 1 + raises(TypeError, min, 1, 2, bar=2) + raises(TypeError, min, 1, 2, key=lambda x: x, bar=2) - def test_max(self): - assert max(1, 2) == 2 - assert max(1, 2, key=lambda x: -x) == 1 - assert max([1, 2, 3]) == 3 - raises(TypeError, max, 1, 2, bar=2) - raises(TypeError, max, 1, 2, key=lambda x: x, bar=2) + def test_max(self): + assert max(1, 2) == 2 + assert max(1, 2, key=lambda x: -x) == 1 + assert max([1, 2, 3]) == 3 + raises(TypeError, max, 1, 2, bar=2) + raises(TypeError, max, 1, 2, key=lambda x: x, bar=2) diff --git a/pypy/module/__builtin__/test/test_minmax.py b/pypy/module/__builtin__/test/test_minmax.py --- a/pypy/module/__builtin__/test/test_minmax.py +++ b/pypy/module/__builtin__/test/test_minmax.py @@ -1,73 +1,73 @@ class AppTestMin: - def test_min_notseq(self): - raises(TypeError, min, 1) + def test_min_notseq(self): + raises(TypeError, min, 1) - def test_min_usual(self): - assert min(1, 2, 3) == 1 + def test_min_usual(self): + assert min(1, 2, 3) == 1 - def test_min_floats(self): - assert min(0.1, 2.7, 14.7) == 0.1 + def test_min_floats(self): + assert min(0.1, 2.7, 14.7) == 0.1 - def test_min_chars(self): - assert min('a', 'b', 'c') == 'a' + def test_min_chars(self): + assert min('a', 'b', 'c') == 'a' - def test_min_strings(self): - assert min('aaa', 'bbb', 'c') == 'aaa' + def test_min_strings(self): + assert min('aaa', 'bbb', 'c') == 'aaa' - def test_min_noargs(self): - raises(TypeError, min) + def test_min_noargs(self): + raises(TypeError, min) - def test_min_empty(self): - raises(ValueError, min, []) + def test_min_empty(self): + raises(ValueError, min, []) class AppTestMax: - def test_max_notseq(self): - raises(TypeError, max, 1) + def test_max_notseq(self): + raises(TypeError, max, 1) - def test_max_usual(self): - assert max(1, 2, 3) == 3 + def test_max_usual(self): + assert max(1, 2, 3) == 3 - def test_max_floats(self): - assert max(0.1, 2.7, 14.7) == 14.7 + def test_max_floats(self): + assert max(0.1, 2.7, 14.7) == 14.7 - def test_max_chars(self): - assert max('a', 'b', 'c') == 'c' + def test_max_chars(self): + assert max('a', 'b', 'c') == 'c' - def test_max_strings(self): - assert max('aaa', 'bbb', 'c') == 'c' + def test_max_strings(self): + assert max('aaa', 'bbb', 'c') == 'c' - def test_max_noargs(self): - raises(TypeError, max) + def test_max_noargs(self): + raises(TypeError, max) - def test_max_empty(self): - raises(ValueError, max, []) + def test_max_empty(self): + raises(ValueError, max, []) class AppTestMaxTuple: - def test_max_usual(self): - assert max((1, 2, 3)) == 3 + def test_max_usual(self): + assert max((1, 2, 3)) == 3 - def test_max_floats(self): - assert max((0.1, 2.7, 14.7)) == 14.7 + def test_max_floats(self): + assert max((0.1, 2.7, 14.7)) == 14.7 - def test_max_chars(self): - assert max(('a', 'b', 'c')) == 'c' + def test_max_chars(self): + assert max(('a', 'b', 'c')) == 'c' - def test_max_strings(self): - assert max(('aaa', 'bbb', 'c')) == 'c' + def test_max_strings(self): + assert max(('aaa', 'bbb', 'c')) == 'c' class AppTestMinList: - def test_min_usual(self): - assert min([1, 2, 3]) == 1 + def test_min_usual(self): + assert min([1, 2, 3]) == 1 - def test_min_floats(self): - assert min([0.1, 2.7, 14.7]) == 0.1 + def test_min_floats(self): + assert min([0.1, 2.7, 14.7]) == 0.1 - def test_min_chars(self): - assert min(['a', 'b', 'c']) == 'a' + def test_min_chars(self): + assert min(['a', 'b', 'c']) == 'a' - def test_min_strings(self): - assert min(['aaa', 'bbb', 'c']) == 'aaa' + def test_min_strings(self): + assert min(['aaa', 'bbb', 'c']) == 'aaa' diff --git a/pypy/module/__builtin__/test/test_zip.py b/pypy/module/__builtin__/test/test_zip.py --- a/pypy/module/__builtin__/test/test_zip.py +++ b/pypy/module/__builtin__/test/test_zip.py @@ -1,39 +1,39 @@ class AppTestZip: - def test_zip_no_arguments(self): - import sys - if sys.version_info < (2,4): - # Test 2.3 behaviour - raises(TypeError, zip) - else: - # Test 2.4 behaviour - assert list(zip()) == [] - assert list(zip(*[])) == [] - - def test_one_list(self): - assert list(zip([1, 2, 3])) == [(1,), (2,), (3,)] + def test_zip_no_arguments(self): + import sys + if sys.version_info < (2,4): + # Test 2.3 behaviour + raises(TypeError, zip) + else: + # Test 2.4 behaviour + assert list(zip()) == [] + assert list(zip(*[])) == [] - def test_three_lists_same_size(self): - assert list(zip([1, 2, 3], [3, 4, 5], [6, 7, 8])) == ( - [(1, 3, 6), (2, 4, 7), (3, 5, 8)]) + def test_one_list(self): + assert list(zip([1, 2, 3])) == [(1,), (2,), (3,)] - def test_three_lists_different_sizes(self): - assert list(zip([1, 2], [3, 4, 5, 6], [6, 7, 8])) == ( - [(1, 3, 6), (2, 4, 7)]) + def test_three_lists_same_size(self): + assert list(zip([1, 2, 3], [3, 4, 5], [6, 7, 8])) == ( + [(1, 3, 6), (2, 4, 7), (3, 5, 8)]) - def test_tuples(self): - assert list(zip((1, 2, 3))) == [(1,), (2,), (3,)] + def test_three_lists_different_sizes(self): + assert list(zip([1, 2], [3, 4, 5, 6], [6, 7, 8])) == ( + [(1, 3, 6), (2, 4, 7)]) - def test_string(self): - assert list(zip('hello')) == [('h',), ('e',), ('l',), ('l',), ('o',)] + def test_tuples(self): + assert list(zip((1, 2, 3))) == [(1,), (2,), (3,)] - def test_strings(self): - assert list(zip('hello', 'bye')) == ( - [('h', 'b'), ('e', 'y'), ('l', 'e')]) + def test_string(self): + assert list(zip('hello')) == [('h',), ('e',), ('l',), ('l',), ('o',)] - def test_mixed_types(self): - assert list(zip('hello', [1,2,3,4], (7,8,9,10))) == ( - [('h', 1, 7), ('e', 2, 8), ('l', 3, 9), ('l', 4, 10)]) + def test_strings(self): + assert list(zip('hello', 'bye')) == ( + [('h', 'b'), ('e', 'y'), ('l', 'e')]) + + def test_mixed_types(self): + assert list(zip('hello', [1,2,3,4], (7,8,9,10))) == ( + [('h', 1, 7), ('e', 2, 8), ('l', 3, 9), ('l', 4, 10)]) class AppTestZip2: def test_zip(self): @@ -45,11 +45,11 @@ for x in obj_list: assert next(it) == (x, ) raises(StopIteration, next, it) - + it = zip([1, 2, 3], [4], [5, 6]) assert next(it) == (1, 4, 5) raises(StopIteration, next, it) - + it = zip([], [], [1], []) raises(StopIteration, next, it) @@ -78,4 +78,3 @@ assert str(e).find("#" + str(x + 1) + " ") >= 0 else: fail("TypeError expected") - From noreply at buildbot.pypy.org Thu Mar 7 22:12:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 22:12:10 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130307211210.97CB51C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62187:6316975159a0 Date: 2013-03-07 16:11 -0500 http://bitbucket.org/pypy/pypy/changeset/6316975159a0/ Log: merge heads diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -919,24 +919,24 @@ "Cursor needed to be reset because of commit/rollback " "and can no longer be fetched from.") - # do all statements - def fetchone(self): + def __iter__(self): + return self + + def __next__(self): self.__check_cursor() self.__check_reset() + if not self.__statement: + raise StopIteration + return self.__statement._next(self) - if self.__statement is None: - return None + if sys.version_info[0] < 3: + next = __next__ + del __next__ - try: - return self.__statement._next(self) - except StopIteration: - return None + def fetchone(self): + return next(self, None) def fetchmany(self, size=None): - self.__check_cursor() - self.__check_reset() - if self.__statement is None: - return [] if size is None: size = self.arraysize lst = [] @@ -947,15 +947,8 @@ return lst def fetchall(self): - self.__check_cursor() - self.__check_reset() - if self.__statement is None: - return [] return list(self) - def __iter__(self): - return iter(self.fetchone, None) - def __get_connection(self): return self.__connection connection = property(__get_connection) 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 @@ -52,6 +52,16 @@ # raises ProgrammingError because should check closed before check args pytest.raises(_sqlite3.ProgrammingError, "con()") +def test_cursor_iter(): + con = _sqlite3.connect(':memory:') + cur = con.cursor() + with pytest.raises(StopIteration): + next(cur) + cur = con.execute('select 1') + next(cur) + with pytest.raises(StopIteration): + next(cur) + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') From noreply at buildbot.pypy.org Thu Mar 7 22:58:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Mar 2013 22:58:29 +0100 (CET) Subject: [pypy-commit] cffi default: Kill the historical non-decorator version of ffi.callback(), as a Message-ID: <20130307215829.804701C1058@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1187:8a27b7fa299a Date: 2013-03-07 22:58 +0100 http://bitbucket.org/cffi/cffi/changeset/8a27b7fa299a/ Log: Kill the historical non-decorator version of ffi.callback(), as a motivation for doing "the right thing" (see new paragraph in docs). diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -231,13 +231,13 @@ """ return self._backend.buffer(cdata, size) - def callback(self, cdecl, python_callable=None, error=None): - """Return a callback object or a decorator making such a - callback object. 'cdecl' must name a C function pointer type. - The callback invokes the specified 'python_callable' (which may - be provided either directly or via a decorator). Important: the - callback object must be manually kept alive for as long as the - callback may be invoked from the C level. + def callback(self, cdecl, error=None): + """Return a a decorator making a callback object. 'cdecl' must + name a C function or function pointer type. The decorated + Python function is turned into a of the specified + function pointer type. Important: the callback object must be + manually kept alive for as long as the callback may be invoked + from the C level. """ def callback_decorator_wrap(python_callable): if not callable(python_callable): @@ -246,10 +246,10 @@ return self._backend.callback(cdecl, python_callable, error) if isinstance(cdecl, basestring): cdecl = self._typeof(cdecl, consider_function_as_funcptr=True) - if python_callable is None: - return callback_decorator_wrap # decorator mode - else: - return callback_decorator_wrap(python_callable) # direct mode + if isinstance(error, types.FunctionType): + raise TypeError("Not supported any more: ffi.callback('...', fn)." + " Use the decorator form: @ffi.callback('...')") + return callback_decorator_wrap def getctype(self, cdecl, replace_with=''): """Return a string giving the C type 'cdecl', which may be itself diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -983,23 +983,21 @@ passed as callbacks. To make new C callback objects that will invoke a Python function, you need to use:: - >>> def myfunc(x, y): - ... return x + y - ... - >>> ffi.callback("int(int, int)", myfunc) - > - -.. versionadded:: 0.4 - Or equivalently as a decorator: - >>> @ffi.callback("int(int, int)") ... def myfunc(x, y): ... return x + y + ... + >>> myfunc + > Note that you can also use a C *function pointer* type like ``"int(*)(int, int)"`` (as opposed to a C *function* type like ``"int(int, int)"``). It is equivalent here. +.. versionchanged:: 0.6 + ``ffi.callback()`` is now only available as a decorator (see later + for the motivation). + Warning: like ffi.new(), ffi.callback() returns a cdata that has ownership of its C data. (In this case, the necessary C data contains the libffi data structures to do a callback.) This means that the @@ -1009,6 +1007,18 @@ the callback to remain valid forever, store the object in a fresh global variable somewhere.) +Generally, C APIs define callbacks taking a general ``void *`` argument. +You can make good use of it with CFFI as well, in order to avoid +creating a large number of callback objects. You would create instead +only one (or a small number of) callback as global functions. You +cannot give a "pointer" to a real Python object as the ``void *`` +argument, but instead you can use its id() casted to ``void *``. You +store in a ``weakref.WeakValueDictionary`` the mapping that goes from +the id() back to the full object. When the callback is invoked, you +look up the full object in the mapping, gracefully ignoring it if it was +already freed. (In order to encourage this approach, ``ffi.callback()`` +can only be used as a decorator from version 0.6.) + Note that callbacks of a variadic function type are not supported. A workaround is to add custom C code. In the following example, a callback gets a first argument that counts how many extra ``int`` diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -658,11 +658,11 @@ def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) - py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) + py.test.raises(TypeError, ffi.callback("int(*)(int)"), 0) def cb(n): return n + 1 cb.__qualname__ = 'cb' - p = ffi.callback("int(*)(int)", cb) + p = ffi.callback("int(*)(int)")(cb) res = p(41) # calling an 'int(*)(int)', i.e. a function pointer assert res == 42 and type(res) is int res = p(ffi.cast("int", -41)) @@ -688,47 +688,47 @@ def test_functionptr_voidptr_return(self): ffi = FFI(backend=self.Backend()) - def cb(): + @ffi.callback("void*(*)()") + def p(): return ffi.NULL - p = ffi.callback("void*(*)()", cb) res = p() assert res is not None assert res == ffi.NULL int_ptr = ffi.new('int*') void_ptr = ffi.cast('void*', int_ptr) - def cb(): + @ffi.callback("void*(*)()") + def p(): return void_ptr - p = ffi.callback("void*(*)()", cb) res = p() assert res == void_ptr def test_functionptr_intptr_return(self): ffi = FFI(backend=self.Backend()) - def cb(): + @ffi.callback("int*(*)()") + def p(): return ffi.NULL - p = ffi.callback("int*(*)()", cb) res = p() assert res == ffi.NULL int_ptr = ffi.new('int*') - def cb(): + @ffi.callback("int*(*)()") + def p(): return int_ptr - p = ffi.callback("int*(*)()", cb) res = p() assert repr(res).startswith(": " "cannot pass as argument or return value a struct with bit fields") diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -209,8 +209,8 @@ def cb(charp): assert repr(charp).startswith("" % (cb,) res = fptr(b"Hello") assert res == 42 @@ -232,9 +232,9 @@ def test_callback_returning_void(self): ffi = FFI(backend=self.Backend()) for returnvalue in [None, 42]: - def cb(): + @ffi.callback("void(*)(void)") + def fptr(): return returnvalue - fptr = ffi.callback("void(*)(void)", cb) old_stderr = sys.stderr try: sys.stderr = StringIO() diff --git a/testing/test_unicode_literals.py b/testing/test_unicode_literals.py --- a/testing/test_unicode_literals.py +++ b/testing/test_unicode_literals.py @@ -67,6 +67,7 @@ def test_callback(): ffi = FFI() - cb = ffi.callback("int(int)", # unicode literal - lambda x: x + 42) + @ffi.callback("int(int)") # unicode literal + def cb(x): + return x + 42 assert cb(5) == 47 diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -739,7 +739,10 @@ """) lib.reset_cb() assert lib.foo(6) == 41 - my_callback = ffi.callback("int(*)(int)", lambda n: n * 222) + # + @ffi.callback("int(*)(int)") + def my_callback(n): + return n * 222 lib.cb = my_callback assert lib.foo(4) == 887 @@ -757,7 +760,10 @@ """) lib.reset_cb() assert lib.foo(6) == 41 - my_callback = ffi.callback("int(*)(int)", lambda n: n * 222) + # + @ffi.callback("int(int)") + def my_callback(n): + return n * 222 lib.cb = my_callback assert lib.foo(4) == 887 From noreply at buildbot.pypy.org Thu Mar 7 23:14:35 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 23:14:35 +0100 (CET) Subject: [pypy-commit] pypy py3k: add range.index and make a couple fixes to contains/count Message-ID: <20130307221435.A1E4D1C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62188:a8c28f968217 Date: 2013-03-07 14:12 -0800 http://bitbucket.org/pypy/pypy/changeset/a8c28f968217/ Log: add range.index and make a couple fixes to contains/count diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -4,7 +4,7 @@ """ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef from rpython.rlib import jit @@ -422,24 +422,31 @@ return True def descr_contains(self, space, w_item): - try: - int_value = space.int_w(w_item) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise + w_type = space.type(w_item) + if space.is_w(w_type, space.w_int) or space.is_w(w_type, space.w_bool): + return space.newbool(self._contains_long(space, w_item)) + else: return space.sequence_contains(self, w_item) - else: - return space.newbool(self._contains_long(space, w_item)) def descr_count(self, space, w_item): - try: - int_value = space.int_w(w_item) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise + w_type = space.type(w_item) + if space.is_w(w_type, space.w_int) or space.is_w(w_type, space.w_bool): + return space.newint(self._contains_long(space, w_item)) + else: return space.sequence_count(self, w_item) - else: - return space.newint(self._contains_long(space, w_item)) + + def descr_index(self, space, w_item): + w_type = space.type(w_item) + if not (space.is_w(w_type, space.w_int) or + space.is_w(w_type, space.w_bool)): + return space.sequence_index(self, w_item) + + if not self._contains_long(space, w_item): + item_repr = space.unicode_w(space.repr(w_item)) + raise operationerrfmt(space.w_ValueError, u"%s is not in range", + item_repr) + w_index = space.sub(w_item, self.w_start) + return space.floordiv(w_index, self.w_step) W_Range.typedef = TypeDef("range", @@ -452,6 +459,7 @@ __reduce__ = interp2app(W_Range.descr_reduce), __contains__ = interp2app(W_Range.descr_contains), count = interp2app(W_Range.descr_count), + index = interp2app(W_Range.descr_index), ) class W_RangeIterator(Wrappable): diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -345,6 +345,69 @@ assert b not in x raises(OverflowError, len, x) assert _range_len(x) == expected_len + assert x[0] == a + idx = sys.maxsize + 1 + assert x[idx] == a + idx + assert a[idx:idx + 1][0] == a + idx + try: + x[-expected_len - 1] + except IndexError: + pass + else: + assert False, 'Expected IndexError' + try: + x[expected_len] + except IndexError: + pass + else: + assert False, 'Expected IndexError' + + def test_range_index(self): + u = range(2) + assert u.index(0) == 0 + assert u.index(1) == 1 + raises(ValueError, u.index, 2) + raises(ValueError, u.index, object()) + raises(TypeError, u.index) + + assert range(1, 10, 3).index(4) == 1 + assert range(1, -10, -3).index(-5) == 2 + + assert range(10**20).index(1) == 1 + assert range(10**20).index(10**20 - 1) == 10**20 - 1 + + raises(ValueError, range(1, 2**100, 2).index, 2**87) + assert range(1, 2**100, 2).index(2**87+1) == 2**86 + + class AlwaysEqual(object): + def __eq__(self, other): + return True + always_equal = AlwaysEqual() + assert range(10).index(always_equal) == 0 + + def test_range_types(self): + assert 1.0 in range(3) + assert True in range(3) + assert 1+0j in range(3) + + class C1: + def __eq__(self, other): return True + assert C1() in range(3) + + # Objects are never coerced into other types for comparison. + class C2: + def __int__(self): return 1 + def __index__(self): return 1 + assert C2() not in range(3) + # ..except if explicitly told so. + assert int(C2()) in range(3) + + # Check that the range.__contains__ optimization is only + # used for ints, not for instances of subclasses of int. + class C3(int): + def __eq__(self, other): return True + assert C3(11) in range(10) + assert C3(11) in list(range(10)) def test_range_reduce(self): x = range(2, 9, 3) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -439,6 +439,21 @@ if space.eq_w(w_next, w_item): count += 1 + def sequence_index(space, w_container, w_item): + w_iter = space.iter(w_container) + index = 0 + while 1: + try: + w_next = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + msg = "sequence.index(x): x not in sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + if space.eq_w(w_next, w_item): + return space.wrap(index) + index += 1 + def hash(space, w_obj): w_hash = space.lookup(w_obj, '__hash__') if w_hash is None: From noreply at buildbot.pypy.org Thu Mar 7 23:14:37 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 23:14:37 +0100 (CET) Subject: [pypy-commit] pypy py3k: use the new space.sequence_index for operator.indexOf for consistency's sake Message-ID: <20130307221437.100BA1C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62189:60088715348f Date: 2013-03-07 14:14 -0800 http://bitbucket.org/pypy/pypy/changeset/60088715348f/ Log: use the new space.sequence_index for operator.indexOf for consistency's sake (though this may be slower until sequence_index gets a jitdriver) diff --git a/pypy/module/operator/__init__.py b/pypy/module/operator/__init__.py --- a/pypy/module/operator/__init__.py +++ b/pypy/module/operator/__init__.py @@ -17,7 +17,7 @@ appleveldefs = {} - app_names = ['countOf', 'indexOf', + app_names = ['countOf', 'attrgetter', 'itemgetter', 'methodcaller', ] @@ -34,7 +34,8 @@ 'sub', 'truediv', 'truth', 'xor', 'iadd', 'iand', 'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul', 'ior', 'ipow', - 'irshift', 'isub', 'itruediv', 'ixor', '_length_hint'] + 'irshift', 'isub', 'itruediv', 'ixor', '_length_hint', + 'indexOf'] interpleveldefs = {} diff --git a/pypy/module/operator/app_operator.py b/pypy/module/operator/app_operator.py --- a/pypy/module/operator/app_operator.py +++ b/pypy/module/operator/app_operator.py @@ -14,16 +14,6 @@ count += 1 return count -def indexOf(a, b): - 'indexOf(a, b) -- Return the first index of b in a.' - index = 0 - for x in a: - if x == b: - return index - index += 1 - raise ValueError('sequence.index(x): x not in sequence') - - def attrgetter(attr, *attrs): if attrs: getters = [single_attr_getter(a) for a in (attr,) + attrs] diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py --- a/pypy/module/operator/interp_operator.py +++ b/pypy/module/operator/interp_operator.py @@ -54,7 +54,9 @@ 'gt(a, b) -- Same as a>b.' return space.gt(w_a, w_b) -# indexOf +def indexOf(space, w_a, w_b): + 'indexOf(a, b) -- Return the first index of b in a.' + return space.sequence_index(w_a, w_b) def inv(space, w_obj,): 'inv(a) -- Same as ~a.' diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py --- a/pypy/module/operator/test/test_operator.py +++ b/pypy/module/operator/test/test_operator.py @@ -173,3 +173,10 @@ assert methodcaller("method", 4)(x) == (4, 3) assert methodcaller("method", 4, 5)(x) == (4, 5) assert methodcaller("method", 4, arg2=42)(x) == (4, 42) + + def test_indexOf(self): + import operator + raises(TypeError, operator.indexOf) + raises(TypeError, operator.indexOf, None, None) + assert operator.indexOf([4, 3, 2, 1], 3) == 1 + raises(ValueError, operator.indexOf, [4, 3, 2, 1], 0) From noreply at buildbot.pypy.org Thu Mar 7 23:25:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Mar 2013 23:25:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix translation, hack, blerg Message-ID: <20130307222558.942F51C06F2@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62190:5a8741c00853 Date: 2013-03-07 14:25 -0800 http://bitbucket.org/pypy/pypy/changeset/5a8741c00853/ Log: fix translation, hack, blerg diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -443,8 +443,8 @@ if not self._contains_long(space, w_item): item_repr = space.unicode_w(space.repr(w_item)) - raise operationerrfmt(space.w_ValueError, u"%s is not in range", - item_repr) + msg = u"%s is not in range" % item_repr + raise OperationError(space.w_ValueError, space.wrap(msg)) w_index = space.sub(w_item, self.w_start) return space.floordiv(w_index, self.w_step) From noreply at buildbot.pypy.org Thu Mar 7 23:43:48 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 23:43:48 +0100 (CET) Subject: [pypy-commit] pypy default: unify sqlite3 between default and py3k Message-ID: <20130307224348.804341C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62191:71538a3eb8f3 Date: 2013-03-07 17:38 -0500 http://bitbucket.org/pypy/pypy/changeset/71538a3eb8f3/ Log: unify sqlite3 between default and py3k diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -34,6 +34,16 @@ import weakref from threading import _get_ident as _thread_get_ident +if sys.version_info[0] >= 3: + StandardError = Exception + long = int + xrange = range + basestring = unicode = str + buffer = memoryview + BLOB_TYPE = bytes +else: + BLOB_TYPE = buffer + names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() for name in names: try: @@ -243,7 +253,7 @@ ########################################## # SQLite version information -sqlite_version = sqlite.sqlite3_libversion() +sqlite_version = str(sqlite.sqlite3_libversion().decode('ascii')) class Error(StandardError): pass @@ -282,6 +292,16 @@ def unicode_text_factory(x): return unicode(x, 'utf-8') +if sys.version_info[0] < 3: + def OptimizedUnicode(s): + try: + val = unicode(s, "ascii").encode("ascii") + except UnicodeDecodeError: + val = unicode(s, "utf-8") + return val +else: + OptimizedUnicode = unicode_text_factory + class _StatementCache(object): def __init__(self, connection, maxcount): @@ -440,7 +460,7 @@ @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): - if not isinstance(sql, (str, unicode)): + if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") return self._statement_cache.get(sql, self.row_factory) @@ -640,7 +660,7 @@ @_check_closed_wrap def create_collation(self, name, callback): name = name.upper() - if not all(c in string.uppercase + string.digits + '_' for c in name): + if not all(c in string.ascii_uppercase + string.digits + '_' for c in name): raise ProgrammingError("invalid character in collation name") if callback is None: @@ -714,6 +734,11 @@ if ret != SQLITE_OK: raise self._get_exception(ret) + if sys.version_info[0] >= 3: + def __get_in_transaction(self): + return self._in_transaction + in_transaction = property(__get_in_transaction) + def __get_total_changes(self): self._check_closed() return sqlite.sqlite3_total_changes(self._db) @@ -726,7 +751,7 @@ if val is None: self.commit() else: - self.__begin_statement = b"BEGIN " + val.encode('ascii') + self.__begin_statement = str("BEGIN " + val).encode('utf-8') self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) @@ -800,7 +825,7 @@ try: self.__description = None self._reset = False - if not isinstance(sql, (str, unicode)): + if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -847,7 +872,7 @@ try: self.__description = None self._reset = False - if not isinstance(sql, (str, unicode)): + if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -982,7 +1007,7 @@ def __init__(self, connection, sql): self.__con = connection - if not isinstance(sql, (str, unicode)): + if not isinstance(sql, basestring): raise ValueError("sql must be a string") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): @@ -1060,16 +1085,18 @@ self.__row_cast_map.append(converter) - def __check_decodable(self, param): - if self.__con.text_factory in (unicode, OptimizedUnicode, unicode_text_factory): - for c in param: - if ord(c) & 0x80 != 0: - raise self.__con.ProgrammingError( - "You must not use 8-bit bytestrings unless " - "you use a text_factory that can interpret " - "8-bit bytestrings (like text_factory = str). " - "It is highly recommended that you instead " - "just switch your application to Unicode strings.") + if sys.version_info[0] < 3: + def __check_decodable(self, param): + if self.__con.text_factory in (unicode, OptimizedUnicode, + unicode_text_factory): + for c in param: + if ord(c) & 0x80 != 0: + raise self.__con.ProgrammingError( + "You must not use 8-bit bytestrings unless " + "you use a text_factory that can interpret " + "8-bit bytestrings (like text_factory = str). " + "It is highly recommended that you instead " + "just switch your application to Unicode strings.") def __set_param(self, idx, param): cvt = converters.get(type(param)) @@ -1080,20 +1107,20 @@ if param is None: rc = sqlite.sqlite3_bind_null(self._statement, idx) - elif type(param) in (bool, int, long): + elif isinstance(param, (bool, int, long)): if -2147483648 <= param <= 2147483647: rc = sqlite.sqlite3_bind_int(self._statement, idx, param) else: rc = sqlite.sqlite3_bind_int64(self._statement, idx, param) - elif type(param) is float: + elif isinstance(param, float): rc = sqlite.sqlite3_bind_double(self._statement, idx, param) + elif isinstance(param, unicode): + param = param.encode("utf-8") + rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) elif isinstance(param, str): self.__check_decodable(param) rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) - elif isinstance(param, unicode): - param = param.encode("utf-8") - rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) - elif type(param) is buffer: + elif isinstance(param, (buffer, bytes)): param = bytes(param) rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) else: @@ -1167,23 +1194,21 @@ converter = self.__row_cast_map[i] if converter is None: - if typ == SQLITE_INTEGER: + if typ == SQLITE_NULL: + val = None + elif typ == SQLITE_INTEGER: val = sqlite.sqlite3_column_int64(self._statement, i) - if -sys.maxint-1 <= val <= sys.maxint: - val = int(val) elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_column_double(self._statement, i) - elif typ == SQLITE_BLOB: - blob = sqlite.sqlite3_column_blob(self._statement, i) - blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = buffer(string_at(blob, blob_len)) - elif typ == SQLITE_NULL: - val = None elif typ == SQLITE_TEXT: text = sqlite.sqlite3_column_text(self._statement, i) text_len = sqlite.sqlite3_column_bytes(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) + elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_column_blob(self._statement, i) + blob_len = sqlite.sqlite3_column_bytes(self._statement, i) + val = BLOB_TYPE(string_at(blob, blob_len)) else: blob = sqlite.sqlite3_column_blob(self._statement, i) if not blob: @@ -1292,21 +1317,19 @@ _params = [] for i in range(nargs): typ = sqlite.sqlite3_value_type(params[i]) - if typ == SQLITE_INTEGER: + if typ == SQLITE_NULL: + val = None + elif typ == SQLITE_INTEGER: val = sqlite.sqlite3_value_int64(params[i]) - if -sys.maxint-1 <= val <= sys.maxint: - val = int(val) elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) + elif typ == SQLITE_TEXT: + val = sqlite.sqlite3_value_text(params[i]) + val = val.decode('utf-8') elif typ == SQLITE_BLOB: blob = sqlite.sqlite3_value_blob(params[i]) blob_len = sqlite.sqlite3_value_bytes(params[i]) - val = buffer(string_at(blob, blob_len)) - elif typ == SQLITE_NULL: - val = None - elif typ == SQLITE_TEXT: - val = sqlite.sqlite3_value_text(params[i]) - val = val.decode('utf-8') + val = BLOB_TYPE(string_at(blob, blob_len)) else: raise NotImplementedError _params.append(val) @@ -1318,14 +1341,14 @@ sqlite.sqlite3_result_null(con) elif isinstance(val, (bool, int, long)): sqlite.sqlite3_result_int64(con, int(val)) - elif isinstance(val, str): - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + elif isinstance(val, float): + sqlite.sqlite3_result_double(con, val) elif isinstance(val, unicode): val = val.encode('utf-8') sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) - elif isinstance(val, float): - sqlite.sqlite3_result_double(con, val) - elif isinstance(val, buffer): + elif isinstance(val, str): + sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + elif isinstance(val, (buffer, bytes)): sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) else: raise NotImplementedError @@ -1397,8 +1420,8 @@ microseconds = int(timepart_full[1]) else: microseconds = 0 - return datetime.datetime(year, month, day, - hours, minutes, seconds, microseconds) + return datetime.datetime(year, month, day, hours, minutes, seconds, + microseconds) register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) @@ -1435,11 +1458,3 @@ return val register_adapters_and_converters() - - -def OptimizedUnicode(s): - try: - val = unicode(s, "ascii").encode("ascii") - except UnicodeDecodeError: - val = unicode(s, "utf-8") - return val From noreply at buildbot.pypy.org Thu Mar 7 23:43:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Mar 2013 23:43:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130307224349.C756E1C10F8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62192:f7086f05b2e3 Date: 2013-03-07 17:43 -0500 http://bitbucket.org/pypy/pypy/changeset/f7086f05b2e3/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -34,6 +34,16 @@ import weakref from threading import _get_ident as _thread_get_ident +if sys.version_info[0] >= 3: + StandardError = Exception + long = int + xrange = range + basestring = unicode = str + buffer = memoryview + BLOB_TYPE = bytes +else: + BLOB_TYPE = buffer + names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() for name in names: try: @@ -243,12 +253,12 @@ ########################################## # SQLite version information -sqlite_version = sqlite.sqlite3_libversion().decode('ascii') +sqlite_version = str(sqlite.sqlite3_libversion().decode('ascii')) -class Error(Exception): +class Error(StandardError): pass -class Warning(Exception): +class Warning(StandardError): pass class InterfaceError(Error): @@ -280,7 +290,17 @@ return factory(database, **kwargs) def unicode_text_factory(x): - return str(x, 'utf-8') + return unicode(x, 'utf-8') + +if sys.version_info[0] < 3: + def OptimizedUnicode(s): + try: + val = unicode(s, "ascii").encode("ascii") + except UnicodeDecodeError: + val = unicode(s, "utf-8") + return val +else: + OptimizedUnicode = unicode_text_factory class _StatementCache(object): @@ -313,7 +333,8 @@ self.__initialized = True self._db = c_void_p() - database = database.encode('utf-8') + if isinstance(database, unicode): + database = database.encode('utf-8') if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: @@ -439,7 +460,7 @@ @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): - if not isinstance(sql, str): + if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") return self._statement_cache.get(sql, self.row_factory) @@ -556,7 +577,8 @@ c_closure = _FUNC(closure) self.__func_cache[callback] = c_closure, closure - name = name.encode('utf-8') + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, c_closure, @@ -624,7 +646,8 @@ self.__aggregates[cls] = (c_step_callback, c_final_callback, step_callback, final_callback) - name = name.encode('utf-8') + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_function(self._db, name, num_args, SQLITE_UTF8, None, cast(None, _FUNC), @@ -656,7 +679,8 @@ c_collation_callback = _COLLATION(collation_callback) self.__collations[name] = c_collation_callback - name = name.encode('utf-8') + if isinstance(name, unicode): + name = name.encode('utf-8') ret = sqlite.sqlite3_create_collation(self._db, name, SQLITE_UTF8, None, @@ -710,9 +734,10 @@ if ret != SQLITE_OK: raise self._get_exception(ret) - def __get_in_transaction(self): - return self._in_transaction - in_transaction = property(__get_in_transaction) + if sys.version_info[0] >= 3: + def __get_in_transaction(self): + return self._in_transaction + in_transaction = property(__get_in_transaction) def __get_total_changes(self): self._check_closed() @@ -726,7 +751,7 @@ if val is None: self.commit() else: - self.__begin_statement = b"BEGIN " + val.encode('utf-8') + self.__begin_statement = str("BEGIN " + val).encode('utf-8') self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) @@ -800,7 +825,7 @@ try: self.__description = None self._reset = False - if not isinstance(sql, str): + if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -847,7 +872,7 @@ try: self.__description = None self._reset = False - if not isinstance(sql, str): + if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -880,9 +905,9 @@ self._reset = False self.__check_cursor() statement = c_void_p() - if isinstance(sql, str): + if isinstance(sql, unicode): sql = sql.encode('utf-8') - else: + elif not isinstance(sql, str): raise ValueError("script argument must be unicode or string.") c_sql = c_char_p(sql) @@ -982,7 +1007,7 @@ def __init__(self, connection, sql): self.__con = connection - if not isinstance(sql, str): + if not isinstance(sql, basestring): raise ValueError("sql must be a string") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): @@ -998,7 +1023,8 @@ self._statement = c_void_p() next_char = c_char_p() - sql = sql.encode('utf-8') + if isinstance(sql, unicode): + sql = sql.encode('utf-8') ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) if ret == SQLITE_OK and self._statement.value is None: @@ -1032,7 +1058,7 @@ def _build_row_cast_map(self): self.__row_cast_map = [] - for i in range(sqlite.sqlite3_column_count(self._statement)): + for i in xrange(sqlite.sqlite3_column_count(self._statement)): converter = None if self.__con._detect_types & PARSE_COLNAMES: @@ -1059,6 +1085,19 @@ self.__row_cast_map.append(converter) + if sys.version_info[0] < 3: + def __check_decodable(self, param): + if self.__con.text_factory in (unicode, OptimizedUnicode, + unicode_text_factory): + for c in param: + if ord(c) & 0x80 != 0: + raise self.__con.ProgrammingError( + "You must not use 8-bit bytestrings unless " + "you use a text_factory that can interpret " + "8-bit bytestrings (like text_factory = str). " + "It is highly recommended that you instead " + "just switch your application to Unicode strings.") + def __set_param(self, idx, param): cvt = converters.get(type(param)) if cvt is not None: @@ -1068,17 +1107,20 @@ if param is None: rc = sqlite.sqlite3_bind_null(self._statement, idx) - elif type(param) in (bool, int): + elif isinstance(param, (bool, int, long)): if -2147483648 <= param <= 2147483647: rc = sqlite.sqlite3_bind_int(self._statement, idx, param) else: rc = sqlite.sqlite3_bind_int64(self._statement, idx, param) - elif type(param) is float: + elif isinstance(param, float): rc = sqlite.sqlite3_bind_double(self._statement, idx, param) - elif isinstance(param, str): + elif isinstance(param, unicode): param = param.encode("utf-8") rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) - elif type(param) in (bytes, memoryview): + elif isinstance(param, str): + self.__check_decodable(param) + rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + elif isinstance(param, (buffer, bytes)): param = bytes(param) rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) else: @@ -1147,28 +1189,26 @@ def _readahead(self, cursor): self.column_count = sqlite.sqlite3_column_count(self._statement) row = [] - for i in range(self.column_count): + for i in xrange(self.column_count): typ = sqlite.sqlite3_column_type(self._statement, i) converter = self.__row_cast_map[i] if converter is None: - if typ == SQLITE_INTEGER: + if typ == SQLITE_NULL: + val = None + elif typ == SQLITE_INTEGER: val = sqlite.sqlite3_column_int64(self._statement, i) - if -sys.maxsize-1 <= val <= sys.maxsize: - val = int(val) elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_column_double(self._statement, i) - elif typ == SQLITE_BLOB: - blob = sqlite.sqlite3_column_blob(self._statement, i) - blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = bytes(string_at(blob, blob_len)) - elif typ == SQLITE_NULL: - val = None elif typ == SQLITE_TEXT: text = sqlite.sqlite3_column_text(self._statement, i) text_len = sqlite.sqlite3_column_bytes(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) + elif typ == SQLITE_BLOB: + blob = sqlite.sqlite3_column_blob(self._statement, i) + blob_len = sqlite.sqlite3_column_bytes(self._statement, i) + val = BLOB_TYPE(string_at(blob, blob_len)) else: blob = sqlite.sqlite3_column_blob(self._statement, i) if not blob: @@ -1188,7 +1228,7 @@ if self._kind == Statement._DML: return None desc = [] - for i in range(sqlite.sqlite3_column_count(self._statement)): + for i in xrange(sqlite.sqlite3_column_count(self._statement)): name = sqlite.sqlite3_column_name(self._statement, i) if name is not None: name = name.decode('utf-8').split("[")[0].strip() @@ -1277,21 +1317,19 @@ _params = [] for i in range(nargs): typ = sqlite.sqlite3_value_type(params[i]) - if typ == SQLITE_INTEGER: + if typ == SQLITE_NULL: + val = None + elif typ == SQLITE_INTEGER: val = sqlite.sqlite3_value_int64(params[i]) - if -sys.maxsize-1 <= val <= sys.maxsize: - val = int(val) elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) + elif typ == SQLITE_TEXT: + val = sqlite.sqlite3_value_text(params[i]) + val = val.decode('utf-8') elif typ == SQLITE_BLOB: blob = sqlite.sqlite3_value_blob(params[i]) blob_len = sqlite.sqlite3_value_bytes(params[i]) - val = bytes(string_at(blob, blob_len)) - elif typ == SQLITE_NULL: - val = None - elif typ == SQLITE_TEXT: - val = sqlite.sqlite3_value_text(params[i]) - val = val.decode('utf-8') + val = BLOB_TYPE(string_at(blob, blob_len)) else: raise NotImplementedError _params.append(val) @@ -1301,14 +1339,16 @@ def _convert_result(con, val): if val is None: sqlite.sqlite3_result_null(con) - elif isinstance(val, (bool, int)): + elif isinstance(val, (bool, int, long)): sqlite.sqlite3_result_int64(con, int(val)) - elif isinstance(val, str): + elif isinstance(val, float): + sqlite.sqlite3_result_double(con, val) + elif isinstance(val, unicode): val = val.encode('utf-8') sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) - elif isinstance(val, float): - sqlite.sqlite3_result_double(con, val) - elif isinstance(val, (bytes, memoryview)): + elif isinstance(val, str): + sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + elif isinstance(val, (buffer, bytes)): sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) else: raise NotImplementedError @@ -1380,8 +1420,8 @@ microseconds = int(timepart_full[1]) else: microseconds = 0 - return datetime.datetime(year, month, day, - hours, minutes, seconds, microseconds) + return datetime.datetime(year, month, day, hours, minutes, seconds, + microseconds) register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) @@ -1418,6 +1458,3 @@ return val register_adapters_and_converters() - - -OptimizedUnicode = unicode_text_factory From noreply at buildbot.pypy.org Fri Mar 8 00:11:44 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 8 Mar 2013 00:11:44 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Fix conditional definition of wait3 and wait4 Message-ID: <20130307231144.3393B1C0925@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r62193:0cc72ca23531 Date: 2013-03-07 00:37 +0100 http://bitbucket.org/pypy/pypy/changeset/0cc72ca23531/ Log: Fix conditional definition of wait3 and wait4 diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -48,12 +48,10 @@ 'popen3' : 'app_posix.popen3', 'popen4' : 'app_posix.popen4', }) - if hasattr(posix, 'wait'): - appleveldefs['wait'] = 'app_posix.wait' - if hasattr(posix, 'wait3'): - appleveldefs['wait3'] = 'app_posix.wait3' - if hasattr(posix, 'wait4'): - appleveldefs['wait4'] = 'app_posix.wait4' + for name in '''wait wait3 wait4'''.split(): + symbol = 'HAVE_' + name.upper() + if getattr(rposix, symbol): + appleveldefs[name] = 'app_posix.%s' % (name,) # Functions implemented on all platforms interpleveldefs = { @@ -107,7 +105,7 @@ getsid getuid geteuid getgid getegid getpgrp getpgid setsid setuid seteuid setgid setegid setpgrp setpgid getppid getgroups setreuid setregid - wait wait3 wait4 killpg waitpid + killpg waitpid '''.split(): symbol = 'HAVE_' + name.upper() if getattr(rposix, symbol): From noreply at buildbot.pypy.org Fri Mar 8 00:11:45 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 8 Mar 2013 00:11:45 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Use configure() for posix constants, instead of the host Python. Message-ID: <20130307231145.783A01C0925@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r62194:287249e7d15c Date: 2013-03-07 01:03 +0100 http://bitbucket.org/pypy/pypy/changeset/287249e7d15c/ Log: Use configure() for posix constants, instead of the host Python. diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -132,9 +132,9 @@ EX_OK EX_USAGE EX_DATAERR EX_NOINPUT EX_NOUSER EX_NOHOST EX_UNAVAILABLE EX_SOFTWARE EX_OSERR EX_OSFILE EX_CANTCREAT EX_IOERR EX_TEMPFAIL EX_PROTOCOL EX_NOPERM EX_CONFIG EX_NOTFOUND - '''.split(): - if hasattr(posix, constant): - value = getattr(posix, constant) + '''.split(): # XXX find a way to avoid duplicating the full list + value = getattr(rposix, constant) + if value is not None: interpleveldefs[constant] = "space.wrap(%s)" % value # XXX don't use the os module here diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -85,7 +85,8 @@ separate_module_sources = [] export_symbols = [] includes=['errno.h', 'stdio.h', 'stdlib.h', 'unistd.h', 'sys/stat.h', - 'signal.h', 'pty.h', 'sys/utsname.h', 'sys/wait.h'] + 'fcntl.h', 'signal.h', 'pty.h', 'sys/utsname.h', 'sys/wait.h', + 'sysexits.h', 'limits.h'] rposix_eci = ExternalCompilationInfo( includes=includes, separate_module_sources=separate_module_sources, @@ -110,6 +111,20 @@ symbol = 'HAVE_' + name.upper() setattr(CConfig, symbol, rffi_platform.Has(name)) +for name in ''' + F_OK R_OK W_OK X_OK NGROUPS_MAX TMP_MAX + WNOHANG WCONTINUED WUNTRACED + O_RDONLY O_WRONLY O_RDWR O_NDELAY O_NONBLOCK O_APPEND + O_DSYNC O_RSYNC O_SYNC O_NOCTTY O_CREAT O_EXCL O_TRUNC + O_BINARY O_TEXT O_LARGEFILE O_SHLOCK O_EXLOCK + O_NOINHERIT O_TEMPORARY O_RANDOM O_SEQUENTIAL + O_ASYNC O_DIRECT O_DIRECTORY O_NOFOLLOW O_NOATIME + EX_OK EX_USAGE EX_DATAERR EX_NOINPUT EX_NOUSER EX_NOHOST + EX_UNAVAILABLE EX_SOFTWARE EX_OSERR EX_OSFILE EX_CANTCREAT + EX_IOERR EX_TEMPFAIL EX_PROTOCOL EX_NOPERM EX_CONFIG EX_NOTFOUND + '''.split(): + setattr(CConfig, name, rffi_platform.DefinedConstantInteger(name)) + globals().update(rffi_platform.configure(CConfig)) From noreply at buildbot.pypy.org Fri Mar 8 00:11:46 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 8 Mar 2013 00:11:46 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Move WEXITSTATUS &co out of ll_os.py. Message-ID: <20130307231146.B4F3A1C0925@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r62195:f0b5c549aea8 Date: 2013-03-08 00:11 +0100 http://bitbucket.org/pypy/pypy/changeset/f0b5c549aea8/ Log: Move WEXITSTATUS &co out of ll_os.py. Looks much simpler like this. diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -1,10 +1,8 @@ # Package initialisation from pypy.interpreter.mixedmodule import MixedModule -from rpython.rtyper.module.ll_os import RegisterOs from rpython.rlib import rposix import os, sys -exec 'import %s as posix' % os.name # this is the list of function which is *not* present in the posix module of # IronPython 2.6, and that we want to ignore for now @@ -144,9 +142,8 @@ interpleveldefs['pathconf_names'] = 'space.wrap(os.pathconf_names)' # Macros for process exit statuses: WIFEXITED &co - # XXX HAVE_SYS_WAIT_H - for name in RegisterOs.w_star: - if hasattr(posix, name): + if rposix.HAVE_WAIT: + for name in rposix.wait_macros: interpleveldefs[name] = 'interp_posix.' + name def __init__(self, space, w_name): diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -3,9 +3,9 @@ from rpython.rlib.objectmodel import specialize from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.unroll import unrolling_iterable +from rpython.tool.sourcetools import func_renamer from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.module.ll_os import RegisterOs from rpython.rtyper.module import ll_os_stat from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rtyper.tool import rffi_platform @@ -1079,23 +1079,21 @@ raise wrap_oserror(space, e) return space.w_None -def declare_new_w_star(name): - if name in RegisterOs.w_star_returning_int: - @unwrap_spec(status=c_int) - def WSTAR(space, status): - return space.wrap(getattr(os, name)(status)) - else: - @unwrap_spec(status=c_int) - def WSTAR(space, status): - return space.newbool(getattr(os, name)(status)) - WSTAR.__doc__ = getattr(os, name).__doc__ - WSTAR.func_name = name - return WSTAR +def declare_wait_macro(name, return_bool=False): + @unwrap_spec(status=c_int) + @func_renamer(name) + def wait_macro(space, status): + result = getattr(rposix, name)(status) + if return_bool: + return space.newbool(result) + else: + return space.wrap(result) + return wait_macro -for name in RegisterOs.w_star: - if hasattr(os, name): - func = declare_new_w_star(name) - globals()[name] = func +for name in rposix.wait_macros_returning_int: + globals()[name] = declare_wait_macro(name) +for name in rposix.wait_macros_returning_bool: + globals()[name] = declare_wait_macro(name, return_bool=True) @unwrap_spec(fd=c_int) def ttyname(space, fd): diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -7,7 +7,6 @@ from pypy.tool.pytest.objspace import gettestobjspace from pypy.conftest import pypydir from rpython.rlib import rposix -from rpython.rtyper.module.ll_os import RegisterOs from rpython.translator.c.test.test_extfunc import need_sparse_files import os import py @@ -566,7 +565,7 @@ raises(TypeError, "os.utime('xxx', 3)") raises(OSError, "os.utime('somefilewhichihopewouldneverappearhere', None)") - for name in RegisterOs.w_star: + for name in rposix.wait_macros: if hasattr(os, name): values = [0, 1, 127, 128, 255] code = py.code.Source(""" diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -1,6 +1,6 @@ import os from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT -from rpython.rtyper.lltypesystem import ll2ctypes, rffi +from rpython.rtyper.lltypesystem import ll2ctypes, lltype, rffi from rpython.rtyper.tool import rffi_platform from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.rarithmetic import intmask @@ -166,13 +166,23 @@ pass # Expose posix functions -def external(name, args, result): - return rffi.llexternal(name, args, result, - compilation_info=CConfig._compilation_info_) +def external(name, args, result, **kwargs): + return rffi.llexternal( + name, args, result, + compilation_info=CConfig._compilation_info_, **kwargs) c_fchmod = external('fchmod', [rffi.INT, rffi.MODE_T], rffi.INT) c_fchown = external('fchown', [rffi.INT, rffi.INT, rffi.INT], rffi.INT) +if HAVE_WAIT: + wait_macros_returning_int = ['WEXITSTATUS', 'WSTOPSIG', 'WTERMSIG'] + wait_macros_returning_bool = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED', + 'WIFSIGNALED', 'WIFEXITED'] + wait_macros = wait_macros_returning_int + wait_macros_returning_bool + for name in wait_macros: + globals()[name] = external(name, [lltype.Signed], lltype.Signed, + macro=True) + #___________________________________________________________________ # Wrappers around posix functions, that accept either strings, or diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py --- a/rpython/rtyper/module/ll_os.py +++ b/rpython/rtyper/module/ll_os.py @@ -211,29 +211,6 @@ '#include ', []) - # we need an indirection via c functions to get macro calls working on llvm XXX still? - if hasattr(os, 'WCOREDUMP'): - decl_snippet = """ - %(ret_type)s pypy_macro_wrapper_%(name)s (int status); - """ - def_snippet = """ - %(ret_type)s pypy_macro_wrapper_%(name)s (int status) { - return %(name)s(status); - } - """ - decls = [] - defs = [] - for name in self.w_star: - data = {'ret_type': 'int', 'name': name} - decls.append((decl_snippet % data).strip()) - defs.append((def_snippet % data).strip()) - - self.compilation_info = self.compilation_info.merge( - ExternalCompilationInfo( - post_include_bits = decls, - separate_module_sources = ["\n".join(defs)] - )) - # a simple, yet useful factory def extdef_for_os_function_returning_int(self, name, **kwds): c_func = self.llexternal(name, [], rffi.INT, **kwds) @@ -1742,45 +1719,6 @@ from rpython.rtyper.module import ll_os_stat return ll_os_stat.register_stat_variant('lstat', traits) - # ------------------------------- os.W* --------------------------------- - - w_star = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED', - 'WIFSIGNALED', 'WIFEXITED', 'WEXITSTATUS', - 'WSTOPSIG', 'WTERMSIG'] - # last 3 are returning int - w_star_returning_int = dict.fromkeys(w_star[-3:]) - - - - def declare_new_w_star(self, name): - """ stupid workaround for the python late-binding - 'feature' - """ - - def fake(status): - return int(getattr(os, name)(status)) - fake.func_name = 'fake_' + name - - os_c_func = self.llexternal("pypy_macro_wrapper_" + name, - [lltype.Signed], lltype.Signed, - _callable=fake) - - if name in self.w_star_returning_int: - def llimpl(status): - return os_c_func(status) - resulttype = int - else: - def llimpl(status): - return bool(os_c_func(status)) - resulttype = bool - llimpl.func_name = name + '_llimpl' - return extdef([int], resulttype, "ll_os." + name, - llimpl=llimpl) - - for name in w_star: - locals()['register_w_' + name] = registering_if(os, name)( - lambda self, xname=name : self.declare_new_w_star(xname)) - @registering_if(os, 'ttyname') def register_os_ttyname(self): os_ttyname = self.llexternal('ttyname', [lltype.Signed], rffi.CCHARP) From noreply at buildbot.pypy.org Fri Mar 8 00:15:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 8 Mar 2013 00:15:13 +0100 (CET) Subject: [pypy-commit] pypy py3k: unused imports Message-ID: <20130307231513.E0A561C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62196:da8050022754 Date: 2013-03-07 15:14 -0800 http://bitbucket.org/pypy/pypy/changeset/da8050022754/ Log: unused imports diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -4,13 +4,12 @@ """ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef from rpython.rlib import jit from rpython.rlib.objectmodel import specialize from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.rbigint import rbigint def get_len_of_range(lo, hi, step): From noreply at buildbot.pypy.org Fri Mar 8 00:54:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 00:54:41 +0100 (CET) Subject: [pypy-commit] cffi default: Give some compatibility explanation when passing a Python file object to Message-ID: <20130307235441.E6FB91C1058@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1188:7a86941ef198 Date: 2013-03-08 00:54 +0100 http://bitbucket.org/cffi/cffi/changeset/7a86941ef198/ Log: Give some compatibility explanation when passing a Python file object to a FILE argument. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -90,6 +90,7 @@ #define CT_CUSTOM_FIELD_POS 32768 #define CT_IS_LONGDOUBLE 65536 #define CT_IS_BOOL 131072 +#define _CT_IS_FILE 262144 #define CT_PRIMITIVE_ANY (CT_PRIMITIVE_SIGNED | \ CT_PRIMITIVE_UNSIGNED | \ CT_PRIMITIVE_CHAR | \ @@ -2041,6 +2042,18 @@ return ct_int; } +static int +_explicit_error_message_for_FILE(CTypeDescrObject *ctitem) +{ + if (!(ctitem->ct_flags & _CT_IS_FILE)) + return 0; + PyErr_SetString(PyExc_TypeError, + "bad argument type for 'FILE' type (note that you cannot " + "pass Python files directly any more since CFFI 0.6; see " + "demo/file1.py)"); + return -1; +} + static Py_ssize_t _prepare_pointer_call_argument(CTypeDescrObject *ctptr, PyObject *init, char **output_data) @@ -2083,6 +2096,8 @@ else { /* refuse to receive just an integer (and interpret it as the array size) */ + if (_explicit_error_message_for_FILE(ctitem) < 0) + return -1; goto convert_default; } @@ -3318,9 +3333,14 @@ static PyObject *b_new_struct_type(PyObject *self, PyObject *args) { char *name; + int flag; if (!PyArg_ParseTuple(args, "s:new_struct_type", &name)) return NULL; - return _b_struct_or_union_type("struct", name, CT_STRUCT); + + flag = CT_STRUCT; + if (strcmp(name, "_IO_FILE") == 0 || strcmp(name, "$FILE") == 0) + flag |= _CT_IS_FILE; + return _b_struct_or_union_type("struct", name, flag); } static PyObject *b_new_union_type(PyObject *self, PyObject *args) @@ -4899,8 +4919,10 @@ static char *_cffi_to_c_pointer(PyObject *obj, CTypeDescrObject *ct) { char *result; - if (convert_from_object((char *)&result, ct, obj) < 0) + if (convert_from_object((char *)&result, ct, obj) < 0) { + _explicit_error_message_for_FILE(ct->ct_itemdescr); return NULL; + } return result; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2655,6 +2655,17 @@ c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] +def test_FILE_forbidden(): + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BFunc = new_function_type((BFILEP,), BFILEP, False) + func = cast(BFunc, 0) + with open(__file__, "rb") as f: + e = py.test.raises(TypeError, func, f) + if '__pypy__' not in sys.builtin_module_names: + assert ('note that you cannot pass Python files directly ' + 'any more since CFFI 0.6') in str(e.value) + def test_version(): # this test is here mostly for PyPy assert __version__ == "0.6" diff --git a/demo/file1.py b/demo/file1.py --- a/demo/file1.py +++ b/demo/file1.py @@ -3,7 +3,10 @@ # # To access FILE objects in C that correspond directly to file descriptors -# at the Python level, just define and use fdopen() and fclose(). +# at the Python level, just define and use fdopen() and fclose(). In +# CFFI <= 0.5 you could directly pass Python file objects, but this is +# not supported any more: you have to build (and close) the C-level FILEs +# explicitly. See also 'file2.py' in the same directory for another example. # ffi = cffi.FFI() From noreply at buildbot.pypy.org Fri Mar 8 00:55:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 00:55:16 +0100 (CET) Subject: [pypy-commit] pypy default: Update to cffi/7a86941ef198 Message-ID: <20130307235516.9F1F81C1058@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62197:0d391c72accf Date: 2013-03-08 00:54 +0100 http://bitbucket.org/pypy/pypy/changeset/0d391c72accf/ Log: Update to cffi/7a86941ef198 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 @@ -2644,6 +2644,17 @@ c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] +def test_FILE_forbidden(): + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BFunc = new_function_type((BFILEP,), BFILEP, False) + func = cast(BFunc, 0) + with open(__file__, "rb") as f: + e = py.test.raises(TypeError, func, f) + if '__pypy__' not in sys.builtin_module_names: + assert ('note that you cannot pass Python files directly ' + 'any more since CFFI 0.6') in str(e.value) + def test_version(): # this test is here mostly for PyPy assert __version__ == "0.6" From noreply at buildbot.pypy.org Fri Mar 8 02:18:42 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 02:18:42 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: port some sqlite fixes/cleanups from default Message-ID: <20130308011842.3A3DE1C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: sqlite-cffi Changeset: r62198:b37a4cb55f8a Date: 2013-03-07 19:54 -0500 http://bitbucket.org/pypy/pypy/changeset/b37a4cb55f8a/ Log: port some sqlite fixes/cleanups from default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -24,10 +24,22 @@ # Note: This software has been modified for use in PyPy. from collections import OrderedDict +from functools import wraps import datetime +import string import sys import weakref -from threading import _get_ident as thread_get_ident +from threading import _get_ident as _thread_get_ident + +if sys.version_info[0] >= 3: + StandardError = Exception + long = int + xrange = range + basestring = unicode = str + buffer = memoryview + _BLOB_TYPE = bytes +else: + _BLOB_TYPE = buffer from cffi import FFI @@ -346,11 +358,21 @@ return factory(database, **kwargs) -def unicode_text_factory(x): +def _unicode_text_factory(x): return unicode(x, 'utf-8') +if sys.version_info[0] < 3: + def OptimizedUnicode(s): + try: + val = unicode(s, "ascii").encode("ascii") + except UnicodeDecodeError: + val = unicode(s, "utf-8") + return val +else: + OptimizedUnicode = _unicode_text_factory -class StatementCache(object): + +class _StatementCache(object): def __init__(self, connection, maxcount): self.connection = connection self.maxcount = maxcount @@ -364,7 +386,7 @@ self.cache[sql] = stat if len(self.cache) > self.maxcount: self.cache.popitem(0) - # + if stat.in_use: stat = Statement(self.connection, sql) stat.set_row_factory(row_factory) @@ -377,7 +399,7 @@ cached_statements=100): db_star = ffi.new('sqlite3 **') if isinstance(database, unicode): - database = database.encode("utf-8") + database = database.encode('utf-8') if lib.sqlite3_open(database, db_star) != lib.SQLITE_OK: raise OperationalError("Could not open database") self.db = db_star[0] @@ -385,14 +407,14 @@ timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds lib.sqlite3_busy_timeout(self.db, timeout) - self.text_factory = unicode_text_factory + self.text_factory = _unicode_text_factory self.closed = False self.statements = [] self.statement_counter = 0 self.row_factory = None self._isolation_level = isolation_level self.detect_types = detect_types - self.statement_cache = StatementCache(self, cached_statements) + self.statement_cache = _StatementCache(self, cached_statements) self.cursors = [] @@ -412,7 +434,49 @@ self.aggregate_instances = {} self._collations = {} if check_same_thread: - self.thread_ident = thread_get_ident() + self.thread_ident = _thread_get_ident() + + def close(self): + self._check_thread() + if self.closed: + return + for statement in self.statements: + obj = statement() + if obj is not None: + obj.finalize() + + self.closed = True + ret = lib.sqlite3_close(self.db) + self._reset_cursors() + if ret != lib.SQLITE_OK: + raise self._get_exception(ret) + + def _check_closed(self): + if getattr(self, 'closed', True): + raise ProgrammingError("Cannot operate on a closed database.") + + def _check_closed_wrap(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + self._check_closed() + return func(self, *args, **kwargs) + return wrapper + + def _check_thread(self): + if not hasattr(self, 'thread_ident'): + return + if self.thread_ident != _thread_get_ident(): + raise ProgrammingError( + "SQLite objects created in a thread can only be used in that " + "same thread. The object was created in thread id %d and this " + "is thread id %d", self.thread_ident, _thread_get_ident()) + + def _check_thread_wrap(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + self._check_thread() + return func(self, *args, **kwargs) + return wrapper def _get_exception(self, error_code=None): if error_code is None: @@ -454,21 +518,19 @@ self.statements = [ref for ref in self.statements if ref() is not None] - def _check_thread(self): - if not hasattr(self, 'thread_ident'): - return - if self.thread_ident != thread_get_ident(): - raise ProgrammingError( - "SQLite objects created in a thread can only be used in that " - "same thread. The object was created in thread id %d and this " - "is thread id %d", self.thread_ident, thread_get_ident()) - def _reset_cursors(self): for cursor_ref in self.cursors: cursor = cursor_ref() if cursor: cursor.reset = True + @_check_thread_wrap + @_check_closed_wrap + def __call__(self, sql): + if not isinstance(sql, basestring): + raise Warning("SQL is of wrong type. Must be string or unicode.") + return self.statement_cache.get(sql, self.row_factory) + def cursor(self, factory=None): self._check_thread() self._check_closed() @@ -479,63 +541,41 @@ cur.row_factory = self.row_factory return cur + def execute(self, *args): + cur = self.cursor() + return cur.execute(*args) + def executemany(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.executemany(*args) - def execute(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory - return cur.execute(*args) - def executescript(self, *args): - self._check_closed() - cur = Cursor(self) - if self.row_factory is not None: - cur.row_factory = self.row_factory + cur = self.cursor() return cur.executescript(*args) - def __call__(self, sql): - self._check_closed() - if not isinstance(sql, (str, unicode)): - raise Warning("SQL is of wrong type. Must be string or unicode.") - statement = self.statement_cache.get(sql, self.row_factory) - return statement - - def _get_isolation_level(self): - return self._isolation_level - - def _set_isolation_level(self, val): - if val is None: - self.commit() - if isinstance(val, unicode): - val = str(val) - self._isolation_level = val - isolation_level = property(_get_isolation_level, _set_isolation_level) + def iterdump(self): + from sqlite3.dump import _iterdump + return _iterdump(self) def _begin(self): self._check_closed() if self._isolation_level is None: return - if lib.sqlite3_get_autocommit(self.db): - sql = "BEGIN " + self._isolation_level - statement_star = ffi.new('sqlite3_stmt **') - next_char = ffi.new('char **') - ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, - next_char) - try: - if ret != lib.SQLITE_OK: - raise self._get_exception(ret) - ret = lib.sqlite3_step(statement_star[0]) - if ret != lib.SQLITE_DONE: - raise self._get_exception(ret) - finally: - lib.sqlite3_finalize(statement_star[0]) + if not lib.sqlite3_get_autocommit(self.db): + return + sql = "BEGIN " + self._isolation_level + statement_star = ffi.new('sqlite3_stmt **') + next_char = ffi.new('char **') + ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, + next_char) + try: + if ret != lib.SQLITE_OK: + raise self._get_exception(ret) + ret = lib.sqlite3_step(statement_star[0]) + if ret != lib.SQLITE_DONE: + raise self._get_exception(ret) + finally: + lib.sqlite3_finalize(statement_star[0]) def commit(self): self._check_thread() @@ -548,10 +588,9 @@ if obj is not None: obj.reset() - sql = "COMMIT" statement_star = ffi.new('sqlite3_stmt **') next_char = ffi.new('char **') - ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, + ret = lib.sqlite3_prepare_v2(self.db, b"COMMIT", -1, statement_star, next_char) try: if ret != lib.SQLITE_OK: @@ -573,10 +612,9 @@ if obj is not None: obj.reset() - sql = "ROLLBACK" statement_star = ffi.new('sqlite3_stmt **') next_char = ffi.new('char **') - ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, + ret = lib.sqlite3_prepare_v2(self.db, b"ROLLBACK", -1, statement_star, next_char) try: if ret != lib.SQLITE_OK: @@ -588,10 +626,6 @@ lib.sqlite3_finalize(statement_star[0]) self._reset_cursors() - def _check_closed(self): - if getattr(self, 'closed', True): - raise ProgrammingError("Cannot operate on a closed database.") - def __enter__(self): return self @@ -601,30 +635,88 @@ else: self.rollback() - def _get_total_changes(self): - return lib.sqlite3_total_changes(self.db) - total_changes = property(_get_total_changes) + @_check_thread_wrap + @_check_closed_wrap + def create_function(self, name, num_args, callback): + try: + closure = self.func_cache[callback] + except KeyError: + @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)") + def closure(context, nargs, c_params): + _function_callback(callback, context, nargs, c_params) + self.func_cache[callback] = closure + ret = lib.sqlite3_create_function(self.db, name, num_args, + lib.SQLITE_UTF8, ffi.NULL, + closure, ffi.NULL, ffi.NULL) + if ret != lib.SQLITE_OK: + raise self.OperationalError("Error creating function") - def close(self): - self._check_thread() - if self.closed: - return - for statement in self.statements: - obj = statement() - if obj is not None: - obj.finalize() + @_check_thread_wrap + @_check_closed_wrap + def create_aggregate(self, name, num_args, cls): + try: + step_callback, final_callback = self._aggregates[cls] + except KeyError: + @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)") + def step_callback(context, argc, c_params): + res = lib.sqlite3_aggregate_context(context, + ffi.sizeof("size_t")) + aggregate_ptr = ffi.cast("size_t[1]", res) - self.closed = True - ret = lib.sqlite3_close(self.db) - self._reset_cursors() + if not aggregate_ptr[0]: + try: + aggregate = cls() + except Exception: + msg = (b"user-defined aggregate's '__init__' " + b"method raised error") + lib.sqlite3_result_error(context, msg, len(msg)) + return + aggregate_id = id(aggregate) + self.aggregate_instances[aggregate_id] = aggregate + aggregate_ptr[0] = aggregate_id + else: + aggregate = self.aggregate_instances[aggregate_ptr[0]] + + params = _convert_params(context, argc, c_params) + try: + aggregate.step(*params) + except Exception: + msg = (b"user-defined aggregate's 'step' " + b"method raised error") + lib.sqlite3_result_error(context, msg, len(msg)) + + @ffi.callback("void(sqlite3_context*)") + def final_callback(context): + res = lib.sqlite3_aggregate_context(context, + ffi.sizeof("size_t")) + aggregate_ptr = ffi.cast("size_t[1]", res) + + if aggregate_ptr[0]: + aggregate = self.aggregate_instances[aggregate_ptr[0]] + try: + val = aggregate.finalize() + except Exception: + msg = (b"user-defined aggregate's 'finalize' " + b"method raised error") + lib.sqlite3_result_error(context, msg, len(msg)) + else: + _convert_result(context, val) + finally: + del self.aggregate_instances[aggregate_ptr[0]] + + self._aggregates[cls] = step_callback, final_callback + + ret = lib.sqlite3_create_function(self.db, name, num_args, + lib.SQLITE_UTF8, ffi.NULL, ffi.NULL, + step_callback, final_callback) if ret != lib.SQLITE_OK: raise self._get_exception(ret) + @_check_thread_wrap + @_check_closed_wrap def create_collation(self, name, callback): - self._check_thread() - self._check_closed() name = name.upper() - if not name.replace('_', '').isalnum(): + if not all(c in string.ascii_uppercase + string.digits + '_' for c in name): raise ProgrammingError("invalid character in collation name") if callback is None: @@ -648,9 +740,28 @@ if ret != lib.SQLITE_OK: raise self._get_exception(ret) + @_check_thread_wrap + @_check_closed_wrap + def set_authorizer(self, callback): + try: + authorizer = self.func_cache[callback] + except KeyError: + @ffi.callback("int(void*, int, const char*, const char*, " + "const char*, const char*)") + def authorizer(userdata, action, arg1, arg2, dbname, source): + try: + return int(callback(action, arg1, arg2, dbname, source)) + except Exception: + return lib.SQLITE_DENY + self.func_cache[callback] = authorizer + + ret = lib.sqlite3_set_authorizer(self.db, authorizer, ffi.NULL) + if ret != lib.SQLITE_OK: + raise self._get_exception(ret) + + @_check_thread_wrap + @_check_closed_wrap def set_progress_handler(self, callable, nsteps): - self._check_thread() - self._check_closed() if callable is None: progress_handler = ffi.NULL else: @@ -670,113 +781,26 @@ lib.sqlite3_progress_handler(self.db, nsteps, progress_handler, ffi.NULL) - def set_authorizer(self, callback): - self._check_thread() + def __get_total_changes(self): self._check_closed() + return lib.sqlite3_total_changes(self.db) + total_changes = property(__get_total_changes) - try: - authorizer = self.func_cache[callback] - except KeyError: - @ffi.callback("int(void*, int, const char*, const char*, " - "const char*, const char*)") - def authorizer(userdata, action, arg1, arg2, dbname, source): - try: - return int(callback(action, arg1, arg2, dbname, source)) - except Exception: - return lib.SQLITE_DENY - self.func_cache[callback] = authorizer + def __get_isolation_level(self): + return self._isolation_level - ret = lib.sqlite3_set_authorizer(self.db, authorizer, ffi.NULL) - if ret != lib.SQLITE_OK: - raise self._get_exception(ret) - - def create_function(self, name, num_args, callback): - self._check_thread() - self._check_closed() - try: - closure = self.func_cache[callback] - except KeyError: - @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)") - def closure(context, nargs, c_params): - function_callback(callback, context, nargs, c_params) - self.func_cache[callback] = closure - ret = lib.sqlite3_create_function(self.db, name, num_args, - lib.SQLITE_UTF8, ffi.NULL, - closure, ffi.NULL, ffi.NULL) - if ret != lib.SQLITE_OK: - raise self.OperationalError("Error creating function") - - def create_aggregate(self, name, num_args, cls): - self._check_thread() - self._check_closed() - - try: - step_callback, final_callback = self._aggregates[cls] - except KeyError: - @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)") - def step_callback(context, argc, c_params): - res = lib.sqlite3_aggregate_context(context, - ffi.sizeof("size_t")) - aggregate_ptr = ffi.cast("size_t[1]", res) - - if not aggregate_ptr[0]: - try: - aggregate = cls() - except Exception: - msg = ("user-defined aggregate's '__init__' " - "method raised error") - lib.sqlite3_result_error(context, msg, len(msg)) - return - aggregate_id = id(aggregate) - self.aggregate_instances[aggregate_id] = aggregate - aggregate_ptr[0] = aggregate_id - else: - aggregate = self.aggregate_instances[aggregate_ptr[0]] - - params = _convert_params(context, argc, c_params) - try: - aggregate.step(*params) - except Exception: - msg = ("user-defined aggregate's 'step' " - "method raised error") - lib.sqlite3_result_error(context, msg, len(msg)) - - @ffi.callback("void(sqlite3_context*)") - def final_callback(context): - res = lib.sqlite3_aggregate_context(context, - ffi.sizeof("size_t")) - aggregate_ptr = ffi.cast("size_t[1]", res) - - if aggregate_ptr[0]: - aggregate = self.aggregate_instances[aggregate_ptr[0]] - try: - val = aggregate.finalize() - except Exception: - msg = ("user-defined aggregate's 'finalize' " - "method raised error") - lib.sqlite3_result_error(context, msg, len(msg)) - else: - _convert_result(context, val) - finally: - del self.aggregate_instances[aggregate_ptr[0]] - - self._aggregates[cls] = step_callback, final_callback - - ret = lib.sqlite3_create_function(self.db, name, num_args, - lib.SQLITE_UTF8, ffi.NULL, ffi.NULL, - step_callback, final_callback) - if ret != lib.SQLITE_OK: - raise self._get_exception(ret) - - def iterdump(self): - from sqlite3.dump import _iterdump - return _iterdump(self) + def __set_isolation_level(self, val): + if val is None: + self.commit() + if isinstance(val, unicode): + val = str(val) + self._isolation_level = val + isolation_level = property(__get_isolation_level, __set_isolation_level) if hasattr(lib, 'sqlite3_enable_load_extension'): + @_check_thread_wrap + @_check_closed_wrap def enable_load_extension(self, enabled): - self._check_thread() - self._check_closed() - rc = lib.sqlite3_enable_load_extension(self.db, int(enabled)) if rc != lib.SQLITE_OK: raise OperationalError("Error enabling load extension") @@ -1074,43 +1098,44 @@ self.row_cast_map.append(converter) - def _check_decodable(self, param): - if self.con.text_factory in (unicode, OptimizedUnicode, - unicode_text_factory): - for c in param: - if ord(c) & 0x80 != 0: - raise self.con.ProgrammingError( + if sys.version_info[0] < 3: + def __check_decodable(self, param): + if self.con.text_factory in (unicode, OptimizedUnicode, + _unicode_text_factory): + for c in param: + if ord(c) & 0x80 != 0: + raise self.con.ProgrammingError( "You must not use 8-bit bytestrings unless " "you use a text_factory that can interpret " "8-bit bytestrings (like text_factory = str). " "It is highly recommended that you instead " "just switch your application to Unicode strings.") - def set_param(self, idx, param): + def __set_param(self, idx, param): cvt = converters.get(type(param)) if cvt is not None: - cvt = param = cvt(param) + param = cvt(param) param = adapt(param) if param is None: lib.sqlite3_bind_null(self.statement, idx) - elif type(param) in (bool, int, long): + elif isinstance(param, (bool, int, long)): if -2147483648 <= param <= 2147483647: lib.sqlite3_bind_int(self.statement, idx, param) else: lib.sqlite3_bind_int64(self.statement, idx, param) - elif type(param) is float: + elif isinstance(param, float): lib.sqlite3_bind_double(self.statement, idx, param) - elif isinstance(param, str): - self._check_decodable(param) - lib.sqlite3_bind_text(self.statement, idx, param, len(param), - _SQLITE_TRANSIENT) elif isinstance(param, unicode): param = param.encode("utf-8") lib.sqlite3_bind_text(self.statement, idx, param, len(param), _SQLITE_TRANSIENT) - elif type(param) is buffer: + elif isinstance(param, str): + self.__check_decodable(param) + lib.sqlite3_bind_text(self.statement, idx, param, len(param), + _SQLITE_TRANSIENT) + elif isinstance(param, (buffer, bytes)): lib.sqlite3_bind_blob(self.statement, idx, str(param), len(param), _SQLITE_TRANSIENT) else: @@ -1139,7 +1164,7 @@ raise ProgrammingError("wrong number of arguments") for i in range(len(params)): - self.set_param(i + 1, params[i]) + self.__set_param(i + 1, params[i]) else: param_count = lib.sqlite3_bind_parameter_count(self.statement) for idx in range(1, param_count + 1): @@ -1152,7 +1177,7 @@ param = params[param_name] except KeyError: raise ProgrammingError("missing parameter '%s'" % param) - self.set_param(idx, param) + self.__set_param(idx, param) def next(self, cursor): self.con._check_closed() @@ -1181,23 +1206,21 @@ converter = self.row_cast_map[i] if converter is None: - if typ == lib.SQLITE_INTEGER: + if typ == lib.SQLITE_NULL: + val = None + elif typ == lib.SQLITE_INTEGER: val = lib.sqlite3_column_int64(self.statement, i) - if -sys.maxint - 1 <= val <= sys.maxint: - val = int(val) elif typ == lib.SQLITE_FLOAT: val = lib.sqlite3_column_double(self.statement, i) - elif typ == lib.SQLITE_BLOB: - blob_len = lib.sqlite3_column_bytes(self.statement, i) - blob = lib.sqlite3_column_blob(self.statement, i) - val = buffer(ffi.buffer(blob, blob_len)) - elif typ == lib.SQLITE_NULL: - val = None elif typ == lib.SQLITE_TEXT: + text = lib.sqlite3_column_text(self.statement, i) text_len = lib.sqlite3_column_bytes(self.statement, i) - text = lib.sqlite3_column_text(self.statement, i) val = ffi.buffer(text, text_len)[:] val = self.con.text_factory(val) + elif typ == lib.SQLITE_BLOB: + blob = lib.sqlite3_column_blob(self.statement, i) + blob_len = lib.sqlite3_column_bytes(self.statement, i) + val = _BLOB_TYPE(ffi.buffer(blob, blob_len)) else: blob = lib.sqlite3_column_blob(self.statement, i) if not blob: @@ -1324,22 +1347,19 @@ _params = [] for i in range(nargs): typ = lib.sqlite3_value_type(params[i]) - if typ == lib.SQLITE_INTEGER: + if typ == lib.SQLITE_NULL: + val = None + elif typ == lib.SQLITE_INTEGER: val = lib.sqlite3_value_int64(params[i]) - if -sys.maxint - 1 <= val <= sys.maxint: - val = int(val) elif typ == lib.SQLITE_FLOAT: val = lib.sqlite3_value_double(params[i]) - elif typ == lib.SQLITE_BLOB: - blob_len = lib.sqlite3_value_bytes(params[i]) - blob = lib.sqlite3_value_blob(params[i]) - val = buffer(ffi.buffer(blob, blob_len)) - elif typ == lib.SQLITE_NULL: - val = None elif typ == lib.SQLITE_TEXT: val = lib.sqlite3_value_text(params[i]) - # XXX changed from con.text_factory val = unicode(ffi.string(val), 'utf-8') + elif typ == lib.SQLITE_BLOB: + blob = lib.sqlite3_value_blob(params[i]) + blob_len = lib.sqlite3_value_bytes(params[i]) + val = _BLOB_TYPE(ffi.buffer(blob, blob_len)) else: raise NotImplementedError _params.append(val) @@ -1351,26 +1371,25 @@ lib.sqlite3_result_null(con) elif isinstance(val, (bool, int, long)): lib.sqlite3_result_int64(con, int(val)) - elif isinstance(val, str): - # XXX ignoring unicode issue - lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT) + elif isinstance(val, float): + lib.sqlite3_result_double(con, val) elif isinstance(val, unicode): val = val.encode('utf-8') lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT) - elif isinstance(val, float): - lib.sqlite3_result_double(con, val) - elif isinstance(val, buffer): + elif isinstance(val, str): + lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT) + elif isinstance(val, (buffer, bytes)): lib.sqlite3_result_blob(con, str(val), len(val), _SQLITE_TRANSIENT) else: raise NotImplementedError -def function_callback(real_cb, context, nargs, c_params): +def _function_callback(real_cb, context, nargs, c_params): params = _convert_params(context, nargs, c_params) try: val = real_cb(*params) except Exception: - msg = "user-defined function raised exception" + msg = b"user-defined function raised exception" lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) @@ -1411,10 +1430,8 @@ microseconds = int(timepart_full[1]) else: microseconds = 0 - - val = datetime.datetime(year, month, day, hours, minutes, seconds, - microseconds) - return val + return datetime.datetime(year, month, day, hours, minutes, seconds, + microseconds) register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) @@ -1451,11 +1468,3 @@ return val register_adapters_and_converters() - - -def OptimizedUnicode(s): - try: - val = unicode(s, "ascii").encode("ascii") - except UnicodeDecodeError: - val = unicode(s, "utf-8") - return val From noreply at buildbot.pypy.org Fri Mar 8 02:18:43 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 02:18:43 +0100 (CET) Subject: [pypy-commit] pypy default: avoid leaking internal names from _sqlite3 Message-ID: <20130308011843.7A7E91C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62199:574c8461a2cf Date: 2013-03-07 19:28 -0500 http://bitbucket.org/pypy/pypy/changeset/574c8461a2cf/ Log: avoid leaking internal names from _sqlite3 diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -40,69 +40,69 @@ xrange = range basestring = unicode = str buffer = memoryview - BLOB_TYPE = bytes + _BLOB_TYPE = bytes else: - BLOB_TYPE = buffer + _BLOB_TYPE = buffer -names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() -for name in names: - try: - sqlite = cdll.LoadLibrary(name) - break - except OSError: - continue -else: - raise ImportError("Could not load C-library, tried: %s" % (names,)) -# pysqlite version information -version = "2.6.0" +def load_library(names): + for name in names: + try: + return cdll.LoadLibrary(name) + except OSError: + pass + else: + raise ImportError("Could not load C-library, tried: %s" % (names,)) -# pysqlite constants -PARSE_COLNAMES = 1 -PARSE_DECLTYPES = 2 +_lib = load_library( + "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split()) +del load_library ########################################## # BEGIN Wrapped SQLite C API and constants ########################################## -SQLITE_OK = 0 -SQLITE_ERROR = 1 -SQLITE_INTERNAL = 2 -SQLITE_PERM = 3 -SQLITE_ABORT = 4 -SQLITE_BUSY = 5 -SQLITE_LOCKED = 6 -SQLITE_NOMEM = 7 -SQLITE_READONLY = 8 -SQLITE_INTERRUPT = 9 -SQLITE_IOERR = 10 -SQLITE_CORRUPT = 11 -SQLITE_NOTFOUND = 12 -SQLITE_FULL = 13 -SQLITE_CANTOPEN = 14 -SQLITE_PROTOCOL = 15 -SQLITE_EMPTY = 16 -SQLITE_SCHEMA = 17 -SQLITE_TOOBIG = 18 -SQLITE_CONSTRAINT = 19 -SQLITE_MISMATCH = 20 -SQLITE_MISUSE = 21 -SQLITE_NOLFS = 22 -SQLITE_AUTH = 23 -SQLITE_FORMAT = 24 -SQLITE_RANGE = 25 -SQLITE_NOTADB = 26 -SQLITE_ROW = 100 -SQLITE_DONE = 101 -SQLITE_INTEGER = 1 -SQLITE_FLOAT = 2 -SQLITE_BLOB = 4 -SQLITE_NULL = 5 -SQLITE_TEXT = 3 -SQLITE3_TEXT = 3 +_lib.SQLITE_OK = 0 +_lib.SQLITE_ERROR = 1 +_lib.SQLITE_INTERNAL = 2 +_lib.SQLITE_PERM = 3 +_lib.SQLITE_ABORT = 4 +_lib.SQLITE_BUSY = 5 +_lib.SQLITE_LOCKED = 6 +_lib.SQLITE_NOMEM = 7 +_lib.SQLITE_READONLY = 8 +_lib.SQLITE_INTERRUPT = 9 +_lib.SQLITE_IOERR = 10 +_lib.SQLITE_CORRUPT = 11 +_lib.SQLITE_NOTFOUND = 12 +_lib.SQLITE_FULL = 13 +_lib.SQLITE_CANTOPEN = 14 +_lib.SQLITE_PROTOCOL = 15 +_lib.SQLITE_EMPTY = 16 +_lib.SQLITE_SCHEMA = 17 +_lib.SQLITE_TOOBIG = 18 +_lib.SQLITE_CONSTRAINT = 19 +_lib.SQLITE_MISMATCH = 20 +_lib.SQLITE_MISUSE = 21 +_lib.SQLITE_NOLFS = 22 +_lib.SQLITE_AUTH = 23 +_lib.SQLITE_FORMAT = 24 +_lib.SQLITE_RANGE = 25 +_lib.SQLITE_NOTADB = 26 +_lib.SQLITE_ROW = 100 +_lib.SQLITE_DONE = 101 -SQLITE_TRANSIENT = cast(-1, c_void_p) -SQLITE_UTF8 = 1 +_lib.SQLITE_INTEGER = 1 +_lib.SQLITE_FLOAT = 2 +_lib.SQLITE_TEXT = 3 +_lib.SQLITE_BLOB = 4 +_lib.SQLITE_NULL = 5 + +_lib.SQLITE_UTF8 = 1 + +_lib.SQLITE_TRANSIENT = cast(-1, c_void_p) + +SQLITE_OK = _lib.SQLITE_OK SQLITE_DENY = 1 SQLITE_IGNORE = 2 @@ -135,161 +135,177 @@ SQLITE_ALTER_TABLE = 26 SQLITE_REINDEX = 27 SQLITE_ANALYZE = 28 -SQLITE_CREATE_VTABLE = 29 -SQLITE_DROP_VTABLE = 30 -SQLITE_FUNCTION = 31 # SQLite C API -sqlite.sqlite3_value_int.argtypes = [c_void_p] -sqlite.sqlite3_value_int.restype = c_int +_lib.sqlite3_value_int.argtypes = [c_void_p] +_lib.sqlite3_value_int.restype = c_int -sqlite.sqlite3_value_int64.argtypes = [c_void_p] -sqlite.sqlite3_value_int64.restype = c_int64 +_lib.sqlite3_value_int64.argtypes = [c_void_p] +_lib.sqlite3_value_int64.restype = c_int64 -sqlite.sqlite3_value_blob.argtypes = [c_void_p] -sqlite.sqlite3_value_blob.restype = c_void_p +_lib.sqlite3_value_blob.argtypes = [c_void_p] +_lib.sqlite3_value_blob.restype = c_void_p -sqlite.sqlite3_value_bytes.argtypes = [c_void_p] -sqlite.sqlite3_value_bytes.restype = c_int +_lib.sqlite3_value_bytes.argtypes = [c_void_p] +_lib.sqlite3_value_bytes.restype = c_int -sqlite.sqlite3_value_double.argtypes = [c_void_p] -sqlite.sqlite3_value_double.restype = c_double +_lib.sqlite3_value_double.argtypes = [c_void_p] +_lib.sqlite3_value_double.restype = c_double -sqlite.sqlite3_value_text.argtypes = [c_void_p] -sqlite.sqlite3_value_text.restype = c_char_p +_lib.sqlite3_value_text.argtypes = [c_void_p] +_lib.sqlite3_value_text.restype = c_char_p -sqlite.sqlite3_value_type.argtypes = [c_void_p] -sqlite.sqlite3_value_type.restype = c_int +_lib.sqlite3_value_type.argtypes = [c_void_p] +_lib.sqlite3_value_type.restype = c_int -sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p] -sqlite.sqlite3_bind_blob.restype = c_int -sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] -sqlite.sqlite3_bind_double.restype = c_int -sqlite.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int] -sqlite.sqlite3_bind_int.restype = c_int -sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64] -sqlite.sqlite3_bind_int64.restype = c_int -sqlite.sqlite3_bind_null.argtypes = [c_void_p, c_int] -sqlite.sqlite3_bind_null.restype = c_int -sqlite.sqlite3_bind_parameter_count.argtypes = [c_void_p] -sqlite.sqlite3_bind_parameter_count.restype = c_int -sqlite.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p] -sqlite.sqlite3_bind_parameter_index.restype = c_int -sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] -sqlite.sqlite3_bind_parameter_name.restype = c_char_p -sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p] -sqlite.sqlite3_bind_text.restype = c_int -sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] -sqlite.sqlite3_busy_timeout.restype = c_int -sqlite.sqlite3_changes.argtypes = [c_void_p] -sqlite.sqlite3_changes.restype = c_int -sqlite.sqlite3_close.argtypes = [c_void_p] -sqlite.sqlite3_close.restype = c_int -sqlite.sqlite3_column_blob.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_blob.restype = c_void_p -sqlite.sqlite3_column_bytes.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_bytes.restype = c_int -sqlite.sqlite3_column_count.argtypes = [c_void_p] -sqlite.sqlite3_column_count.restype = c_int -sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_decltype.restype = c_char_p -sqlite.sqlite3_column_double.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_double.restype = c_double -sqlite.sqlite3_column_int64.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_int64.restype = c_int64 -sqlite.sqlite3_column_name.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_name.restype = c_char_p -sqlite.sqlite3_column_text.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_text.restype = POINTER(c_char) -sqlite.sqlite3_column_type.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_type.restype = c_int -sqlite.sqlite3_complete.argtypes = [c_char_p] -sqlite.sqlite3_complete.restype = c_int -sqlite.sqlite3_errcode.restype = c_int -sqlite.sqlite3_errmsg.argtypes = [c_void_p] -sqlite.sqlite3_errmsg.restype = c_char_p -sqlite.sqlite3_finalize.argtypes = [c_void_p] -sqlite.sqlite3_finalize.restype = c_int -sqlite.sqlite3_get_autocommit.argtypes = [c_void_p] -sqlite.sqlite3_get_autocommit.restype = c_int -sqlite.sqlite3_last_insert_rowid.argtypes = [c_void_p] -sqlite.sqlite3_last_insert_rowid.restype = c_int64 -sqlite.sqlite3_libversion.argtypes = [] -sqlite.sqlite3_libversion.restype = c_char_p -sqlite.sqlite3_open.argtypes = [c_char_p, c_void_p] -sqlite.sqlite3_open.restype = c_int -sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] -sqlite.sqlite3_prepare.restype = c_int -sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] -sqlite.sqlite3_prepare_v2.restype = c_int -sqlite.sqlite3_step.argtypes = [c_void_p] -sqlite.sqlite3_step.restype = c_int -sqlite.sqlite3_reset.argtypes = [c_void_p] -sqlite.sqlite3_reset.restype = c_int -sqlite.sqlite3_total_changes.argtypes = [c_void_p] -sqlite.sqlite3_total_changes.restype = c_int +_lib.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p] +_lib.sqlite3_bind_blob.restype = c_int +_lib.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] +_lib.sqlite3_bind_double.restype = c_int +_lib.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int] +_lib.sqlite3_bind_int.restype = c_int +_lib.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64] +_lib.sqlite3_bind_int64.restype = c_int +_lib.sqlite3_bind_null.argtypes = [c_void_p, c_int] +_lib.sqlite3_bind_null.restype = c_int +_lib.sqlite3_bind_parameter_count.argtypes = [c_void_p] +_lib.sqlite3_bind_parameter_count.restype = c_int +_lib.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p] +_lib.sqlite3_bind_parameter_index.restype = c_int +_lib.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] +_lib.sqlite3_bind_parameter_name.restype = c_char_p +_lib.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p] +_lib.sqlite3_bind_text.restype = c_int +_lib.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] +_lib.sqlite3_busy_timeout.restype = c_int +_lib.sqlite3_changes.argtypes = [c_void_p] +_lib.sqlite3_changes.restype = c_int +_lib.sqlite3_close.argtypes = [c_void_p] +_lib.sqlite3_close.restype = c_int +_lib.sqlite3_column_blob.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_blob.restype = c_void_p +_lib.sqlite3_column_bytes.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_bytes.restype = c_int +_lib.sqlite3_column_count.argtypes = [c_void_p] +_lib.sqlite3_column_count.restype = c_int +_lib.sqlite3_column_decltype.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_decltype.restype = c_char_p +_lib.sqlite3_column_double.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_double.restype = c_double +_lib.sqlite3_column_int64.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_int64.restype = c_int64 +_lib.sqlite3_column_name.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_name.restype = c_char_p +_lib.sqlite3_column_text.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_text.restype = POINTER(c_char) +_lib.sqlite3_column_type.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_type.restype = c_int +_lib.sqlite3_complete.argtypes = [c_char_p] +_lib.sqlite3_complete.restype = c_int +_lib.sqlite3_errcode.restype = c_int +_lib.sqlite3_errmsg.argtypes = [c_void_p] +_lib.sqlite3_errmsg.restype = c_char_p +_lib.sqlite3_finalize.argtypes = [c_void_p] +_lib.sqlite3_finalize.restype = c_int +_lib.sqlite3_get_autocommit.argtypes = [c_void_p] +_lib.sqlite3_get_autocommit.restype = c_int +_lib.sqlite3_last_insert_rowid.argtypes = [c_void_p] +_lib.sqlite3_last_insert_rowid.restype = c_int64 +_lib.sqlite3_libversion.argtypes = [] +_lib.sqlite3_libversion.restype = c_char_p +_lib.sqlite3_open.argtypes = [c_char_p, c_void_p] +_lib.sqlite3_open.restype = c_int +_lib.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] +_lib.sqlite3_prepare.restype = c_int +_lib.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] +_lib.sqlite3_prepare_v2.restype = c_int +_lib.sqlite3_step.argtypes = [c_void_p] +_lib.sqlite3_step.restype = c_int +_lib.sqlite3_reset.argtypes = [c_void_p] +_lib.sqlite3_reset.restype = c_int +_lib.sqlite3_total_changes.argtypes = [c_void_p] +_lib.sqlite3_total_changes.restype = c_int -sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] -sqlite.sqlite3_result_blob.restype = None -sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64] -sqlite.sqlite3_result_int64.restype = None -sqlite.sqlite3_result_null.argtypes = [c_void_p] -sqlite.sqlite3_result_null.restype = None -sqlite.sqlite3_result_double.argtypes = [c_void_p, c_double] -sqlite.sqlite3_result_double.restype = None -sqlite.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int] -sqlite.sqlite3_result_error.restype = None -sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] -sqlite.sqlite3_result_text.restype = None +_lib.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] +_lib.sqlite3_result_blob.restype = None +_lib.sqlite3_result_int64.argtypes = [c_void_p, c_int64] +_lib.sqlite3_result_int64.restype = None +_lib.sqlite3_result_null.argtypes = [c_void_p] +_lib.sqlite3_result_null.restype = None +_lib.sqlite3_result_double.argtypes = [c_void_p, c_double] +_lib.sqlite3_result_double.restype = None +_lib.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int] +_lib.sqlite3_result_error.restype = None +_lib.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] +_lib.sqlite3_result_text.restype = None -_HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") +_HAS_LOAD_EXTENSION = hasattr(_lib, "sqlite3_enable_load_extension") if _HAS_LOAD_EXTENSION: - sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] - sqlite.sqlite3_enable_load_extension.restype = c_int + _lib.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] + _lib.sqlite3_enable_load_extension.restype = c_int ########################################## # END Wrapped SQLite C API and constants ########################################## +# pysqlite version information +version = "2.6.0" + +# pysqlite constants +PARSE_COLNAMES = 1 +PARSE_DECLTYPES = 2 + # SQLite version information -sqlite_version = str(sqlite.sqlite3_libversion().decode('ascii')) +sqlite_version = str(_lib.sqlite3_libversion().decode('ascii')) + class Error(StandardError): pass + class Warning(StandardError): pass + class InterfaceError(Error): pass + class DatabaseError(Error): pass + class InternalError(DatabaseError): pass + class OperationalError(DatabaseError): pass + class ProgrammingError(DatabaseError): pass + class IntegrityError(DatabaseError): pass + class DataError(DatabaseError): pass + class NotSupportedError(DatabaseError): pass + def connect(database, **kwargs): factory = kwargs.get("factory", Connection) return factory(database, **kwargs) -def unicode_text_factory(x): + +def _unicode_text_factory(x): return unicode(x, 'utf-8') if sys.version_info[0] < 3: @@ -300,7 +316,7 @@ val = unicode(s, "utf-8") return val else: - OptimizedUnicode = unicode_text_factory + OptimizedUnicode = _unicode_text_factory class _StatementCache(object): @@ -335,14 +351,14 @@ if isinstance(database, unicode): database = database.encode('utf-8') - if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: + if _lib.sqlite3_open(database, byref(self._db)) != _lib.SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds - sqlite.sqlite3_busy_timeout(self._db, timeout) + _lib.sqlite3_busy_timeout(self._db, timeout) self.row_factory = None - self.text_factory = unicode_text_factory + self.text_factory = _unicode_text_factory self._detect_types = detect_types self._in_transaction = False @@ -373,7 +389,7 @@ def __del__(self): if self._db: - sqlite.sqlite3_close(self._db) + _lib.sqlite3_close(self._db) def close(self): self._check_thread() @@ -384,8 +400,8 @@ obj._finalize() if self._db: - ret = sqlite.sqlite3_close(self._db) - if ret != SQLITE_OK: + ret = _lib.sqlite3_close(self._db) + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) self._db = None @@ -423,26 +439,29 @@ def _get_exception(self, error_code=None): if error_code is None: - error_code = sqlite.sqlite3_errcode(self._db) - error_message = sqlite.sqlite3_errmsg(self._db).decode('utf-8') + error_code = _lib.sqlite3_errcode(self._db) + error_message = _lib.sqlite3_errmsg(self._db).decode('utf-8') - if error_code == SQLITE_OK: + if error_code == _lib.SQLITE_OK: raise ValueError("error signalled but got SQLITE_OK") - elif error_code in (SQLITE_INTERNAL, SQLITE_NOTFOUND): + elif error_code in (_lib.SQLITE_INTERNAL, _lib.SQLITE_NOTFOUND): exc = InternalError - elif error_code == SQLITE_NOMEM: + elif error_code == _lib.SQLITE_NOMEM: exc = MemoryError - elif error_code in (SQLITE_ERROR, SQLITE_PERM, SQLITE_ABORT, SQLITE_BUSY, SQLITE_LOCKED, - SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, - SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): + elif error_code in ( + _lib.SQLITE_ERROR, _lib.SQLITE_PERM, _lib.SQLITE_ABORT, + _lib.SQLITE_BUSY, _lib.SQLITE_LOCKED, _lib.SQLITE_READONLY, + _lib.SQLITE_INTERRUPT, _lib.SQLITE_IOERR, _lib.SQLITE_FULL, + _lib.SQLITE_CANTOPEN, _lib.SQLITE_PROTOCOL, _lib.SQLITE_EMPTY, + _lib.SQLITE_SCHEMA): exc = OperationalError - elif error_code == SQLITE_CORRUPT: + elif error_code == _lib.SQLITE_CORRUPT: exc = DatabaseError - elif error_code == SQLITE_TOOBIG: + elif error_code == _lib.SQLITE_TOOBIG: exc = DataError - elif error_code in (SQLITE_CONSTRAINT, SQLITE_MISMATCH): + elif error_code in (_lib.SQLITE_CONSTRAINT, _lib.SQLITE_MISMATCH): exc = IntegrityError - elif error_code == SQLITE_MISUSE: + elif error_code == _lib.SQLITE_MISUSE: exc = ProgrammingError else: exc = DatabaseError @@ -492,17 +511,17 @@ def _begin(self): statement = c_void_p() - ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, + ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, byref(statement), None) try: - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(statement) + if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) self._in_transaction = True finally: - sqlite.sqlite3_finalize(statement) + _lib.sqlite3_finalize(statement) def commit(self): self._check_thread() @@ -516,17 +535,17 @@ obj._reset() statement = c_void_p() - ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, + ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, byref(statement), None) try: - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(statement) + if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) self._in_transaction = False finally: - sqlite.sqlite3_finalize(statement) + _lib.sqlite3_finalize(statement) def rollback(self): self._check_thread() @@ -545,17 +564,17 @@ cursor._reset = True statement = c_void_p() - ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, + ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, byref(statement), None) try: - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(statement) + if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) self._in_transaction = False finally: - sqlite.sqlite3_finalize(statement) + _lib.sqlite3_finalize(statement) def __enter__(self): return self @@ -573,18 +592,18 @@ c_closure, _ = self.__func_cache[callback] except KeyError: def closure(context, nargs, c_params): - function_callback(callback, context, nargs, c_params) + _function_callback(callback, context, nargs, c_params) c_closure = _FUNC(closure) self.__func_cache[callback] = c_closure, closure if isinstance(name, unicode): name = name.encode('utf-8') - ret = sqlite.sqlite3_create_function(self._db, name, num_args, - SQLITE_UTF8, None, + ret = _lib.sqlite3_create_function(self._db, name, num_args, + _lib.SQLITE_UTF8, None, c_closure, cast(None, _STEP), cast(None, _FINAL)) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self.OperationalError("Error creating function") @_check_thread_wrap @@ -595,7 +614,7 @@ except KeyError: def step_callback(context, argc, c_params): aggregate_ptr = cast( - sqlite.sqlite3_aggregate_context( + _lib.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) @@ -605,7 +624,7 @@ except Exception: msg = (b"user-defined aggregate's '__init__' " b"method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) self.__aggregate_instances[aggregate_id] = aggregate @@ -619,11 +638,11 @@ except Exception: msg = (b"user-defined aggregate's 'step' " b"method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) def final_callback(context): aggregate_ptr = cast( - sqlite.sqlite3_aggregate_context( + _lib.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) @@ -634,7 +653,7 @@ except Exception: msg = (b"user-defined aggregate's 'finalize' " b"method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) finally: @@ -648,12 +667,12 @@ if isinstance(name, unicode): name = name.encode('utf-8') - ret = sqlite.sqlite3_create_function(self._db, name, num_args, - SQLITE_UTF8, None, + ret = _lib.sqlite3_create_function(self._db, name, num_args, + _lib.SQLITE_UTF8, None, cast(None, _FUNC), c_step_callback, c_final_callback) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @_check_thread_wrap @@ -681,11 +700,11 @@ if isinstance(name, unicode): name = name.encode('utf-8') - ret = sqlite.sqlite3_create_collation(self._db, name, - SQLITE_UTF8, + ret = _lib.sqlite3_create_collation(self._db, name, + _lib.SQLITE_UTF8, None, c_collation_callback) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @_check_thread_wrap @@ -703,10 +722,10 @@ self.__func_cache[callback] = c_authorizer, authorizer - ret = sqlite.sqlite3_set_authorizer(self._db, + ret = _lib.sqlite3_set_authorizer(self._db, c_authorizer, None) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @_check_thread_wrap @@ -728,10 +747,10 @@ c_progress_handler = _PROGRESS(progress_handler) self.__func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self._db, nsteps, + ret = _lib.sqlite3_progress_handler(self._db, nsteps, c_progress_handler, None) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) if sys.version_info[0] >= 3: @@ -741,7 +760,7 @@ def __get_total_changes(self): self._check_closed() - return sqlite.sqlite3_total_changes(self._db) + return _lib.sqlite3_total_changes(self._db) total_changes = property(__get_total_changes) def __get_isolation_level(self): @@ -759,8 +778,8 @@ @_check_thread_wrap @_check_closed_wrap def enable_load_extension(self, enabled): - rc = sqlite.sqlite3_enable_load_extension(self._db, int(enabled)) - if rc != SQLITE_OK: + rc = _lib.sqlite3_enable_load_extension(self._db, int(enabled)) + if rc != _lib.SQLITE_OK: raise OperationalError("Error enabling load extension") @@ -841,17 +860,17 @@ self.__statement._set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.__statement._statement) - if ret not in (SQLITE_DONE, SQLITE_ROW): + ret = _lib.sqlite3_step(self.__statement._statement) + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): self.__statement._reset() self.__connection._in_transaction = \ - not sqlite.sqlite3_get_autocommit(self.__connection._db) + not _lib.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) if self.__statement._kind == Statement._DML: self.__statement._reset() - if self.__statement._kind == Statement._DQL and ret == SQLITE_ROW: + if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) else: @@ -860,7 +879,7 @@ self.__rowcount = -1 if self.__statement._kind == Statement._DML: - self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) + self.__rowcount = _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False @@ -887,14 +906,14 @@ self.__rowcount = 0 for params in many_params: self.__statement._set_params(params) - ret = sqlite.sqlite3_step(self.__statement._statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(self.__statement._statement) + if ret != _lib.SQLITE_DONE: self.__statement._reset() self.__connection._in_transaction = \ - not sqlite.sqlite3_get_autocommit(self.__connection._db) + not _lib.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__statement._reset() - self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) + self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False @@ -913,25 +932,25 @@ self.__connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) - if rc != SQLITE_OK: + rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) + if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) - rc = SQLITE_ROW - while rc == SQLITE_ROW: + rc = _lib.SQLITE_ROW + while rc == _lib.SQLITE_ROW: if not statement: - rc = SQLITE_OK + rc = _lib.SQLITE_OK else: - rc = sqlite.sqlite3_step(statement) + rc = _lib.sqlite3_step(statement) - if rc != SQLITE_DONE: - sqlite.sqlite3_finalize(statement) - if rc == SQLITE_OK: + if rc != _lib.SQLITE_DONE: + _lib.sqlite3_finalize(statement) + if rc == _lib.SQLITE_OK: return self else: raise self.__connection._get_exception(rc) - rc = sqlite.sqlite3_finalize(statement) - if rc != SQLITE_OK: + rc = _lib.sqlite3_finalize(statement) + if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) if not c_sql.value: @@ -989,7 +1008,7 @@ description = property(__get_description) def __get_lastrowid(self): - return sqlite.sqlite3_last_insert_rowid(self.__connection._db) + return _lib.sqlite3_last_insert_rowid(self.__connection._db) lastrowid = property(__get_lastrowid) def setinputsizes(self, *args): @@ -1026,13 +1045,13 @@ if isinstance(sql, unicode): sql = sql.encode('utf-8') - ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) - if ret == SQLITE_OK and self._statement.value is None: + ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) + if ret == _lib.SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) + ret = _lib.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) self._kind = Statement._DQL - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) next_char = next_char.value.decode('utf-8') @@ -1042,27 +1061,27 @@ def __del__(self): if self._statement: - sqlite.sqlite3_finalize(self._statement) + _lib.sqlite3_finalize(self._statement) def _finalize(self): if self._statement: - sqlite.sqlite3_finalize(self._statement) + _lib.sqlite3_finalize(self._statement) self._statement = None self._in_use = False def _reset(self): if self._in_use and self._statement: - ret = sqlite.sqlite3_reset(self._statement) + _lib.sqlite3_reset(self._statement) self._in_use = False self._exhausted = False def _build_row_cast_map(self): self.__row_cast_map = [] - for i in xrange(sqlite.sqlite3_column_count(self._statement)): + for i in xrange(_lib.sqlite3_column_count(self._statement)): converter = None if self.__con._detect_types & PARSE_COLNAMES: - colname = sqlite.sqlite3_column_name(self._statement, i) + colname = _lib.sqlite3_column_name(self._statement, i) if colname is not None: colname = colname.decode('utf-8') type_start = -1 @@ -1075,7 +1094,7 @@ converter = converters[key.upper()] if converter is None and self.__con._detect_types & PARSE_DECLTYPES: - decltype = sqlite.sqlite3_column_decltype(self._statement, i) + decltype = _lib.sqlite3_column_decltype(self._statement, i) if decltype is not None: decltype = decltype.decode('utf-8') decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" @@ -1088,7 +1107,7 @@ if sys.version_info[0] < 3: def __check_decodable(self, param): if self.__con.text_factory in (unicode, OptimizedUnicode, - unicode_text_factory): + _unicode_text_factory): for c in param: if ord(c) & 0x80 != 0: raise self.__con.ProgrammingError( @@ -1106,23 +1125,23 @@ param = adapt(param) if param is None: - rc = sqlite.sqlite3_bind_null(self._statement, idx) + rc = _lib.sqlite3_bind_null(self._statement, idx) elif isinstance(param, (bool, int, long)): if -2147483648 <= param <= 2147483647: - rc = sqlite.sqlite3_bind_int(self._statement, idx, param) + rc = _lib.sqlite3_bind_int(self._statement, idx, param) else: - rc = sqlite.sqlite3_bind_int64(self._statement, idx, param) + rc = _lib.sqlite3_bind_int64(self._statement, idx, param) elif isinstance(param, float): - rc = sqlite.sqlite3_bind_double(self._statement, idx, param) + rc = _lib.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, unicode): param = param.encode("utf-8") - rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, str): self.__check_decodable(param) - rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, (buffer, bytes)): param = bytes(param) - rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_blob(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) else: rc = -1 return rc @@ -1130,7 +1149,7 @@ def _set_params(self, params): self._in_use = True - num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) + num_params_needed = _lib.sqlite3_bind_parameter_count(self._statement) if isinstance(params, (tuple, list)) or \ not isinstance(params, dict) and \ hasattr(params, '__getitem__'): @@ -1145,12 +1164,12 @@ (num_params_needed, num_params)) for i in range(num_params): rc = self.__set_param(i + 1, params[i]) - if rc != SQLITE_OK: + if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter %d - " "probably unsupported type." % i) elif isinstance(params, dict): for i in range(1, num_params_needed + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) + param_name = _lib.sqlite3_bind_parameter_name(self._statement, i) if param_name is None: raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " @@ -1162,7 +1181,7 @@ raise ProgrammingError("You did not supply a value for " "binding %d." % i) rc = self.__set_param(i, param) - if rc != SQLITE_OK: + if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter :%s - " "probably unsupported type." % param_name) @@ -1174,47 +1193,47 @@ raise StopIteration item = self._item - ret = sqlite.sqlite3_step(self._statement) - if ret == SQLITE_DONE: + ret = _lib.sqlite3_step(self._statement) + if ret == _lib.SQLITE_DONE: self._exhausted = True self._item = None - elif ret != SQLITE_ROW: + elif ret != _lib.SQLITE_ROW: exc = self.__con._get_exception(ret) - sqlite.sqlite3_reset(self._statement) + _lib.sqlite3_reset(self._statement) raise exc self._readahead(cursor) return item def _readahead(self, cursor): - self.column_count = sqlite.sqlite3_column_count(self._statement) + self.column_count = _lib.sqlite3_column_count(self._statement) row = [] for i in xrange(self.column_count): - typ = sqlite.sqlite3_column_type(self._statement, i) + typ = _lib.sqlite3_column_type(self._statement, i) converter = self.__row_cast_map[i] if converter is None: - if typ == SQLITE_NULL: + if typ == _lib.SQLITE_NULL: val = None - elif typ == SQLITE_INTEGER: - val = sqlite.sqlite3_column_int64(self._statement, i) - elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_column_double(self._statement, i) - elif typ == SQLITE_TEXT: - text = sqlite.sqlite3_column_text(self._statement, i) - text_len = sqlite.sqlite3_column_bytes(self._statement, i) + elif typ == _lib.SQLITE_INTEGER: + val = _lib.sqlite3_column_int64(self._statement, i) + elif typ == _lib.SQLITE_FLOAT: + val = _lib.sqlite3_column_double(self._statement, i) + elif typ == _lib.SQLITE_TEXT: + text = _lib.sqlite3_column_text(self._statement, i) + text_len = _lib.sqlite3_column_bytes(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) - elif typ == SQLITE_BLOB: - blob = sqlite.sqlite3_column_blob(self._statement, i) - blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = BLOB_TYPE(string_at(blob, blob_len)) + elif typ == _lib.SQLITE_BLOB: + blob = _lib.sqlite3_column_blob(self._statement, i) + blob_len = _lib.sqlite3_column_bytes(self._statement, i) + val = _BLOB_TYPE(string_at(blob, blob_len)) else: - blob = sqlite.sqlite3_column_blob(self._statement, i) + blob = _lib.sqlite3_column_blob(self._statement, i) if not blob: val = None else: - blob_len = sqlite.sqlite3_column_bytes(self._statement, i) + blob_len = _lib.sqlite3_column_bytes(self._statement, i) val = bytes(string_at(blob, blob_len)) val = converter(val) row.append(val) @@ -1228,8 +1247,8 @@ if self._kind == Statement._DML: return None desc = [] - for i in xrange(sqlite.sqlite3_column_count(self._statement)): - name = sqlite.sqlite3_column_name(self._statement, i) + for i in xrange(_lib.sqlite3_column_count(self._statement)): + name = _lib.sqlite3_column_name(self._statement, i) if name is not None: name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) @@ -1316,20 +1335,20 @@ def _convert_params(con, nargs, params): _params = [] for i in range(nargs): - typ = sqlite.sqlite3_value_type(params[i]) - if typ == SQLITE_NULL: + typ = _lib.sqlite3_value_type(params[i]) + if typ == _lib.SQLITE_NULL: val = None - elif typ == SQLITE_INTEGER: - val = sqlite.sqlite3_value_int64(params[i]) - elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_value_double(params[i]) - elif typ == SQLITE_TEXT: - val = sqlite.sqlite3_value_text(params[i]) + elif typ == _lib.SQLITE_INTEGER: + val = _lib.sqlite3_value_int64(params[i]) + elif typ == _lib.SQLITE_FLOAT: + val = _lib.sqlite3_value_double(params[i]) + elif typ == _lib.SQLITE_TEXT: + val = _lib.sqlite3_value_text(params[i]) val = val.decode('utf-8') - elif typ == SQLITE_BLOB: - blob = sqlite.sqlite3_value_blob(params[i]) - blob_len = sqlite.sqlite3_value_bytes(params[i]) - val = BLOB_TYPE(string_at(blob, blob_len)) + elif typ == _lib.SQLITE_BLOB: + blob = _lib.sqlite3_value_blob(params[i]) + blob_len = _lib.sqlite3_value_bytes(params[i]) + val = _BLOB_TYPE(string_at(blob, blob_len)) else: raise NotImplementedError _params.append(val) @@ -1338,52 +1357,52 @@ def _convert_result(con, val): if val is None: - sqlite.sqlite3_result_null(con) + _lib.sqlite3_result_null(con) elif isinstance(val, (bool, int, long)): - sqlite.sqlite3_result_int64(con, int(val)) + _lib.sqlite3_result_int64(con, int(val)) elif isinstance(val, float): - sqlite.sqlite3_result_double(con, val) + _lib.sqlite3_result_double(con, val) elif isinstance(val, unicode): val = val.encode('utf-8') - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + _lib.sqlite3_result_text(con, val, len(val), _lib.SQLITE_TRANSIENT) elif isinstance(val, str): - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + _lib.sqlite3_result_text(con, val, len(val), _lib.SQLITE_TRANSIENT) elif isinstance(val, (buffer, bytes)): - sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) + _lib.sqlite3_result_blob(con, bytes(val), len(val), _lib.SQLITE_TRANSIENT) else: raise NotImplementedError -def function_callback(real_cb, context, nargs, c_params): +def _function_callback(real_cb, context, nargs, c_params): params = _convert_params(context, nargs, c_params) try: val = real_cb(*params) except Exception: msg = b"user-defined function raised exception" - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) _FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) _STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) _FINAL = CFUNCTYPE(None, c_void_p) -sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] -sqlite.sqlite3_create_function.restype = c_int +_lib.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] +_lib.sqlite3_create_function.restype = c_int -sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] -sqlite.sqlite3_aggregate_context.restype = c_void_p +_lib.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] +_lib.sqlite3_aggregate_context.restype = c_void_p _COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, _COLLATION] -sqlite.sqlite3_create_collation.restype = c_int +_lib.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, _COLLATION] +_lib.sqlite3_create_collation.restype = c_int _PROGRESS = CFUNCTYPE(c_int, c_void_p) -sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p] -sqlite.sqlite3_progress_handler.restype = c_int +_lib.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p] +_lib.sqlite3_progress_handler.restype = c_int _AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) -sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p] -sqlite.sqlite3_set_authorizer.restype = c_int +_lib.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p] +_lib.sqlite3_set_authorizer.restype = c_int converters = {} adapters = {} From noreply at buildbot.pypy.org Fri Mar 8 02:18:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 02:18:44 +0100 (CET) Subject: [pypy-commit] pypy default: some pep8 Message-ID: <20130308011844.9E5BC1C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62200:4fdef2502248 Date: 2013-03-07 19:57 -0500 http://bitbucket.org/pypy/pypy/changeset/4fdef2502248/ Log: some pep8 diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -426,9 +426,9 @@ pass else: raise ProgrammingError( - "SQLite objects created in a thread can only be used in that same thread." - "The object was created in thread id %d and this is thread id %d", - self.__thread_ident, _thread_get_ident()) + "SQLite objects created in a thread can only be used in that " + "same thread. The object was created in thread id %d and this " + "is thread id %d", self.__thread_ident, _thread_get_ident()) def _check_thread_wrap(func): @wraps(func) @@ -474,7 +474,8 @@ self.__statement_counter += 1 if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements if ref() is not None] + self.__statements = [ref for ref in self.__statements + if ref() is not None] @_check_thread_wrap @_check_closed_wrap @@ -864,7 +865,7 @@ if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): self.__statement._reset() self.__connection._in_transaction = \ - not _lib.sqlite3_get_autocommit(self.__connection._db) + not _lib.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) if self.__statement._kind == Statement._DML: @@ -901,7 +902,8 @@ if not self.__connection._in_transaction: self.__connection._begin() else: - raise ProgrammingError("executemany is only for DML statements") + raise ProgrammingError( + "executemany is only for DML statements") self.__rowcount = 0 for params in many_params: @@ -910,7 +912,7 @@ if ret != _lib.SQLITE_DONE: self.__statement._reset() self.__connection._in_transaction = \ - not _lib.sqlite3_get_autocommit(self.__connection._db) + not _lib.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__statement._reset() self.__rowcount += _lib.sqlite3_changes(self.__connection._db) From noreply at buildbot.pypy.org Fri Mar 8 02:18:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 02:18:45 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130308011845.BF7CC1C0925@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62201:7d5c829d6e47 Date: 2013-03-07 20:18 -0500 http://bitbucket.org/pypy/pypy/changeset/7d5c829d6e47/ Log: merge heads 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 @@ -2644,6 +2644,17 @@ c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] +def test_FILE_forbidden(): + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BFunc = new_function_type((BFILEP,), BFILEP, False) + func = cast(BFunc, 0) + with open(__file__, "rb") as f: + e = py.test.raises(TypeError, func, f) + if '__pypy__' not in sys.builtin_module_names: + assert ('note that you cannot pass Python files directly ' + 'any more since CFFI 0.6') in str(e.value) + def test_version(): # this test is here mostly for PyPy assert __version__ == "0.6" From noreply at buildbot.pypy.org Fri Mar 8 05:03:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:03:02 +0100 (CET) Subject: [pypy-commit] pypy default: further reduce diffs in datetime.py between 2.x and 3.x Message-ID: <20130308040302.6BD091C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62202:04ef71ea0eb7 Date: 2013-03-07 23:00 -0500 http://bitbucket.org/pypy/pypy/changeset/04ef71ea0eb7/ Log: further reduce diffs in datetime.py between 2.x and 3.x diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -19,11 +19,15 @@ import time as _time import math as _math +def _cmp(x, y): + return 0 if x == y else 1 if x > y else -1 + def _round(x): return _math.floor(x + 0.5) if x >= 0.0 else _math.ceil(x - 0.5) MINYEAR = 1 MAXYEAR = 9999 +_MINYEARFMT = 1900 # Utility functions, adapted from Python's Demo/classes/Dates.py, which # also assumes the current Gregorian calendar indefinitely extended in @@ -172,10 +176,11 @@ # Correctly substitute for %z and %Z escapes in strftime formats. def _wrap_strftime(object, format, timetuple): year = timetuple[0] - if year < 1900: - raise ValueError("year=%d is before 1900; the datetime strftime() " - "methods require year >= 1900" % year) - # Don't call _utcoffset() or tzname() unless actually needed. + if year < _MINYEARFMT: + raise ValueError("year=%d is before %d; the datetime strftime() " + "methods require year >= %d" % + (year, _MINYEARFMT, _MINYEARFMT)) + # Don't call utcoffset() or tzname() unless actually needed. freplace = None # the string to use for %f zreplace = None # the string to use for %z Zreplace = None # the string to use for %Z @@ -263,9 +268,9 @@ raise ValueError("tzinfo.%s() must return a whole number " "of minutes" % name) offset = minutes - if -1440 < offset < 1440: - return offset - raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) + if not -1440 < offset < 1440: + raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) + return offset def _check_int_field(value): if isinstance(value, int): @@ -690,7 +695,7 @@ def _cmp(self, other): assert isinstance(other, timedelta) - return cmp(self._getstate(), other._getstate()) + return _cmp(self._getstate(), other._getstate()) def __hash__(self): return hash(self._getstate()) @@ -750,7 +755,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str) and len(year) == 4: + if isinstance(year, bytes) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -938,7 +943,7 @@ assert isinstance(other, date) y, m, d = self._year, self._month, self._day y2, m2, d2 = other._year, other._month, other._day - return cmp((y, m, d), (y2, m2, d2)) + return _cmp((y, m, d), (y2, m2, d2)) def __hash__(self): "Hash." @@ -1021,8 +1026,9 @@ def __setstate(self, string): if len(string) != 4 or not (1 <= ord(string[2]) <= 12): raise TypeError("not enough arguments") - self._month, self._day = ord(string[2]), ord(string[3]) - self._year = ord(string[0]) * 256 + ord(string[1]) + yhi, ylo, self._month, self._day = (ord(string[0]), ord(string[1]), + ord(string[2]), ord(string[3])) + self._year = yhi * 256 + ylo def __reduce__(self): return (self.__class__, self._getstate()) @@ -1140,7 +1146,7 @@ second, microsecond (default to zero) tzinfo (default to None) """ - if isinstance(hour, str): + if isinstance(hour, bytes) and len(hour) == 6: # Pickle support self = object.__new__(cls) self.__setstate(hour, minute or None) @@ -1235,16 +1241,16 @@ base_compare = myoff == otoff if base_compare: - return cmp((self._hour, self._minute, self._second, - self._microsecond), - (other._hour, other._minute, other._second, - other._microsecond)) + return _cmp((self._hour, self._minute, self._second, + self._microsecond), + (other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: raise TypeError("cannot compare naive and aware times") myhhmm = self._hour * 60 + self._minute - myoff othhmm = other._hour * 60 + other._minute - otoff - return cmp((myhhmm, self._second, self._microsecond), - (othhmm, other._second, other._microsecond)) + return _cmp((myhhmm, self._second, self._microsecond), + (othhmm, other._second, other._microsecond)) def __hash__(self): """Hash.""" @@ -1408,10 +1414,10 @@ def __setstate(self, string, tzinfo): if len(string) != 6 or ord(string[0]) >= 24: raise TypeError("an integer is required") - self._hour, self._minute, self._second = ord(string[0]), \ - ord(string[1]), ord(string[2]) - self._microsecond = (((ord(string[3]) << 8) | \ - ord(string[4])) << 8) | ord(string[5]) + self._hour, self._minute, self._second, us1, us2, us3 = ( + ord(string[0]), ord(string[1]), ord(string[2]), + ord(string[3]), ord(string[4]), ord(string[5])) + self._microsecond = (((us1 << 8) | us2) << 8) | us3 self._tzinfo = tzinfo def __reduce__(self): @@ -1433,7 +1439,7 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str) and len(year) == 10: + if isinstance(year, bytes) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) @@ -1812,12 +1818,12 @@ base_compare = myoff == otoff if base_compare: - return cmp((self._year, self._month, self._day, - self._hour, self._minute, self._second, - self._microsecond), - (other._year, other._month, other._day, - other._hour, other._minute, other._second, - other._microsecond)) + return _cmp((self._year, self._month, self._day, + self._hour, self._minute, self._second, + self._microsecond), + (other._year, other._month, other._day, + other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: raise TypeError("cannot compare naive and aware datetimes") # XXX What follows could be done more efficiently... @@ -1892,11 +1898,13 @@ return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - (self._month, self._day, self._hour, self._minute, - self._second) = (ord(string[2]), ord(string[3]), ord(string[4]), - ord(string[5]), ord(string[6])) - self._year = ord(string[0]) * 256 + ord(string[1]) - self._microsecond = (((ord(string[7]) << 8) | ord(string[8])) << 8) | ord(string[9]) + (yhi, ylo, self._month, self._day, self._hour, + self._minute, self._second, us1, us2, us3) = (ord(string[0]), + ord(string[1]), ord(string[2]), ord(string[3]), + ord(string[4]), ord(string[5]), ord(string[6]), + ord(string[7]), ord(string[8]), ord(string[9])) + self._year = yhi * 256 + ylo + self._microsecond = (((us1 << 8) | us2) << 8) | us3 self._tzinfo = tzinfo def __reduce__(self): From noreply at buildbot.pypy.org Fri Mar 8 05:03:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:03:03 +0100 (CET) Subject: [pypy-commit] pypy default: use struct.pack for datetime getstate (faster, works in both py2/py3) Message-ID: <20130308040303.B1AF71C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62203:f3009e9f2f66 Date: 2013-03-07 22:44 -0500 http://bitbucket.org/pypy/pypy/changeset/f3009e9f2f66/ Log: use struct.pack for datetime getstate (faster, works in both py2/py3) diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -18,6 +18,7 @@ import time as _time import math as _math +import struct as _struct def _cmp(x, y): return 0 if x == y else 1 if x > y else -1 @@ -1021,7 +1022,7 @@ def _getstate(self): yhi, ylo = divmod(self._year, 256) - return ("%c%c%c%c" % (yhi, ylo, self._month, self._day), ) + return (_struct.pack('4B', yhi, ylo, self._month, self._day),) def __setstate(self, string): if len(string) != 4 or not (1 <= ord(string[2]) <= 12): @@ -1404,8 +1405,8 @@ def _getstate(self): us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = ("%c" * 6) % (self._hour, self._minute, self._second, - us1, us2, us3) + basestate = _struct.pack('6B', self._hour, self._minute, self._second, + us1, us2, us3) if self._tzinfo is None: return (basestate,) else: @@ -1889,9 +1890,9 @@ yhi, ylo = divmod(self._year, 256) us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = ("%c" * 10) % (yhi, ylo, self._month, self._day, - self._hour, self._minute, self._second, - us1, us2, us3) + basestate = _struct.pack('10B', yhi, ylo, self._month, self._day, + self._hour, self._minute, self._second, + us1, us2, us3) if self._tzinfo is None: return (basestate,) else: From noreply at buildbot.pypy.org Fri Mar 8 05:04:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:04:03 +0100 (CET) Subject: [pypy-commit] pypy py3k: further reduce diffs in datetime.py between 2.x and 3.x Message-ID: <20130308040403.3DE161C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62204:b93a6a2665c3 Date: 2013-03-07 22:59 -0500 http://bitbucket.org/pypy/pypy/changeset/b93a6a2665c3/ Log: further reduce diffs in datetime.py between 2.x and 3.x diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -27,6 +27,7 @@ MINYEAR = 1 MAXYEAR = 9999 +_MINYEARFMT = 1000 _MAXORDINAL = 3652059 # date.max.toordinal() # Utility functions, adapted from Python's Demo/classes/Dates.py, which @@ -176,9 +177,10 @@ # Correctly substitute for %z and %Z escapes in strftime formats. def _wrap_strftime(object, format, timetuple): year = timetuple[0] - if year < 1000: - raise ValueError("year=%d is before 1000; the datetime strftime() " - "methods require year >= 1000" % year) + if year < _MINYEARFMT: + raise ValueError("year=%d is before %d; the datetime strftime() " + "methods require year >= %d" % + (year, _MINYEARFMT, _MINYEARFMT)) # Don't call utcoffset() or tzname() unless actually needed. freplace = None # the string to use for %f zreplace = None # the string to use for %z @@ -318,7 +320,7 @@ raise TypeError("can't compare '%s' to '%s'" % ( type(x).__name__, type(y).__name__)) -class timedelta: +class timedelta(object): """Represent the difference between two datetime objects. Supported operators: @@ -651,7 +653,7 @@ microseconds=999999) timedelta.resolution = timedelta(microseconds=1) -class date: +class date(object): """Concrete date type. Constructors: @@ -944,7 +946,7 @@ date.max = date(9999, 12, 31) date.resolution = timedelta(days=1) -class tzinfo: +class tzinfo(object): """Abstract base class for time zone info classes. Subclasses must override the name(), utcoffset() and dst() methods. @@ -1014,7 +1016,7 @@ _tzinfo_class = tzinfo -class time: +class time(object): """Time with time zone. Constructors: @@ -1145,8 +1147,8 @@ if base_compare: return _cmp((self._hour, self._minute, self._second, self._microsecond), - (other._hour, other._minute, other._second, - other._microsecond)) + (other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: raise TypeError("cannot compare naive and aware times") myhhmm = self._hour * 60 + self._minute - myoff//timedelta(minutes=1) @@ -1308,8 +1310,7 @@ def __setstate(self, string, tzinfo): if len(string) != 6 or string[0] >= 24: raise TypeError("an integer is required") - (self._hour, self._minute, self._second, - us1, us2, us3) = string + self._hour, self._minute, self._second, us1, us2, us3 = string self._microsecond = (((us1 << 8) | us2) << 8) | us3 if tzinfo is None or isinstance(tzinfo, _tzinfo_class): self._tzinfo = tzinfo @@ -1703,9 +1704,9 @@ return _cmp((self._year, self._month, self._day, self._hour, self._minute, self._second, self._microsecond), - (other._year, other._month, other._day, - other._hour, other._minute, other._second, - other._microsecond)) + (other._year, other._month, other._day, + other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: raise TypeError("cannot compare naive and aware datetimes") # XXX What follows could be done more efficiently... @@ -1783,7 +1784,7 @@ def __setstate(self, string, tzinfo): (yhi, ylo, self._month, self._day, self._hour, - self._minute, self._second, us1, us2, us3) = string + self._minute, self._second, us1, us2, us3) = string self._year = yhi * 256 + ylo self._microsecond = (((us1 << 8) | us2) << 8) | us3 if tzinfo is None or isinstance(tzinfo, _tzinfo_class): From noreply at buildbot.pypy.org Fri Mar 8 05:04:04 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:04:04 +0100 (CET) Subject: [pypy-commit] pypy py3k: use struct.pack for datetime getstate (faster, works in both py2/py3) Message-ID: <20130308040404.95E6A1C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62205:a7f2fbea4eaf Date: 2013-03-07 22:44 -0500 http://bitbucket.org/pypy/pypy/changeset/a7f2fbea4eaf/ Log: use struct.pack for datetime getstate (faster, works in both py2/py3) diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -18,6 +18,7 @@ import time as _time import math as _math +import struct as _struct def _cmp(x, y): return 0 if x == y else 1 if x > y else -1 @@ -929,7 +930,7 @@ def _getstate(self): yhi, ylo = divmod(self._year, 256) - return bytes([yhi, ylo, self._month, self._day]), + return (_struct.pack('4B', yhi, ylo, self._month, self._day),) def __setstate(self, string): if len(string) != 4 or not (1 <= string[2] <= 12): @@ -1300,8 +1301,8 @@ def _getstate(self): us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = bytes([self._hour, self._minute, self._second, - us1, us2, us3]) + basestate = _struct.pack('6B', self._hour, self._minute, self._second, + us1, us2, us3) if self._tzinfo is None: return (basestate,) else: @@ -1774,9 +1775,9 @@ yhi, ylo = divmod(self._year, 256) us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = bytes([yhi, ylo, self._month, self._day, - self._hour, self._minute, self._second, - us1, us2, us3]) + basestate = _struct.pack('10B', yhi, ylo, self._month, self._day, + self._hour, self._minute, self._second, + us1, us2, us3) if self._tzinfo is None: return (basestate,) else: From noreply at buildbot.pypy.org Fri Mar 8 05:38:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:38:03 +0100 (CET) Subject: [pypy-commit] pypy default: clean up datetime pickle support Message-ID: <20130308043803.982591C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62206:41536d424a04 Date: 2013-03-07 23:37 -0500 http://bitbucket.org/pypy/pypy/changeset/41536d424a04/ Log: clean up datetime pickle support diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -756,7 +756,8 @@ year, month, day (required, base 1) """ - if isinstance(year, bytes) and len(year) == 4: + if month is None and isinstance(year, bytes) and len(year) == 4 and \ + 1 <= ord(year[2]) <= 12: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1025,8 +1026,6 @@ return (_struct.pack('4B', yhi, ylo, self._month, self._day),) def __setstate(self, string): - if len(string) != 4 or not (1 <= ord(string[2]) <= 12): - raise TypeError("not enough arguments") yhi, ylo, self._month, self._day = (ord(string[0]), ord(string[1]), ord(string[2]), ord(string[3])) self._year = yhi * 256 + ylo @@ -1147,7 +1146,7 @@ second, microsecond (default to zero) tzinfo (default to None) """ - if isinstance(hour, bytes) and len(hour) == 6: + if isinstance(hour, bytes) and len(hour) == 6 and ord(hour[0]) < 24: # Pickle support self = object.__new__(cls) self.__setstate(hour, minute or None) @@ -1413,8 +1412,6 @@ return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - if len(string) != 6 or ord(string[0]) >= 24: - raise TypeError("an integer is required") self._hour, self._minute, self._second, us1, us2, us3 = ( ord(string[0]), ord(string[1]), ord(string[2]), ord(string[3]), ord(string[4]), ord(string[5])) @@ -1440,7 +1437,8 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, bytes) and len(year) == 10: + if isinstance(year, bytes) and len(year) == 10 and \ + 1 <= ord(year[2]) <= 12: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) From noreply at buildbot.pypy.org Fri Mar 8 05:38:12 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:38:12 +0100 (CET) Subject: [pypy-commit] pypy py3k: clean up datetime pickle support Message-ID: <20130308043812.5C5721C1067@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62207:e5e29597b960 Date: 2013-03-07 23:37 -0500 http://bitbucket.org/pypy/pypy/changeset/e5e29597b960/ Log: clean up datetime pickle support diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -691,8 +691,8 @@ year, month, day (required, base 1) """ - if (isinstance(year, bytes) and len(year) == 4 and - 1 <= year[2] <= 12 and month is None): # Month is sane + if month is None and isinstance(year, bytes) and len(year) == 4 and \ + 1 <= year[2] <= 12: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -933,8 +933,6 @@ return (_struct.pack('4B', yhi, ylo, self._month, self._day),) def __setstate(self, string): - if len(string) != 4 or not (1 <= string[2] <= 12): - raise TypeError("not enough arguments") yhi, ylo, self._month, self._day = string self._year = yhi * 256 + ylo @@ -1051,7 +1049,7 @@ second, microsecond (default to zero) tzinfo (default to None) """ - if isinstance(hour, bytes) and len(hour) == 6: + if isinstance(hour, bytes) and len(hour) == 6 and hour[0] < 24: # Pickle support self = object.__new__(cls) self.__setstate(hour, minute or None) @@ -1309,8 +1307,6 @@ return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - if len(string) != 6 or string[0] >= 24: - raise TypeError("an integer is required") self._hour, self._minute, self._second, us1, us2, us3 = string self._microsecond = (((us1 << 8) | us2) << 8) | us3 if tzinfo is None or isinstance(tzinfo, _tzinfo_class): @@ -1337,7 +1333,7 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, bytes) and len(year) == 10: + if isinstance(year, bytes) and len(year) == 10 and 1 <= year[2] <= 12: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) From noreply at buildbot.pypy.org Fri Mar 8 05:39:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 05:39:52 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308043952.7EBB41C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62208:d62f548e5d51 Date: 2013-03-07 23:39 -0500 http://bitbucket.org/pypy/pypy/changeset/d62f548e5d51/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -40,69 +40,69 @@ xrange = range basestring = unicode = str buffer = memoryview - BLOB_TYPE = bytes + _BLOB_TYPE = bytes else: - BLOB_TYPE = buffer + _BLOB_TYPE = buffer -names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() -for name in names: - try: - sqlite = cdll.LoadLibrary(name) - break - except OSError: - continue -else: - raise ImportError("Could not load C-library, tried: %s" % (names,)) -# pysqlite version information -version = "2.6.0" +def load_library(names): + for name in names: + try: + return cdll.LoadLibrary(name) + except OSError: + pass + else: + raise ImportError("Could not load C-library, tried: %s" % (names,)) -# pysqlite constants -PARSE_COLNAMES = 1 -PARSE_DECLTYPES = 2 +_lib = load_library( + "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split()) +del load_library ########################################## # BEGIN Wrapped SQLite C API and constants ########################################## -SQLITE_OK = 0 -SQLITE_ERROR = 1 -SQLITE_INTERNAL = 2 -SQLITE_PERM = 3 -SQLITE_ABORT = 4 -SQLITE_BUSY = 5 -SQLITE_LOCKED = 6 -SQLITE_NOMEM = 7 -SQLITE_READONLY = 8 -SQLITE_INTERRUPT = 9 -SQLITE_IOERR = 10 -SQLITE_CORRUPT = 11 -SQLITE_NOTFOUND = 12 -SQLITE_FULL = 13 -SQLITE_CANTOPEN = 14 -SQLITE_PROTOCOL = 15 -SQLITE_EMPTY = 16 -SQLITE_SCHEMA = 17 -SQLITE_TOOBIG = 18 -SQLITE_CONSTRAINT = 19 -SQLITE_MISMATCH = 20 -SQLITE_MISUSE = 21 -SQLITE_NOLFS = 22 -SQLITE_AUTH = 23 -SQLITE_FORMAT = 24 -SQLITE_RANGE = 25 -SQLITE_NOTADB = 26 -SQLITE_ROW = 100 -SQLITE_DONE = 101 -SQLITE_INTEGER = 1 -SQLITE_FLOAT = 2 -SQLITE_BLOB = 4 -SQLITE_NULL = 5 -SQLITE_TEXT = 3 -SQLITE3_TEXT = 3 +_lib.SQLITE_OK = 0 +_lib.SQLITE_ERROR = 1 +_lib.SQLITE_INTERNAL = 2 +_lib.SQLITE_PERM = 3 +_lib.SQLITE_ABORT = 4 +_lib.SQLITE_BUSY = 5 +_lib.SQLITE_LOCKED = 6 +_lib.SQLITE_NOMEM = 7 +_lib.SQLITE_READONLY = 8 +_lib.SQLITE_INTERRUPT = 9 +_lib.SQLITE_IOERR = 10 +_lib.SQLITE_CORRUPT = 11 +_lib.SQLITE_NOTFOUND = 12 +_lib.SQLITE_FULL = 13 +_lib.SQLITE_CANTOPEN = 14 +_lib.SQLITE_PROTOCOL = 15 +_lib.SQLITE_EMPTY = 16 +_lib.SQLITE_SCHEMA = 17 +_lib.SQLITE_TOOBIG = 18 +_lib.SQLITE_CONSTRAINT = 19 +_lib.SQLITE_MISMATCH = 20 +_lib.SQLITE_MISUSE = 21 +_lib.SQLITE_NOLFS = 22 +_lib.SQLITE_AUTH = 23 +_lib.SQLITE_FORMAT = 24 +_lib.SQLITE_RANGE = 25 +_lib.SQLITE_NOTADB = 26 +_lib.SQLITE_ROW = 100 +_lib.SQLITE_DONE = 101 -SQLITE_TRANSIENT = cast(-1, c_void_p) -SQLITE_UTF8 = 1 +_lib.SQLITE_INTEGER = 1 +_lib.SQLITE_FLOAT = 2 +_lib.SQLITE_TEXT = 3 +_lib.SQLITE_BLOB = 4 +_lib.SQLITE_NULL = 5 + +_lib.SQLITE_UTF8 = 1 + +_lib.SQLITE_TRANSIENT = cast(-1, c_void_p) + +SQLITE_OK = _lib.SQLITE_OK SQLITE_DENY = 1 SQLITE_IGNORE = 2 @@ -135,161 +135,177 @@ SQLITE_ALTER_TABLE = 26 SQLITE_REINDEX = 27 SQLITE_ANALYZE = 28 -SQLITE_CREATE_VTABLE = 29 -SQLITE_DROP_VTABLE = 30 -SQLITE_FUNCTION = 31 # SQLite C API -sqlite.sqlite3_value_int.argtypes = [c_void_p] -sqlite.sqlite3_value_int.restype = c_int +_lib.sqlite3_value_int.argtypes = [c_void_p] +_lib.sqlite3_value_int.restype = c_int -sqlite.sqlite3_value_int64.argtypes = [c_void_p] -sqlite.sqlite3_value_int64.restype = c_int64 +_lib.sqlite3_value_int64.argtypes = [c_void_p] +_lib.sqlite3_value_int64.restype = c_int64 -sqlite.sqlite3_value_blob.argtypes = [c_void_p] -sqlite.sqlite3_value_blob.restype = c_void_p +_lib.sqlite3_value_blob.argtypes = [c_void_p] +_lib.sqlite3_value_blob.restype = c_void_p -sqlite.sqlite3_value_bytes.argtypes = [c_void_p] -sqlite.sqlite3_value_bytes.restype = c_int +_lib.sqlite3_value_bytes.argtypes = [c_void_p] +_lib.sqlite3_value_bytes.restype = c_int -sqlite.sqlite3_value_double.argtypes = [c_void_p] -sqlite.sqlite3_value_double.restype = c_double +_lib.sqlite3_value_double.argtypes = [c_void_p] +_lib.sqlite3_value_double.restype = c_double -sqlite.sqlite3_value_text.argtypes = [c_void_p] -sqlite.sqlite3_value_text.restype = c_char_p +_lib.sqlite3_value_text.argtypes = [c_void_p] +_lib.sqlite3_value_text.restype = c_char_p -sqlite.sqlite3_value_type.argtypes = [c_void_p] -sqlite.sqlite3_value_type.restype = c_int +_lib.sqlite3_value_type.argtypes = [c_void_p] +_lib.sqlite3_value_type.restype = c_int -sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p] -sqlite.sqlite3_bind_blob.restype = c_int -sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] -sqlite.sqlite3_bind_double.restype = c_int -sqlite.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int] -sqlite.sqlite3_bind_int.restype = c_int -sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64] -sqlite.sqlite3_bind_int64.restype = c_int -sqlite.sqlite3_bind_null.argtypes = [c_void_p, c_int] -sqlite.sqlite3_bind_null.restype = c_int -sqlite.sqlite3_bind_parameter_count.argtypes = [c_void_p] -sqlite.sqlite3_bind_parameter_count.restype = c_int -sqlite.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p] -sqlite.sqlite3_bind_parameter_index.restype = c_int -sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] -sqlite.sqlite3_bind_parameter_name.restype = c_char_p -sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p] -sqlite.sqlite3_bind_text.restype = c_int -sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] -sqlite.sqlite3_busy_timeout.restype = c_int -sqlite.sqlite3_changes.argtypes = [c_void_p] -sqlite.sqlite3_changes.restype = c_int -sqlite.sqlite3_close.argtypes = [c_void_p] -sqlite.sqlite3_close.restype = c_int -sqlite.sqlite3_column_blob.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_blob.restype = c_void_p -sqlite.sqlite3_column_bytes.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_bytes.restype = c_int -sqlite.sqlite3_column_count.argtypes = [c_void_p] -sqlite.sqlite3_column_count.restype = c_int -sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_decltype.restype = c_char_p -sqlite.sqlite3_column_double.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_double.restype = c_double -sqlite.sqlite3_column_int64.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_int64.restype = c_int64 -sqlite.sqlite3_column_name.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_name.restype = c_char_p -sqlite.sqlite3_column_text.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_text.restype = POINTER(c_char) -sqlite.sqlite3_column_type.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_type.restype = c_int -sqlite.sqlite3_complete.argtypes = [c_char_p] -sqlite.sqlite3_complete.restype = c_int -sqlite.sqlite3_errcode.restype = c_int -sqlite.sqlite3_errmsg.argtypes = [c_void_p] -sqlite.sqlite3_errmsg.restype = c_char_p -sqlite.sqlite3_finalize.argtypes = [c_void_p] -sqlite.sqlite3_finalize.restype = c_int -sqlite.sqlite3_get_autocommit.argtypes = [c_void_p] -sqlite.sqlite3_get_autocommit.restype = c_int -sqlite.sqlite3_last_insert_rowid.argtypes = [c_void_p] -sqlite.sqlite3_last_insert_rowid.restype = c_int64 -sqlite.sqlite3_libversion.argtypes = [] -sqlite.sqlite3_libversion.restype = c_char_p -sqlite.sqlite3_open.argtypes = [c_char_p, c_void_p] -sqlite.sqlite3_open.restype = c_int -sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] -sqlite.sqlite3_prepare.restype = c_int -sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] -sqlite.sqlite3_prepare_v2.restype = c_int -sqlite.sqlite3_step.argtypes = [c_void_p] -sqlite.sqlite3_step.restype = c_int -sqlite.sqlite3_reset.argtypes = [c_void_p] -sqlite.sqlite3_reset.restype = c_int -sqlite.sqlite3_total_changes.argtypes = [c_void_p] -sqlite.sqlite3_total_changes.restype = c_int +_lib.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p] +_lib.sqlite3_bind_blob.restype = c_int +_lib.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] +_lib.sqlite3_bind_double.restype = c_int +_lib.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int] +_lib.sqlite3_bind_int.restype = c_int +_lib.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64] +_lib.sqlite3_bind_int64.restype = c_int +_lib.sqlite3_bind_null.argtypes = [c_void_p, c_int] +_lib.sqlite3_bind_null.restype = c_int +_lib.sqlite3_bind_parameter_count.argtypes = [c_void_p] +_lib.sqlite3_bind_parameter_count.restype = c_int +_lib.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p] +_lib.sqlite3_bind_parameter_index.restype = c_int +_lib.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] +_lib.sqlite3_bind_parameter_name.restype = c_char_p +_lib.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p] +_lib.sqlite3_bind_text.restype = c_int +_lib.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] +_lib.sqlite3_busy_timeout.restype = c_int +_lib.sqlite3_changes.argtypes = [c_void_p] +_lib.sqlite3_changes.restype = c_int +_lib.sqlite3_close.argtypes = [c_void_p] +_lib.sqlite3_close.restype = c_int +_lib.sqlite3_column_blob.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_blob.restype = c_void_p +_lib.sqlite3_column_bytes.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_bytes.restype = c_int +_lib.sqlite3_column_count.argtypes = [c_void_p] +_lib.sqlite3_column_count.restype = c_int +_lib.sqlite3_column_decltype.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_decltype.restype = c_char_p +_lib.sqlite3_column_double.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_double.restype = c_double +_lib.sqlite3_column_int64.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_int64.restype = c_int64 +_lib.sqlite3_column_name.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_name.restype = c_char_p +_lib.sqlite3_column_text.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_text.restype = POINTER(c_char) +_lib.sqlite3_column_type.argtypes = [c_void_p, c_int] +_lib.sqlite3_column_type.restype = c_int +_lib.sqlite3_complete.argtypes = [c_char_p] +_lib.sqlite3_complete.restype = c_int +_lib.sqlite3_errcode.restype = c_int +_lib.sqlite3_errmsg.argtypes = [c_void_p] +_lib.sqlite3_errmsg.restype = c_char_p +_lib.sqlite3_finalize.argtypes = [c_void_p] +_lib.sqlite3_finalize.restype = c_int +_lib.sqlite3_get_autocommit.argtypes = [c_void_p] +_lib.sqlite3_get_autocommit.restype = c_int +_lib.sqlite3_last_insert_rowid.argtypes = [c_void_p] +_lib.sqlite3_last_insert_rowid.restype = c_int64 +_lib.sqlite3_libversion.argtypes = [] +_lib.sqlite3_libversion.restype = c_char_p +_lib.sqlite3_open.argtypes = [c_char_p, c_void_p] +_lib.sqlite3_open.restype = c_int +_lib.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] +_lib.sqlite3_prepare.restype = c_int +_lib.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] +_lib.sqlite3_prepare_v2.restype = c_int +_lib.sqlite3_step.argtypes = [c_void_p] +_lib.sqlite3_step.restype = c_int +_lib.sqlite3_reset.argtypes = [c_void_p] +_lib.sqlite3_reset.restype = c_int +_lib.sqlite3_total_changes.argtypes = [c_void_p] +_lib.sqlite3_total_changes.restype = c_int -sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] -sqlite.sqlite3_result_blob.restype = None -sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64] -sqlite.sqlite3_result_int64.restype = None -sqlite.sqlite3_result_null.argtypes = [c_void_p] -sqlite.sqlite3_result_null.restype = None -sqlite.sqlite3_result_double.argtypes = [c_void_p, c_double] -sqlite.sqlite3_result_double.restype = None -sqlite.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int] -sqlite.sqlite3_result_error.restype = None -sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] -sqlite.sqlite3_result_text.restype = None +_lib.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p] +_lib.sqlite3_result_blob.restype = None +_lib.sqlite3_result_int64.argtypes = [c_void_p, c_int64] +_lib.sqlite3_result_int64.restype = None +_lib.sqlite3_result_null.argtypes = [c_void_p] +_lib.sqlite3_result_null.restype = None +_lib.sqlite3_result_double.argtypes = [c_void_p, c_double] +_lib.sqlite3_result_double.restype = None +_lib.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int] +_lib.sqlite3_result_error.restype = None +_lib.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] +_lib.sqlite3_result_text.restype = None -_HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") +_HAS_LOAD_EXTENSION = hasattr(_lib, "sqlite3_enable_load_extension") if _HAS_LOAD_EXTENSION: - sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] - sqlite.sqlite3_enable_load_extension.restype = c_int + _lib.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] + _lib.sqlite3_enable_load_extension.restype = c_int ########################################## # END Wrapped SQLite C API and constants ########################################## +# pysqlite version information +version = "2.6.0" + +# pysqlite constants +PARSE_COLNAMES = 1 +PARSE_DECLTYPES = 2 + # SQLite version information -sqlite_version = str(sqlite.sqlite3_libversion().decode('ascii')) +sqlite_version = str(_lib.sqlite3_libversion().decode('ascii')) + class Error(StandardError): pass + class Warning(StandardError): pass + class InterfaceError(Error): pass + class DatabaseError(Error): pass + class InternalError(DatabaseError): pass + class OperationalError(DatabaseError): pass + class ProgrammingError(DatabaseError): pass + class IntegrityError(DatabaseError): pass + class DataError(DatabaseError): pass + class NotSupportedError(DatabaseError): pass + def connect(database, **kwargs): factory = kwargs.get("factory", Connection) return factory(database, **kwargs) -def unicode_text_factory(x): + +def _unicode_text_factory(x): return unicode(x, 'utf-8') if sys.version_info[0] < 3: @@ -300,7 +316,7 @@ val = unicode(s, "utf-8") return val else: - OptimizedUnicode = unicode_text_factory + OptimizedUnicode = _unicode_text_factory class _StatementCache(object): @@ -335,14 +351,14 @@ if isinstance(database, unicode): database = database.encode('utf-8') - if sqlite.sqlite3_open(database, byref(self._db)) != SQLITE_OK: + if _lib.sqlite3_open(database, byref(self._db)) != _lib.SQLITE_OK: raise OperationalError("Could not open database") if timeout is not None: timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds - sqlite.sqlite3_busy_timeout(self._db, timeout) + _lib.sqlite3_busy_timeout(self._db, timeout) self.row_factory = None - self.text_factory = unicode_text_factory + self.text_factory = _unicode_text_factory self._detect_types = detect_types self._in_transaction = False @@ -373,7 +389,7 @@ def __del__(self): if self._db: - sqlite.sqlite3_close(self._db) + _lib.sqlite3_close(self._db) def close(self): self._check_thread() @@ -384,8 +400,8 @@ obj._finalize() if self._db: - ret = sqlite.sqlite3_close(self._db) - if ret != SQLITE_OK: + ret = _lib.sqlite3_close(self._db) + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) self._db = None @@ -410,9 +426,9 @@ pass else: raise ProgrammingError( - "SQLite objects created in a thread can only be used in that same thread." - "The object was created in thread id %d and this is thread id %d", - self.__thread_ident, _thread_get_ident()) + "SQLite objects created in a thread can only be used in that " + "same thread. The object was created in thread id %d and this " + "is thread id %d", self.__thread_ident, _thread_get_ident()) def _check_thread_wrap(func): @wraps(func) @@ -423,26 +439,29 @@ def _get_exception(self, error_code=None): if error_code is None: - error_code = sqlite.sqlite3_errcode(self._db) - error_message = sqlite.sqlite3_errmsg(self._db).decode('utf-8') + error_code = _lib.sqlite3_errcode(self._db) + error_message = _lib.sqlite3_errmsg(self._db).decode('utf-8') - if error_code == SQLITE_OK: + if error_code == _lib.SQLITE_OK: raise ValueError("error signalled but got SQLITE_OK") - elif error_code in (SQLITE_INTERNAL, SQLITE_NOTFOUND): + elif error_code in (_lib.SQLITE_INTERNAL, _lib.SQLITE_NOTFOUND): exc = InternalError - elif error_code == SQLITE_NOMEM: + elif error_code == _lib.SQLITE_NOMEM: exc = MemoryError - elif error_code in (SQLITE_ERROR, SQLITE_PERM, SQLITE_ABORT, SQLITE_BUSY, SQLITE_LOCKED, - SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, - SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): + elif error_code in ( + _lib.SQLITE_ERROR, _lib.SQLITE_PERM, _lib.SQLITE_ABORT, + _lib.SQLITE_BUSY, _lib.SQLITE_LOCKED, _lib.SQLITE_READONLY, + _lib.SQLITE_INTERRUPT, _lib.SQLITE_IOERR, _lib.SQLITE_FULL, + _lib.SQLITE_CANTOPEN, _lib.SQLITE_PROTOCOL, _lib.SQLITE_EMPTY, + _lib.SQLITE_SCHEMA): exc = OperationalError - elif error_code == SQLITE_CORRUPT: + elif error_code == _lib.SQLITE_CORRUPT: exc = DatabaseError - elif error_code == SQLITE_TOOBIG: + elif error_code == _lib.SQLITE_TOOBIG: exc = DataError - elif error_code in (SQLITE_CONSTRAINT, SQLITE_MISMATCH): + elif error_code in (_lib.SQLITE_CONSTRAINT, _lib.SQLITE_MISMATCH): exc = IntegrityError - elif error_code == SQLITE_MISUSE: + elif error_code == _lib.SQLITE_MISUSE: exc = ProgrammingError else: exc = DatabaseError @@ -455,7 +474,8 @@ self.__statement_counter += 1 if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements if ref() is not None] + self.__statements = [ref for ref in self.__statements + if ref() is not None] @_check_thread_wrap @_check_closed_wrap @@ -492,17 +512,17 @@ def _begin(self): statement = c_void_p() - ret = sqlite.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, + ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, byref(statement), None) try: - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(statement) + if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) self._in_transaction = True finally: - sqlite.sqlite3_finalize(statement) + _lib.sqlite3_finalize(statement) def commit(self): self._check_thread() @@ -516,17 +536,17 @@ obj._reset() statement = c_void_p() - ret = sqlite.sqlite3_prepare_v2(self._db, b"COMMIT", -1, + ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, byref(statement), None) try: - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(statement) + if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) self._in_transaction = False finally: - sqlite.sqlite3_finalize(statement) + _lib.sqlite3_finalize(statement) def rollback(self): self._check_thread() @@ -545,17 +565,17 @@ cursor._reset = True statement = c_void_p() - ret = sqlite.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, + ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, byref(statement), None) try: - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(statement) + if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) self._in_transaction = False finally: - sqlite.sqlite3_finalize(statement) + _lib.sqlite3_finalize(statement) def __enter__(self): return self @@ -573,18 +593,18 @@ c_closure, _ = self.__func_cache[callback] except KeyError: def closure(context, nargs, c_params): - function_callback(callback, context, nargs, c_params) + _function_callback(callback, context, nargs, c_params) c_closure = _FUNC(closure) self.__func_cache[callback] = c_closure, closure if isinstance(name, unicode): name = name.encode('utf-8') - ret = sqlite.sqlite3_create_function(self._db, name, num_args, - SQLITE_UTF8, None, + ret = _lib.sqlite3_create_function(self._db, name, num_args, + _lib.SQLITE_UTF8, None, c_closure, cast(None, _STEP), cast(None, _FINAL)) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self.OperationalError("Error creating function") @_check_thread_wrap @@ -595,7 +615,7 @@ except KeyError: def step_callback(context, argc, c_params): aggregate_ptr = cast( - sqlite.sqlite3_aggregate_context( + _lib.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) @@ -605,7 +625,7 @@ except Exception: msg = (b"user-defined aggregate's '__init__' " b"method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) self.__aggregate_instances[aggregate_id] = aggregate @@ -619,11 +639,11 @@ except Exception: msg = (b"user-defined aggregate's 'step' " b"method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) def final_callback(context): aggregate_ptr = cast( - sqlite.sqlite3_aggregate_context( + _lib.sqlite3_aggregate_context( context, sizeof(c_ssize_t)), POINTER(c_ssize_t)) @@ -634,7 +654,7 @@ except Exception: msg = (b"user-defined aggregate's 'finalize' " b"method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) finally: @@ -648,12 +668,12 @@ if isinstance(name, unicode): name = name.encode('utf-8') - ret = sqlite.sqlite3_create_function(self._db, name, num_args, - SQLITE_UTF8, None, + ret = _lib.sqlite3_create_function(self._db, name, num_args, + _lib.SQLITE_UTF8, None, cast(None, _FUNC), c_step_callback, c_final_callback) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @_check_thread_wrap @@ -681,11 +701,11 @@ if isinstance(name, unicode): name = name.encode('utf-8') - ret = sqlite.sqlite3_create_collation(self._db, name, - SQLITE_UTF8, + ret = _lib.sqlite3_create_collation(self._db, name, + _lib.SQLITE_UTF8, None, c_collation_callback) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @_check_thread_wrap @@ -703,10 +723,10 @@ self.__func_cache[callback] = c_authorizer, authorizer - ret = sqlite.sqlite3_set_authorizer(self._db, + ret = _lib.sqlite3_set_authorizer(self._db, c_authorizer, None) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @_check_thread_wrap @@ -728,10 +748,10 @@ c_progress_handler = _PROGRESS(progress_handler) self.__func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self._db, nsteps, + ret = _lib.sqlite3_progress_handler(self._db, nsteps, c_progress_handler, None) - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self._get_exception(ret) if sys.version_info[0] >= 3: @@ -741,7 +761,7 @@ def __get_total_changes(self): self._check_closed() - return sqlite.sqlite3_total_changes(self._db) + return _lib.sqlite3_total_changes(self._db) total_changes = property(__get_total_changes) def __get_isolation_level(self): @@ -759,8 +779,8 @@ @_check_thread_wrap @_check_closed_wrap def enable_load_extension(self, enabled): - rc = sqlite.sqlite3_enable_load_extension(self._db, int(enabled)) - if rc != SQLITE_OK: + rc = _lib.sqlite3_enable_load_extension(self._db, int(enabled)) + if rc != _lib.SQLITE_OK: raise OperationalError("Error enabling load extension") @@ -841,17 +861,17 @@ self.__statement._set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.__statement._statement) - if ret not in (SQLITE_DONE, SQLITE_ROW): + ret = _lib.sqlite3_step(self.__statement._statement) + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): self.__statement._reset() self.__connection._in_transaction = \ - not sqlite.sqlite3_get_autocommit(self.__connection._db) + not _lib.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) if self.__statement._kind == Statement._DML: self.__statement._reset() - if self.__statement._kind == Statement._DQL and ret == SQLITE_ROW: + if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) else: @@ -860,7 +880,7 @@ self.__rowcount = -1 if self.__statement._kind == Statement._DML: - self.__rowcount = sqlite.sqlite3_changes(self.__connection._db) + self.__rowcount = _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False @@ -882,19 +902,20 @@ if not self.__connection._in_transaction: self.__connection._begin() else: - raise ProgrammingError("executemany is only for DML statements") + raise ProgrammingError( + "executemany is only for DML statements") self.__rowcount = 0 for params in many_params: self.__statement._set_params(params) - ret = sqlite.sqlite3_step(self.__statement._statement) - if ret != SQLITE_DONE: + ret = _lib.sqlite3_step(self.__statement._statement) + if ret != _lib.SQLITE_DONE: self.__statement._reset() self.__connection._in_transaction = \ - not sqlite.sqlite3_get_autocommit(self.__connection._db) + not _lib.sqlite3_get_autocommit(self.__connection._db) raise self.__connection._get_exception(ret) self.__statement._reset() - self.__rowcount += sqlite.sqlite3_changes(self.__connection._db) + self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False @@ -913,25 +934,25 @@ self.__connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) - if rc != SQLITE_OK: + rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) + if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) - rc = SQLITE_ROW - while rc == SQLITE_ROW: + rc = _lib.SQLITE_ROW + while rc == _lib.SQLITE_ROW: if not statement: - rc = SQLITE_OK + rc = _lib.SQLITE_OK else: - rc = sqlite.sqlite3_step(statement) + rc = _lib.sqlite3_step(statement) - if rc != SQLITE_DONE: - sqlite.sqlite3_finalize(statement) - if rc == SQLITE_OK: + if rc != _lib.SQLITE_DONE: + _lib.sqlite3_finalize(statement) + if rc == _lib.SQLITE_OK: return self else: raise self.__connection._get_exception(rc) - rc = sqlite.sqlite3_finalize(statement) - if rc != SQLITE_OK: + rc = _lib.sqlite3_finalize(statement) + if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) if not c_sql.value: @@ -989,7 +1010,7 @@ description = property(__get_description) def __get_lastrowid(self): - return sqlite.sqlite3_last_insert_rowid(self.__connection._db) + return _lib.sqlite3_last_insert_rowid(self.__connection._db) lastrowid = property(__get_lastrowid) def setinputsizes(self, *args): @@ -1026,13 +1047,13 @@ if isinstance(sql, unicode): sql = sql.encode('utf-8') - ret = sqlite.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) - if ret == SQLITE_OK and self._statement.value is None: + ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) + if ret == _lib.SQLITE_OK and self._statement.value is None: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) + ret = _lib.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) self._kind = Statement._DQL - if ret != SQLITE_OK: + if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) next_char = next_char.value.decode('utf-8') @@ -1042,27 +1063,27 @@ def __del__(self): if self._statement: - sqlite.sqlite3_finalize(self._statement) + _lib.sqlite3_finalize(self._statement) def _finalize(self): if self._statement: - sqlite.sqlite3_finalize(self._statement) + _lib.sqlite3_finalize(self._statement) self._statement = None self._in_use = False def _reset(self): if self._in_use and self._statement: - ret = sqlite.sqlite3_reset(self._statement) + _lib.sqlite3_reset(self._statement) self._in_use = False self._exhausted = False def _build_row_cast_map(self): self.__row_cast_map = [] - for i in xrange(sqlite.sqlite3_column_count(self._statement)): + for i in xrange(_lib.sqlite3_column_count(self._statement)): converter = None if self.__con._detect_types & PARSE_COLNAMES: - colname = sqlite.sqlite3_column_name(self._statement, i) + colname = _lib.sqlite3_column_name(self._statement, i) if colname is not None: colname = colname.decode('utf-8') type_start = -1 @@ -1075,7 +1096,7 @@ converter = converters[key.upper()] if converter is None and self.__con._detect_types & PARSE_DECLTYPES: - decltype = sqlite.sqlite3_column_decltype(self._statement, i) + decltype = _lib.sqlite3_column_decltype(self._statement, i) if decltype is not None: decltype = decltype.decode('utf-8') decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" @@ -1088,7 +1109,7 @@ if sys.version_info[0] < 3: def __check_decodable(self, param): if self.__con.text_factory in (unicode, OptimizedUnicode, - unicode_text_factory): + _unicode_text_factory): for c in param: if ord(c) & 0x80 != 0: raise self.__con.ProgrammingError( @@ -1106,23 +1127,23 @@ param = adapt(param) if param is None: - rc = sqlite.sqlite3_bind_null(self._statement, idx) + rc = _lib.sqlite3_bind_null(self._statement, idx) elif isinstance(param, (bool, int, long)): if -2147483648 <= param <= 2147483647: - rc = sqlite.sqlite3_bind_int(self._statement, idx, param) + rc = _lib.sqlite3_bind_int(self._statement, idx, param) else: - rc = sqlite.sqlite3_bind_int64(self._statement, idx, param) + rc = _lib.sqlite3_bind_int64(self._statement, idx, param) elif isinstance(param, float): - rc = sqlite.sqlite3_bind_double(self._statement, idx, param) + rc = _lib.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, unicode): param = param.encode("utf-8") - rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, str): self.__check_decodable(param) - rc = sqlite.sqlite3_bind_text(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, (buffer, bytes)): param = bytes(param) - rc = sqlite.sqlite3_bind_blob(self._statement, idx, param, len(param), SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_blob(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) else: rc = -1 return rc @@ -1130,7 +1151,7 @@ def _set_params(self, params): self._in_use = True - num_params_needed = sqlite.sqlite3_bind_parameter_count(self._statement) + num_params_needed = _lib.sqlite3_bind_parameter_count(self._statement) if isinstance(params, (tuple, list)) or \ not isinstance(params, dict) and \ hasattr(params, '__getitem__'): @@ -1145,12 +1166,12 @@ (num_params_needed, num_params)) for i in range(num_params): rc = self.__set_param(i + 1, params[i]) - if rc != SQLITE_OK: + if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter %d - " "probably unsupported type." % i) elif isinstance(params, dict): for i in range(1, num_params_needed + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self._statement, i) + param_name = _lib.sqlite3_bind_parameter_name(self._statement, i) if param_name is None: raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " @@ -1162,7 +1183,7 @@ raise ProgrammingError("You did not supply a value for " "binding %d." % i) rc = self.__set_param(i, param) - if rc != SQLITE_OK: + if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter :%s - " "probably unsupported type." % param_name) @@ -1174,47 +1195,47 @@ raise StopIteration item = self._item - ret = sqlite.sqlite3_step(self._statement) - if ret == SQLITE_DONE: + ret = _lib.sqlite3_step(self._statement) + if ret == _lib.SQLITE_DONE: self._exhausted = True self._item = None - elif ret != SQLITE_ROW: + elif ret != _lib.SQLITE_ROW: exc = self.__con._get_exception(ret) - sqlite.sqlite3_reset(self._statement) + _lib.sqlite3_reset(self._statement) raise exc self._readahead(cursor) return item def _readahead(self, cursor): - self.column_count = sqlite.sqlite3_column_count(self._statement) + self.column_count = _lib.sqlite3_column_count(self._statement) row = [] for i in xrange(self.column_count): - typ = sqlite.sqlite3_column_type(self._statement, i) + typ = _lib.sqlite3_column_type(self._statement, i) converter = self.__row_cast_map[i] if converter is None: - if typ == SQLITE_NULL: + if typ == _lib.SQLITE_NULL: val = None - elif typ == SQLITE_INTEGER: - val = sqlite.sqlite3_column_int64(self._statement, i) - elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_column_double(self._statement, i) - elif typ == SQLITE_TEXT: - text = sqlite.sqlite3_column_text(self._statement, i) - text_len = sqlite.sqlite3_column_bytes(self._statement, i) + elif typ == _lib.SQLITE_INTEGER: + val = _lib.sqlite3_column_int64(self._statement, i) + elif typ == _lib.SQLITE_FLOAT: + val = _lib.sqlite3_column_double(self._statement, i) + elif typ == _lib.SQLITE_TEXT: + text = _lib.sqlite3_column_text(self._statement, i) + text_len = _lib.sqlite3_column_bytes(self._statement, i) val = string_at(text, text_len) val = self.__con.text_factory(val) - elif typ == SQLITE_BLOB: - blob = sqlite.sqlite3_column_blob(self._statement, i) - blob_len = sqlite.sqlite3_column_bytes(self._statement, i) - val = BLOB_TYPE(string_at(blob, blob_len)) + elif typ == _lib.SQLITE_BLOB: + blob = _lib.sqlite3_column_blob(self._statement, i) + blob_len = _lib.sqlite3_column_bytes(self._statement, i) + val = _BLOB_TYPE(string_at(blob, blob_len)) else: - blob = sqlite.sqlite3_column_blob(self._statement, i) + blob = _lib.sqlite3_column_blob(self._statement, i) if not blob: val = None else: - blob_len = sqlite.sqlite3_column_bytes(self._statement, i) + blob_len = _lib.sqlite3_column_bytes(self._statement, i) val = bytes(string_at(blob, blob_len)) val = converter(val) row.append(val) @@ -1228,8 +1249,8 @@ if self._kind == Statement._DML: return None desc = [] - for i in xrange(sqlite.sqlite3_column_count(self._statement)): - name = sqlite.sqlite3_column_name(self._statement, i) + for i in xrange(_lib.sqlite3_column_count(self._statement)): + name = _lib.sqlite3_column_name(self._statement, i) if name is not None: name = name.decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) @@ -1316,20 +1337,20 @@ def _convert_params(con, nargs, params): _params = [] for i in range(nargs): - typ = sqlite.sqlite3_value_type(params[i]) - if typ == SQLITE_NULL: + typ = _lib.sqlite3_value_type(params[i]) + if typ == _lib.SQLITE_NULL: val = None - elif typ == SQLITE_INTEGER: - val = sqlite.sqlite3_value_int64(params[i]) - elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_value_double(params[i]) - elif typ == SQLITE_TEXT: - val = sqlite.sqlite3_value_text(params[i]) + elif typ == _lib.SQLITE_INTEGER: + val = _lib.sqlite3_value_int64(params[i]) + elif typ == _lib.SQLITE_FLOAT: + val = _lib.sqlite3_value_double(params[i]) + elif typ == _lib.SQLITE_TEXT: + val = _lib.sqlite3_value_text(params[i]) val = val.decode('utf-8') - elif typ == SQLITE_BLOB: - blob = sqlite.sqlite3_value_blob(params[i]) - blob_len = sqlite.sqlite3_value_bytes(params[i]) - val = BLOB_TYPE(string_at(blob, blob_len)) + elif typ == _lib.SQLITE_BLOB: + blob = _lib.sqlite3_value_blob(params[i]) + blob_len = _lib.sqlite3_value_bytes(params[i]) + val = _BLOB_TYPE(string_at(blob, blob_len)) else: raise NotImplementedError _params.append(val) @@ -1338,52 +1359,52 @@ def _convert_result(con, val): if val is None: - sqlite.sqlite3_result_null(con) + _lib.sqlite3_result_null(con) elif isinstance(val, (bool, int, long)): - sqlite.sqlite3_result_int64(con, int(val)) + _lib.sqlite3_result_int64(con, int(val)) elif isinstance(val, float): - sqlite.sqlite3_result_double(con, val) + _lib.sqlite3_result_double(con, val) elif isinstance(val, unicode): val = val.encode('utf-8') - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + _lib.sqlite3_result_text(con, val, len(val), _lib.SQLITE_TRANSIENT) elif isinstance(val, str): - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + _lib.sqlite3_result_text(con, val, len(val), _lib.SQLITE_TRANSIENT) elif isinstance(val, (buffer, bytes)): - sqlite.sqlite3_result_blob(con, bytes(val), len(val), SQLITE_TRANSIENT) + _lib.sqlite3_result_blob(con, bytes(val), len(val), _lib.SQLITE_TRANSIENT) else: raise NotImplementedError -def function_callback(real_cb, context, nargs, c_params): +def _function_callback(real_cb, context, nargs, c_params): params = _convert_params(context, nargs, c_params) try: val = real_cb(*params) except Exception: msg = b"user-defined function raised exception" - sqlite.sqlite3_result_error(context, msg, len(msg)) + _lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) _FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) _STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) _FINAL = CFUNCTYPE(None, c_void_p) -sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] -sqlite.sqlite3_create_function.restype = c_int +_lib.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, _FUNC, _STEP, _FINAL] +_lib.sqlite3_create_function.restype = c_int -sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] -sqlite.sqlite3_aggregate_context.restype = c_void_p +_lib.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] +_lib.sqlite3_aggregate_context.restype = c_void_p _COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, _COLLATION] -sqlite.sqlite3_create_collation.restype = c_int +_lib.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, _COLLATION] +_lib.sqlite3_create_collation.restype = c_int _PROGRESS = CFUNCTYPE(c_int, c_void_p) -sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p] -sqlite.sqlite3_progress_handler.restype = c_int +_lib.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p] +_lib.sqlite3_progress_handler.restype = c_int _AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) -sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p] -sqlite.sqlite3_set_authorizer.restype = c_int +_lib.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p] +_lib.sqlite3_set_authorizer.restype = c_int converters = {} adapters = {} 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 @@ -2644,6 +2644,17 @@ c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] +def test_FILE_forbidden(): + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BFunc = new_function_type((BFILEP,), BFILEP, False) + func = cast(BFunc, 0) + with open(__file__, "rb") as f: + e = py.test.raises(TypeError, func, f) + if '__pypy__' not in sys.builtin_module_names: + assert ('note that you cannot pass Python files directly ' + 'any more since CFFI 0.6') in str(e.value) + def test_version(): # this test is here mostly for PyPy assert __version__ == "0.6" From noreply at buildbot.pypy.org Fri Mar 8 06:43:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 06:43:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: small cleanups Message-ID: <20130308054349.8C21A1C023D@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62209:c3a770cd870e Date: 2013-03-07 23:53 -0500 http://bitbucket.org/pypy/pypy/changeset/c3a770cd870e/ Log: small cleanups diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -10,7 +10,7 @@ import operator try: - from _thread import get_ident as _thread_ident + from threading import _get_ident as _thread_ident except ImportError: def _thread_ident(): return -1 @@ -432,5 +432,5 @@ This API is used by pickle.py and copy.py. """ - return (type(self), (self.default_factory,), None, None, iter(self.items())) + return (type(self), (self.default_factory,), None, None, self.items()) From noreply at buildbot.pypy.org Fri Mar 8 06:43:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 06:43:50 +0100 (CET) Subject: [pypy-commit] pypy default: port some lib_pypy cleanups/fixes/modernizations from py3k Message-ID: <20130308054350.D5BFD1C023D@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62210:42658a039a09 Date: 2013-03-08 00:25 -0500 http://bitbucket.org/pypy/pypy/changeset/42658a039a09/ Log: port some lib_pypy cleanups/fixes/modernizations from py3k diff --git a/lib_pypy/__init__.py b/lib_pypy/__init__.py --- a/lib_pypy/__init__.py +++ b/lib_pypy/__init__.py @@ -1,4 +1,4 @@ # This __init__.py shows up in PyPy's app-level standard library. # Let's try to prevent that confusion... if __name__ != 'lib_pypy': - raise ImportError, '__init__' + raise ImportError('__init__') diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -10,7 +10,7 @@ import operator try: - from thread import get_ident as _thread_ident + from threading import _get_ident as _thread_ident except ImportError: def _thread_ident(): return -1 @@ -97,7 +97,7 @@ def pop(self): if self.left is self.right and self.leftndx > self.rightndx: - raise IndexError, "pop from an empty deque" + raise IndexError("pop from an empty deque") x = self.right[self.rightndx] self.right[self.rightndx] = None self.length -= 1 @@ -118,7 +118,7 @@ def popleft(self): if self.left is self.right and self.leftndx > self.rightndx: - raise IndexError, "pop from an empty deque" + raise IndexError("pop from an empty deque") x = self.left[self.leftndx] self.left[self.leftndx] = None self.length -= 1 @@ -322,7 +322,7 @@ return type(self), (list(self), self.maxlen) def __hash__(self): - raise TypeError, "deque objects are unhashable" + raise TypeError("deque objects are unhashable") def __copy__(self): return self.__class__(self, self.maxlen) @@ -374,11 +374,11 @@ self.counter = len(deq) def giveup(): self.counter = 0 - raise RuntimeError, "deque mutated during iteration" + raise RuntimeError("deque mutated during iteration") self._gen = itergen(deq.state, giveup) def next(self): - res = self._gen.next() + res = next(self._gen) self.counter -= 1 return res diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py --- a/lib_pypy/_csv.py +++ b/lib_pypy/_csv.py @@ -225,7 +225,7 @@ self._parse_reset() while True: try: - line = self.input_iter.next() + line = next(self.input_iter) except StopIteration: # End of input OR exception if len(self.field) > 0: diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -3,9 +3,17 @@ This module contains functions that can read and write Python values in a binary format. The format is specific to Python, but independent of machine architecture issues (e.g., you can write a Python value to a file on a PC, transport the file to a Sun, and read it back there). Details of the format may change between Python versions. """ +# NOTE: This module is used in the Python3 interpreter, but also by +# the "sandboxed" process. It must work for Python2 as well. + import types from _codecs import utf_8_decode, utf_8_encode +try: + intern +except NameError: + from sys import intern + try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -49,7 +57,7 @@ if func: break else: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") func(self, x) def w_long64(self, x): @@ -72,7 +80,7 @@ def dump_none(self, x): self._write(TYPE_NONE) - dispatch[types.NoneType] = dump_none + dispatch[type(None)] = dump_none def dump_bool(self, x): if x: @@ -83,7 +91,7 @@ def dump_stopiter(self, x): if x is not StopIteration: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") self._write(TYPE_STOPITER) dispatch[type(StopIteration)] = dump_stopiter @@ -91,10 +99,11 @@ self._write(TYPE_ELLIPSIS) try: - dispatch[types.EllipsisType] = dump_ellipsis + dispatch[type(Ellipsis)] = dump_ellipsis except NameError: pass + # In Python3, this function is not used; see dump_long() below. def dump_int(self, x): y = x>>31 if y and y != -1: @@ -103,7 +112,7 @@ else: self._write(TYPE_INT) self.w_long(x) - dispatch[types.IntType] = dump_int + dispatch[int] = dump_int def dump_long(self, x): self._write(TYPE_LONG) @@ -118,27 +127,32 @@ self.w_long(len(digits) * sign) for d in digits: self.w_short(d) - dispatch[types.LongType] = dump_long + try: + long + except NameError: + dispatch[int] = dump_long + else: + dispatch[long] = dump_long def dump_float(self, x): write = self._write write(TYPE_FLOAT) - s = `x` + s = repr(x) write(chr(len(s))) write(s) - dispatch[types.FloatType] = dump_float + dispatch[float] = dump_float def dump_complex(self, x): write = self._write write(TYPE_COMPLEX) - s = `x.real` + s = repr(x.real) write(chr(len(s))) write(s) - s = `x.imag` + s = repr(x.imag) write(chr(len(s))) write(s) try: - dispatch[types.ComplexType] = dump_complex + dispatch[complex] = dump_complex except NameError: pass @@ -148,7 +162,7 @@ self._write(TYPE_STRING) self.w_long(len(x)) self._write(x) - dispatch[types.StringType] = dump_string + dispatch[bytes] = dump_string def dump_unicode(self, x): self._write(TYPE_UNICODE) @@ -156,21 +170,26 @@ s, len_s = utf_8_encode(x) self.w_long(len_s) self._write(s) - dispatch[types.UnicodeType] = dump_unicode + try: + unicode + except NameError: + dispatch[str] = dump_unicode + else: + dispatch[unicode] = dump_unicode def dump_tuple(self, x): self._write(TYPE_TUPLE) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.TupleType] = dump_tuple + dispatch[tuple] = dump_tuple def dump_list(self, x): self._write(TYPE_LIST) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.ListType] = dump_list + dispatch[list] = dump_list def dump_dict(self, x): self._write(TYPE_DICT) @@ -178,7 +197,7 @@ self.dump(key) self.dump(value) self._write(TYPE_NULL) - dispatch[types.DictionaryType] = dump_dict + dispatch[dict] = dump_dict def dump_code(self, x): self._write(TYPE_CODE) @@ -252,7 +271,7 @@ try: return self.dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) def r_short(self): lo = ord(self._read(1)) @@ -270,7 +289,7 @@ d = ord(s[3]) x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -280,14 +299,14 @@ b = ord(self._read(1)) c = ord(self._read(1)) d = ord(self._read(1)) - e = long(ord(self._read(1))) - f = long(ord(self._read(1))) - g = long(ord(self._read(1))) - h = long(ord(self._read(1))) + e = ord(self._read(1)) + f = ord(self._read(1)) + g = ord(self._read(1)) + h = ord(self._read(1)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x def load_null(self): @@ -324,10 +343,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = self.r_short() - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long @@ -459,7 +478,7 @@ self.bufpos += 4 x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -469,14 +488,14 @@ b = ord(_read1(self)) c = ord(_read1(self)) d = ord(_read1(self)) - e = long(ord(_read1(self))) - f = long(ord(_read1(self))) - g = long(ord(_read1(self))) - h = long(ord(_read1(self))) + e = ord(_read1(self)) + f = ord(_read1(self)) + g = ord(_read1(self)) + h = ord(_read1(self)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x _load_dispatch = {} @@ -498,7 +517,7 @@ self.bufpos += 1 return _load_dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) except IndexError: raise EOFError @@ -540,10 +559,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = _r_short(self) - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long diff --git a/lib_pypy/_md5.py b/lib_pypy/_md5.py --- a/lib_pypy/_md5.py +++ b/lib_pypy/_md5.py @@ -47,16 +47,16 @@ def _bytelist2long(list): "Transform a list of characters into a list of longs." - imax = len(list)/4 - hl = [0L] * imax + imax = len(list) // 4 + hl = [0] * imax j = 0 i = 0 while i < imax: - b0 = long(ord(list[j])) - b1 = (long(ord(list[j+1]))) << 8 - b2 = (long(ord(list[j+2]))) << 16 - b3 = (long(ord(list[j+3]))) << 24 + b0 = ord(list[j]) + b1 = ord(list[j+1]) << 8 + b2 = ord(list[j+2]) << 16 + b3 = ord(list[j+3]) << 24 hl[i] = b0 | b1 |b2 | b3 i = i+1 j = j+4 @@ -100,16 +100,16 @@ (now summed-up in one function). """ - res = 0L + res = 0 res = res + a + func(b, c, d) res = res + x res = res + ac - res = res & 0xffffffffL + res = res & 0xffffffff res = _rotateLeft(res, s) - res = res & 0xffffffffL + res = res & 0xffffffff res = res + b - return res & 0xffffffffL + return res & 0xffffffff class MD5Type: @@ -122,7 +122,7 @@ "Initialisation." # Initial message length in bits(!). - self.length = 0L + self.length = 0 self.count = [0, 0] # Initial empty message as a sequence of bytes (8 bit characters). @@ -136,15 +136,15 @@ def init(self): "Initialize the message-digest and set all fields to zero." - self.length = 0L + self.length = 0 self.count = [0, 0] self.input = [] # Load magic initialization constants. - self.A = 0x67452301L - self.B = 0xefcdab89L - self.C = 0x98badcfeL - self.D = 0x10325476L + self.A = 0x67452301 + self.B = 0xefcdab89 + self.C = 0x98badcfe + self.D = 0x10325476 def _transform(self, inp): @@ -161,90 +161,90 @@ S11, S12, S13, S14 = 7, 12, 17, 22 - a = XX(F, a, b, c, d, inp[ 0], S11, 0xD76AA478L) # 1 - d = XX(F, d, a, b, c, inp[ 1], S12, 0xE8C7B756L) # 2 - c = XX(F, c, d, a, b, inp[ 2], S13, 0x242070DBL) # 3 - b = XX(F, b, c, d, a, inp[ 3], S14, 0xC1BDCEEEL) # 4 - a = XX(F, a, b, c, d, inp[ 4], S11, 0xF57C0FAFL) # 5 - d = XX(F, d, a, b, c, inp[ 5], S12, 0x4787C62AL) # 6 - c = XX(F, c, d, a, b, inp[ 6], S13, 0xA8304613L) # 7 - b = XX(F, b, c, d, a, inp[ 7], S14, 0xFD469501L) # 8 - a = XX(F, a, b, c, d, inp[ 8], S11, 0x698098D8L) # 9 - d = XX(F, d, a, b, c, inp[ 9], S12, 0x8B44F7AFL) # 10 - c = XX(F, c, d, a, b, inp[10], S13, 0xFFFF5BB1L) # 11 - b = XX(F, b, c, d, a, inp[11], S14, 0x895CD7BEL) # 12 - a = XX(F, a, b, c, d, inp[12], S11, 0x6B901122L) # 13 - d = XX(F, d, a, b, c, inp[13], S12, 0xFD987193L) # 14 - c = XX(F, c, d, a, b, inp[14], S13, 0xA679438EL) # 15 - b = XX(F, b, c, d, a, inp[15], S14, 0x49B40821L) # 16 + a = XX(F, a, b, c, d, inp[ 0], S11, 0xD76AA478) # 1 + d = XX(F, d, a, b, c, inp[ 1], S12, 0xE8C7B756) # 2 + c = XX(F, c, d, a, b, inp[ 2], S13, 0x242070DB) # 3 + b = XX(F, b, c, d, a, inp[ 3], S14, 0xC1BDCEEE) # 4 + a = XX(F, a, b, c, d, inp[ 4], S11, 0xF57C0FAF) # 5 + d = XX(F, d, a, b, c, inp[ 5], S12, 0x4787C62A) # 6 + c = XX(F, c, d, a, b, inp[ 6], S13, 0xA8304613) # 7 + b = XX(F, b, c, d, a, inp[ 7], S14, 0xFD469501) # 8 + a = XX(F, a, b, c, d, inp[ 8], S11, 0x698098D8) # 9 + d = XX(F, d, a, b, c, inp[ 9], S12, 0x8B44F7AF) # 10 + c = XX(F, c, d, a, b, inp[10], S13, 0xFFFF5BB1) # 11 + b = XX(F, b, c, d, a, inp[11], S14, 0x895CD7BE) # 12 + a = XX(F, a, b, c, d, inp[12], S11, 0x6B901122) # 13 + d = XX(F, d, a, b, c, inp[13], S12, 0xFD987193) # 14 + c = XX(F, c, d, a, b, inp[14], S13, 0xA679438E) # 15 + b = XX(F, b, c, d, a, inp[15], S14, 0x49B40821) # 16 # Round 2. S21, S22, S23, S24 = 5, 9, 14, 20 - a = XX(G, a, b, c, d, inp[ 1], S21, 0xF61E2562L) # 17 - d = XX(G, d, a, b, c, inp[ 6], S22, 0xC040B340L) # 18 - c = XX(G, c, d, a, b, inp[11], S23, 0x265E5A51L) # 19 - b = XX(G, b, c, d, a, inp[ 0], S24, 0xE9B6C7AAL) # 20 - a = XX(G, a, b, c, d, inp[ 5], S21, 0xD62F105DL) # 21 - d = XX(G, d, a, b, c, inp[10], S22, 0x02441453L) # 22 - c = XX(G, c, d, a, b, inp[15], S23, 0xD8A1E681L) # 23 - b = XX(G, b, c, d, a, inp[ 4], S24, 0xE7D3FBC8L) # 24 - a = XX(G, a, b, c, d, inp[ 9], S21, 0x21E1CDE6L) # 25 - d = XX(G, d, a, b, c, inp[14], S22, 0xC33707D6L) # 26 - c = XX(G, c, d, a, b, inp[ 3], S23, 0xF4D50D87L) # 27 - b = XX(G, b, c, d, a, inp[ 8], S24, 0x455A14EDL) # 28 - a = XX(G, a, b, c, d, inp[13], S21, 0xA9E3E905L) # 29 - d = XX(G, d, a, b, c, inp[ 2], S22, 0xFCEFA3F8L) # 30 - c = XX(G, c, d, a, b, inp[ 7], S23, 0x676F02D9L) # 31 - b = XX(G, b, c, d, a, inp[12], S24, 0x8D2A4C8AL) # 32 + a = XX(G, a, b, c, d, inp[ 1], S21, 0xF61E2562) # 17 + d = XX(G, d, a, b, c, inp[ 6], S22, 0xC040B340) # 18 + c = XX(G, c, d, a, b, inp[11], S23, 0x265E5A51) # 19 + b = XX(G, b, c, d, a, inp[ 0], S24, 0xE9B6C7AA) # 20 + a = XX(G, a, b, c, d, inp[ 5], S21, 0xD62F105D) # 21 + d = XX(G, d, a, b, c, inp[10], S22, 0x02441453) # 22 + c = XX(G, c, d, a, b, inp[15], S23, 0xD8A1E681) # 23 + b = XX(G, b, c, d, a, inp[ 4], S24, 0xE7D3FBC8) # 24 + a = XX(G, a, b, c, d, inp[ 9], S21, 0x21E1CDE6) # 25 + d = XX(G, d, a, b, c, inp[14], S22, 0xC33707D6) # 26 + c = XX(G, c, d, a, b, inp[ 3], S23, 0xF4D50D87) # 27 + b = XX(G, b, c, d, a, inp[ 8], S24, 0x455A14ED) # 28 + a = XX(G, a, b, c, d, inp[13], S21, 0xA9E3E905) # 29 + d = XX(G, d, a, b, c, inp[ 2], S22, 0xFCEFA3F8) # 30 + c = XX(G, c, d, a, b, inp[ 7], S23, 0x676F02D9) # 31 + b = XX(G, b, c, d, a, inp[12], S24, 0x8D2A4C8A) # 32 # Round 3. S31, S32, S33, S34 = 4, 11, 16, 23 - a = XX(H, a, b, c, d, inp[ 5], S31, 0xFFFA3942L) # 33 - d = XX(H, d, a, b, c, inp[ 8], S32, 0x8771F681L) # 34 - c = XX(H, c, d, a, b, inp[11], S33, 0x6D9D6122L) # 35 - b = XX(H, b, c, d, a, inp[14], S34, 0xFDE5380CL) # 36 - a = XX(H, a, b, c, d, inp[ 1], S31, 0xA4BEEA44L) # 37 - d = XX(H, d, a, b, c, inp[ 4], S32, 0x4BDECFA9L) # 38 - c = XX(H, c, d, a, b, inp[ 7], S33, 0xF6BB4B60L) # 39 - b = XX(H, b, c, d, a, inp[10], S34, 0xBEBFBC70L) # 40 - a = XX(H, a, b, c, d, inp[13], S31, 0x289B7EC6L) # 41 - d = XX(H, d, a, b, c, inp[ 0], S32, 0xEAA127FAL) # 42 - c = XX(H, c, d, a, b, inp[ 3], S33, 0xD4EF3085L) # 43 - b = XX(H, b, c, d, a, inp[ 6], S34, 0x04881D05L) # 44 - a = XX(H, a, b, c, d, inp[ 9], S31, 0xD9D4D039L) # 45 - d = XX(H, d, a, b, c, inp[12], S32, 0xE6DB99E5L) # 46 - c = XX(H, c, d, a, b, inp[15], S33, 0x1FA27CF8L) # 47 - b = XX(H, b, c, d, a, inp[ 2], S34, 0xC4AC5665L) # 48 + a = XX(H, a, b, c, d, inp[ 5], S31, 0xFFFA3942) # 33 + d = XX(H, d, a, b, c, inp[ 8], S32, 0x8771F681) # 34 + c = XX(H, c, d, a, b, inp[11], S33, 0x6D9D6122) # 35 + b = XX(H, b, c, d, a, inp[14], S34, 0xFDE5380C) # 36 + a = XX(H, a, b, c, d, inp[ 1], S31, 0xA4BEEA44) # 37 + d = XX(H, d, a, b, c, inp[ 4], S32, 0x4BDECFA9) # 38 + c = XX(H, c, d, a, b, inp[ 7], S33, 0xF6BB4B60) # 39 + b = XX(H, b, c, d, a, inp[10], S34, 0xBEBFBC70) # 40 + a = XX(H, a, b, c, d, inp[13], S31, 0x289B7EC6) # 41 + d = XX(H, d, a, b, c, inp[ 0], S32, 0xEAA127FA) # 42 + c = XX(H, c, d, a, b, inp[ 3], S33, 0xD4EF3085) # 43 + b = XX(H, b, c, d, a, inp[ 6], S34, 0x04881D05) # 44 + a = XX(H, a, b, c, d, inp[ 9], S31, 0xD9D4D039) # 45 + d = XX(H, d, a, b, c, inp[12], S32, 0xE6DB99E5) # 46 + c = XX(H, c, d, a, b, inp[15], S33, 0x1FA27CF8) # 47 + b = XX(H, b, c, d, a, inp[ 2], S34, 0xC4AC5665) # 48 # Round 4. S41, S42, S43, S44 = 6, 10, 15, 21 - a = XX(I, a, b, c, d, inp[ 0], S41, 0xF4292244L) # 49 - d = XX(I, d, a, b, c, inp[ 7], S42, 0x432AFF97L) # 50 - c = XX(I, c, d, a, b, inp[14], S43, 0xAB9423A7L) # 51 - b = XX(I, b, c, d, a, inp[ 5], S44, 0xFC93A039L) # 52 - a = XX(I, a, b, c, d, inp[12], S41, 0x655B59C3L) # 53 - d = XX(I, d, a, b, c, inp[ 3], S42, 0x8F0CCC92L) # 54 - c = XX(I, c, d, a, b, inp[10], S43, 0xFFEFF47DL) # 55 - b = XX(I, b, c, d, a, inp[ 1], S44, 0x85845DD1L) # 56 - a = XX(I, a, b, c, d, inp[ 8], S41, 0x6FA87E4FL) # 57 - d = XX(I, d, a, b, c, inp[15], S42, 0xFE2CE6E0L) # 58 - c = XX(I, c, d, a, b, inp[ 6], S43, 0xA3014314L) # 59 - b = XX(I, b, c, d, a, inp[13], S44, 0x4E0811A1L) # 60 - a = XX(I, a, b, c, d, inp[ 4], S41, 0xF7537E82L) # 61 - d = XX(I, d, a, b, c, inp[11], S42, 0xBD3AF235L) # 62 - c = XX(I, c, d, a, b, inp[ 2], S43, 0x2AD7D2BBL) # 63 - b = XX(I, b, c, d, a, inp[ 9], S44, 0xEB86D391L) # 64 + a = XX(I, a, b, c, d, inp[ 0], S41, 0xF4292244) # 49 + d = XX(I, d, a, b, c, inp[ 7], S42, 0x432AFF97) # 50 + c = XX(I, c, d, a, b, inp[14], S43, 0xAB9423A7) # 51 + b = XX(I, b, c, d, a, inp[ 5], S44, 0xFC93A039) # 52 + a = XX(I, a, b, c, d, inp[12], S41, 0x655B59C3) # 53 + d = XX(I, d, a, b, c, inp[ 3], S42, 0x8F0CCC92) # 54 + c = XX(I, c, d, a, b, inp[10], S43, 0xFFEFF47D) # 55 + b = XX(I, b, c, d, a, inp[ 1], S44, 0x85845DD1) # 56 + a = XX(I, a, b, c, d, inp[ 8], S41, 0x6FA87E4F) # 57 + d = XX(I, d, a, b, c, inp[15], S42, 0xFE2CE6E0) # 58 + c = XX(I, c, d, a, b, inp[ 6], S43, 0xA3014314) # 59 + b = XX(I, b, c, d, a, inp[13], S44, 0x4E0811A1) # 60 + a = XX(I, a, b, c, d, inp[ 4], S41, 0xF7537E82) # 61 + d = XX(I, d, a, b, c, inp[11], S42, 0xBD3AF235) # 62 + c = XX(I, c, d, a, b, inp[ 2], S43, 0x2AD7D2BB) # 63 + b = XX(I, b, c, d, a, inp[ 9], S44, 0xEB86D391) # 64 - A = (A + a) & 0xffffffffL - B = (B + b) & 0xffffffffL - C = (C + c) & 0xffffffffL - D = (D + d) & 0xffffffffL + A = (A + a) & 0xffffffff + B = (B + b) & 0xffffffff + C = (C + c) & 0xffffffff + D = (D + d) & 0xffffffff self.A, self.B, self.C, self.D = A, B, C, D @@ -267,10 +267,10 @@ the hashed string. """ - leninBuf = long(len(inBuf)) + leninBuf = len(inBuf) # Compute number of bytes mod 64. - index = (self.count[0] >> 3) & 0x3FL + index = (self.count[0] >> 3) & 0x3F # Update number of bits. self.count[0] = self.count[0] + (leninBuf << 3) @@ -309,7 +309,7 @@ input = [] + self.input count = [] + self.count - index = (self.count[0] >> 3) & 0x3fL + index = (self.count[0] >> 3) & 0x3f if index < 56: padLen = 56 - index diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py --- a/lib_pypy/_pypy_wait.py +++ b/lib_pypy/_pypy_wait.py @@ -1,6 +1,6 @@ +from resource import _struct_rusage, struct_rusage from ctypes import CDLL, c_int, POINTER, byref from ctypes.util import find_library -from resource import _struct_rusage, struct_rusage __all__ = ["wait3", "wait4"] diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py --- a/lib_pypy/grp.py +++ b/lib_pypy/grp.py @@ -59,6 +59,12 @@ libc.getgrent.argtypes = [] libc.getgrent.restype = POINTER(GroupStruct) +libc.setgrent.argtypes = [] +libc.setgrent.restype = None + +libc.endgrent.argtypes = [] +libc.endgrent.restype = None + def _group_from_gstruct(res): i = 0 mem = [] diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py --- a/lib_pypy/stackless.py +++ b/lib_pypy/stackless.py @@ -433,16 +433,16 @@ def insert(self): if self.blocked: - raise RuntimeError, "You cannot run a blocked tasklet" + raise RuntimeError("You cannot run a blocked tasklet") if not self.alive: - raise RuntimeError, "You cannot run an unbound(dead) tasklet" + raise RuntimeError("You cannot run an unbound(dead) tasklet") _scheduler_append(self) def remove(self): if self.blocked: - raise RuntimeError, "You cannot remove a blocked tasklet." + raise RuntimeError("You cannot remove a blocked tasklet.") if self is getcurrent(): - raise RuntimeError, "The current tasklet cannot be removed." + raise RuntimeError("The current tasklet cannot be removed.") # not sure if I will revive this " Use t=tasklet().capture()" _scheduler_remove(self) From noreply at buildbot.pypy.org Fri Mar 8 06:43:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 06:43:52 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308054352.1C5F61C023D@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62211:27f49aef77f3 Date: 2013-03-08 00:39 -0500 http://bitbucket.org/pypy/pypy/changeset/27f49aef77f3/ Log: merge default diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -8,7 +8,11 @@ import types from _codecs import utf_8_decode, utf_8_encode -import sys + +try: + intern +except NameError: + from sys import intern try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -295,10 +299,10 @@ b = ord(self._read(1)) c = ord(self._read(1)) d = ord(self._read(1)) - e = int(ord(self._read(1))) - f = int(ord(self._read(1))) - g = int(ord(self._read(1))) - h = int(ord(self._read(1))) + e = ord(self._read(1)) + f = ord(self._read(1)) + g = ord(self._read(1)) + h = ord(self._read(1)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: @@ -369,7 +373,7 @@ def load_interned(self): n = self.r_long() - ret = sys.intern(self._read(n)) + ret = intern(self._read(n)) self._stringtable.append(ret) return ret dispatch[TYPE_INTERNED] = load_interned @@ -484,10 +488,10 @@ b = ord(_read1(self)) c = ord(_read1(self)) d = ord(_read1(self)) - e = int(ord(_read1(self))) - f = int(ord(_read1(self))) - g = int(ord(_read1(self))) - h = int(ord(_read1(self))) + e = ord(_read1(self)) + f = ord(_read1(self)) + g = ord(_read1(self)) + h = ord(_read1(self)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: @@ -585,7 +589,7 @@ def load_interned(self): n = _r_long(self) - ret = sys.intern(_read(self, n)) + ret = intern(_read(self, n)) self._stringtable.append(ret) return ret dispatch[TYPE_INTERNED] = load_interned diff --git a/lib_pypy/_md5.py b/lib_pypy/_md5.py --- a/lib_pypy/_md5.py +++ b/lib_pypy/_md5.py @@ -53,10 +53,10 @@ j = 0 i = 0 while i < imax: - b0 = list[j] - b1 = list[j+1] << 8 - b2 = list[j+2] << 16 - b3 = list[j+3] << 24 + b0 = ord(list[j]) + b1 = ord(list[j+1]) << 8 + b2 = ord(list[j+2]) << 16 + b3 = ord(list[j+3]) << 24 hl[i] = b0 | b1 |b2 | b3 i = i+1 j = j+4 @@ -270,7 +270,7 @@ the hashed string. """ - leninBuf = int(len(inBuf)) + leninBuf = len(inBuf) # Compute number of bytes mod 64. index = (self.count[0] >> 3) & 0x3F From noreply at buildbot.pypy.org Fri Mar 8 06:55:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 06:55:50 +0100 (CET) Subject: [pypy-commit] pypy default: fix sqlite ints on 32bit Message-ID: <20130308055550.464D21C023D@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62212:7a7fe66e8639 Date: 2013-03-08 00:54 -0500 http://bitbucket.org/pypy/pypy/changeset/7a7fe66e8639/ Log: fix sqlite ints on 32bit diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1219,6 +1219,7 @@ val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_column_int64(self._statement, i) + val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_column_double(self._statement, i) elif typ == _lib.SQLITE_TEXT: @@ -1342,6 +1343,7 @@ val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_value_int64(params[i]) + val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_value_double(params[i]) elif typ == _lib.SQLITE_TEXT: From noreply at buildbot.pypy.org Fri Mar 8 06:55:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 06:55:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308055551.7A9111C023D@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62213:35cbae0c2105 Date: 2013-03-08 00:55 -0500 http://bitbucket.org/pypy/pypy/changeset/35cbae0c2105/ Log: merge default diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1219,6 +1219,7 @@ val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_column_int64(self._statement, i) + val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_column_double(self._statement, i) elif typ == _lib.SQLITE_TEXT: @@ -1342,6 +1343,7 @@ val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_value_int64(params[i]) + val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_value_double(params[i]) elif typ == _lib.SQLITE_TEXT: From noreply at buildbot.pypy.org Fri Mar 8 07:45:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 07:45:31 +0100 (CET) Subject: [pypy-commit] pypy default: generalize these imports for py2/py3 Message-ID: <20130308064531.2D4E31C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62214:2508584f0728 Date: 2013-03-08 01:44 -0500 http://bitbucket.org/pypy/pypy/changeset/2508584f0728/ Log: generalize these imports for py2/py3 diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -111,7 +111,7 @@ # Internal stuff try: - from thread import _local + from threading import local as _local except ImportError: class _local(object): # assume no threads pass diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py --- a/lib_pypy/stackless.py +++ b/lib_pypy/stackless.py @@ -93,7 +93,7 @@ try: - from thread import _local + from threading import local as _local except ImportError: class _local(object): # assume no threads pass From noreply at buildbot.pypy.org Fri Mar 8 07:45:32 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 07:45:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308064532.6DFE21C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62215:1854c25557ed Date: 2013-03-08 01:45 -0500 http://bitbucket.org/pypy/pypy/changeset/1854c25557ed/ Log: merge default diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -111,7 +111,7 @@ # Internal stuff try: - from _thread import _local + from threading import local as _local except ImportError: class _local(object): # assume no threads pass diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py --- a/lib_pypy/stackless.py +++ b/lib_pypy/stackless.py @@ -93,7 +93,7 @@ try: - from _thread import _local + from threading import local as _local except ImportError: class _local(object): # assume no threads pass From noreply at buildbot.pypy.org Fri Mar 8 08:02:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 08:02:51 +0100 (CET) Subject: [pypy-commit] pypy default: some fixes/cleanups from py3k version Message-ID: <20130308070251.38A841C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62216:04e522a23446 Date: 2013-03-08 01:56 -0500 http://bitbucket.org/pypy/pypy/changeset/04e522a23446/ Log: some fixes/cleanups from py3k version diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha.py --- a/lib_pypy/_sha.py +++ b/lib_pypy/_sha.py @@ -38,12 +38,12 @@ s = '' pack = struct.pack while n > 0: - s = pack('>I', n & 0xffffffffL) + s + s = pack('>I', n & 0xffffffff) + s n = n >> 32 # Strip off leading zeros. for i in range(len(s)): - if s[i] <> '\000': + if s[i] != '\000': break else: # Only happens when n == 0. @@ -63,16 +63,16 @@ def _bytelist2longBigEndian(list): "Transform a list of characters into a list of longs." - imax = len(list)/4 - hl = [0L] * imax + imax = len(list) // 4 + hl = [0] * imax j = 0 i = 0 while i < imax: - b0 = long(ord(list[j])) << 24 - b1 = long(ord(list[j+1])) << 16 - b2 = long(ord(list[j+2])) << 8 - b3 = long(ord(list[j+3])) + b0 = ord(list[j]) << 24 + b1 = ord(list[j+1]) << 16 + b2 = ord(list[j+2]) << 8 + b3 = ord(list[j+3]) hl[i] = b0 | b1 | b2 | b3 i = i+1 j = j+4 @@ -108,10 +108,10 @@ # Constants to be used K = [ - 0x5A827999L, # ( 0 <= t <= 19) - 0x6ED9EBA1L, # (20 <= t <= 39) - 0x8F1BBCDCL, # (40 <= t <= 59) - 0xCA62C1D6L # (60 <= t <= 79) + 0x5A827999, # ( 0 <= t <= 19) + 0x6ED9EBA1, # (20 <= t <= 39) + 0x8F1BBCDC, # (40 <= t <= 59) + 0xCA62C1D6 # (60 <= t <= 79) ] class sha: @@ -124,7 +124,7 @@ "Initialisation." # Initial message length in bits(!). - self.length = 0L + self.length = 0 self.count = [0, 0] # Initial empty message as a sequence of bytes (8 bit characters). @@ -138,21 +138,21 @@ def init(self): "Initialize the message-digest and set all fields to zero." - self.length = 0L + self.length = 0 self.input = [] # Initial 160 bit message digest (5 times 32 bit). - self.H0 = 0x67452301L - self.H1 = 0xEFCDAB89L - self.H2 = 0x98BADCFEL - self.H3 = 0x10325476L - self.H4 = 0xC3D2E1F0L + self.H0 = 0x67452301 + self.H1 = 0xEFCDAB89 + self.H2 = 0x98BADCFE + self.H3 = 0x10325476 + self.H4 = 0xC3D2E1F0 def _transform(self, W): for t in range(16, 80): W.append(_rotateLeft( - W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1) & 0xffffffffL) + W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1) & 0xffffffff) A = self.H0 B = self.H1 @@ -166,49 +166,49 @@ TEMP = _rotateLeft(A, 5) + f[t/20] + E + W[t] + K[t/20] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff """ for t in range(0, 20): TEMP = _rotateLeft(A, 5) + ((B & C) | ((~ B) & D)) + E + W[t] + K[0] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff for t in range(20, 40): TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[1] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff for t in range(40, 60): TEMP = _rotateLeft(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff for t in range(60, 80): TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[3] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff - self.H0 = (self.H0 + A) & 0xffffffffL - self.H1 = (self.H1 + B) & 0xffffffffL - self.H2 = (self.H2 + C) & 0xffffffffL - self.H3 = (self.H3 + D) & 0xffffffffL - self.H4 = (self.H4 + E) & 0xffffffffL + self.H0 = (self.H0 + A) & 0xffffffff + self.H1 = (self.H1 + B) & 0xffffffff + self.H2 = (self.H2 + C) & 0xffffffff + self.H3 = (self.H3 + D) & 0xffffffff + self.H4 = (self.H4 + E) & 0xffffffff # Down from here all methods follow the Python Standard Library @@ -230,10 +230,10 @@ to the hashed string. """ - leninBuf = long(len(inBuf)) + leninBuf = len(inBuf) # Compute number of bytes mod 64. - index = (self.count[1] >> 3) & 0x3FL + index = (self.count[1] >> 3) & 0x3F # Update number of bits. self.count[1] = self.count[1] + (leninBuf << 3) @@ -273,7 +273,7 @@ input = [] + self.input count = [] + self.count - index = (self.count[1] >> 3) & 0x3fL + index = (self.count[1] >> 3) & 0x3f if index < 56: padLen = 56 - index From noreply at buildbot.pypy.org Fri Mar 8 08:02:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 08:02:52 +0100 (CET) Subject: [pypy-commit] pypy default: redundant Message-ID: <20130308070252.91B791C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62217:e3de1062e2c6 Date: 2013-03-08 02:01 -0500 http://bitbucket.org/pypy/pypy/changeset/e3de1062e2c6/ Log: redundant diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -225,10 +225,7 @@ elif data == TRUE[1:]: val = True else: - try: - val = int(data) - except ValueError: - val = long(data) + val = int(data) self.append(val) dispatch[INT] = load_int From noreply at buildbot.pypy.org Fri Mar 8 08:02:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 08:02:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix comment Message-ID: <20130308070253.B62DF1C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62218:87fe65b23854 Date: 2013-03-08 01:55 -0500 http://bitbucket.org/pypy/pypy/changeset/87fe65b23854/ Log: fix comment diff --git a/lib_pypy/_sha1.py b/lib_pypy/_sha1.py --- a/lib_pypy/_sha1.py +++ b/lib_pypy/_sha1.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# -*- coding: iso-8859-1 +# -*- coding: iso-8859-1 -*- # Note that PyPy contains also a built-in module 'sha' which will hide # this one if compiled in. From noreply at buildbot.pypy.org Fri Mar 8 08:24:14 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 8 Mar 2013 08:24:14 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Configure wait macros individually Message-ID: <20130308072414.D7DF31C1130@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r62220:dc601bc3b3c5 Date: 2013-03-08 08:22 +0100 http://bitbucket.org/pypy/pypy/changeset/dc601bc3b3c5/ Log: Configure wait macros individually diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -142,8 +142,8 @@ interpleveldefs['pathconf_names'] = 'space.wrap(os.pathconf_names)' # Macros for process exit statuses: WIFEXITED &co - if rposix.HAVE_WAIT: - for name in rposix.wait_macros: + for name in rposix.wait_macros: + if getattr(rposix, 'HAVE_' + name): interpleveldefs[name] = 'interp_posix.' + name def __init__(self, space, w_name): diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -125,6 +125,13 @@ '''.split(): setattr(CConfig, name, rffi_platform.DefinedConstantInteger(name)) +wait_macros_returning_int = ['WEXITSTATUS', 'WSTOPSIG', 'WTERMSIG'] +wait_macros_returning_bool = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED', + 'WIFSIGNALED', 'WIFEXITED'] +wait_macros = wait_macros_returning_int + wait_macros_returning_bool +for name in wait_macros: + setattr(CConfig, 'HAVE_' + name, rffi_platform.Defined(name)) + globals().update(rffi_platform.configure(CConfig)) @@ -174,14 +181,9 @@ c_fchmod = external('fchmod', [rffi.INT, rffi.MODE_T], rffi.INT) c_fchown = external('fchown', [rffi.INT, rffi.INT, rffi.INT], rffi.INT) -if HAVE_WAIT: - wait_macros_returning_int = ['WEXITSTATUS', 'WSTOPSIG', 'WTERMSIG'] - wait_macros_returning_bool = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED', - 'WIFSIGNALED', 'WIFEXITED'] - wait_macros = wait_macros_returning_int + wait_macros_returning_bool - for name in wait_macros: - globals()[name] = external(name, [lltype.Signed], lltype.Signed, - macro=True) +for name in wait_macros: + globals()[name] = external(name, [lltype.Signed], lltype.Signed, + macro=True) #___________________________________________________________________ From noreply at buildbot.pypy.org Fri Mar 8 08:24:13 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 8 Mar 2013 08:24:13 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Fix translation Message-ID: <20130308072413.7B2A51C1063@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r62219:75e81b9becd8 Date: 2013-03-08 08:08 +0100 http://bitbucket.org/pypy/pypy/changeset/75e81b9becd8/ Log: Fix translation diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1085,7 +1085,7 @@ def wait_macro(space, status): result = getattr(rposix, name)(status) if return_bool: - return space.newbool(result) + return space.newbool(bool(result)) else: return space.wrap(result) return wait_macro From noreply at buildbot.pypy.org Fri Mar 8 10:16:56 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 10:16:56 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: result of primitive SUSPEND is new frame Message-ID: <20130308091656.CD8BD1C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r140:43be3cfa850d Date: 2013-03-07 23:43 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/43be3cfa850d/ Log: result of primitive SUSPEND is new frame diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -968,7 +968,7 @@ w_frame = interp.space.unwrap_pointersobject(w_frame) return w_frame.as_context_get_shadow(interp.space) - at expose_primitive(SUSPEND, unwrap_spec=[object]) + at expose_primitive(SUSPEND, unwrap_spec=[object], result_is_new_frame=True) def func(interp, s_frame, w_rcvr, result_is_new_frame=True): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( From noreply at buildbot.pypy.org Fri Mar 8 10:16:57 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 10:16:57 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Add GET_NEXT_EVENT and DRAW_RECTANGLE stubs Message-ID: <20130308091657.E65141C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r141:1544fbf12f74 Date: 2013-03-08 10:16 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/1544fbf12f74/ Log: Add GET_NEXT_EVENT and DRAW_RECTANGLE stubs diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -528,13 +528,16 @@ KBD_PEEK = 109 + at expose_primitive(GET_NEXT_EVENT, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + raise PrimitiveNotYetWrittenError() + @expose_primitive(BE_CURSOR, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): # TODO: Use info from cursor object. interp.space.objtable['w_cursor'] = w_rcvr return w_rcvr - @expose_primitive(BE_DISPLAY, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 4: @@ -643,6 +646,7 @@ VALUE_UNINTERRUPTABLY = 123 LOW_SPACE_SEMAPHORE = 124 SIGNAL_AT_BYTES_LEFT = 125 +DRAW_RECTANGLE = 127 @expose_primitive(IMAGE_NAME) def func(interp, s_frame, argument_count): @@ -664,6 +668,10 @@ # dont know when the space runs out return w_reciver + at expose_primitive(DRAW_RECTANGLE, unwrap_spec=[object, int, int, int, int]) +def func(interp, s_frame, w_rcvr, left, right, top, bottom): + raise PrimitiveNotYetWrittenError() + # ___________________________________________________________________________ # Squeak Miscellaneous Primitives (128-149) From noreply at buildbot.pypy.org Fri Mar 8 10:16:59 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 10:16:59 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Merge default Message-ID: <20130308091659.5D1911C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r142:189f3b3f83e5 Date: 2013-03-08 10:16 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/189f3b3f83e5/ Log: Merge default diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,3 +1,7 @@ syntax: glob *.py[co] *~ +pypy-c-jit-62116-b027d4428675-linux +images/Squeak* +targetimageloadingsmalltalk-c +images/package-cache diff --git a/images/minitest.image b/images/minitest.image index 5753d32adc6e5ca83c6b7bf990258090ca1812d7..11fbf4e52f946020cefb4e771afc7a950f001596 GIT binary patch [cut] diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -33,7 +33,7 @@ get_printable_location=get_printable_location ) - def __init__(self, space, image=None, image_name="", max_stack_depth=500): + def __init__(self, space, image=None, image_name="", max_stack_depth=100): self.space = space self.image = image self.image_name = image_name @@ -72,10 +72,17 @@ s_new_context.push(nlr.value) def c_loop(self, s_context): + # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) + # print padding + s_context.short_str() + old_pc = 0 while True: pc = s_context._pc method = s_context.s_method() - + if pc < old_pc: + self.jit_driver.can_enter_jit( + pc=pc, self=self, method=method, + s_context=s_context) + old_pc = pc self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, s_context=s_context) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -532,6 +532,7 @@ self._temps_and_stack[ptr] = w_v self._stack_ptr = ptr + 1 + @jit.unroll_safe def push_all(self, lst): for elt in lst: self.push(elt) @@ -690,6 +691,10 @@ # A blockcontext doesn't have any temps return 0 + def short_str(self): + return 'BlockContext of %s (%i)' % (self.w_method().get_identifier_string(), + self.pc() + 1) + class MethodContextShadow(ContextPartShadow): _attr_ = ['w_closure_or_nil', '_w_receiver', '__w_method'] @@ -836,6 +841,10 @@ retval += "\nStack : " + str(self.stack()) return retval + def short_str(self): + block = '[] of' if self.is_closure_context() else '' + return '%s %s (%i)' % (block, self.w_method().get_identifier_string(), self.pc() + 1) + class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", "literals[*]", "bytecodeoffset", diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -4,7 +4,7 @@ # view jit. # -import sys +import sys, os from rpython import conftest class o: view = False @@ -15,8 +15,9 @@ from spyvm import model, interpreter, primitives, shadow -from spyvm import objspace +from spyvm import objspace, squeakimage from spyvm.tool.analyseimage import create_squeakimage, create_testimage +from rpython.rlib.streamio import open_file_as_stream mockclass = objspace.bootstrap_class @@ -46,7 +47,7 @@ # Tests # -# sys.setrecursionlimit(100000) +sys.setrecursionlimit(5000) class TestLLtype(LLJitMixin): @@ -54,19 +55,12 @@ from spyvm import objspace space = objspace.ObjSpace() + image = create_testimage(space) interp = interpreter.Interpreter(space, image) - - - counter = 0 - - w_selector = interp.perform(space.wrap_string("loopTest"), "asSymbol") - w_object = model.W_SmallInteger(0) - s_class = w_object.shadow_of_my_class(space) - s_method = s_class.lookup(w_selector) - s_frame = s_method.create_frame(space, w_object, []) - + w_selector = interp.perform(space.wrap_string('loopTest'), "asSymbol") + assert isinstance(w_selector, model.W_BytesObject) def interp_w(): - interp.loop(s_frame.w_self()) + interp.perform(model.W_SmallInteger(1000), w_selector) self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True, inline=True) diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -11,10 +11,12 @@ def _run_benchmark(interp, number, benchmark): w_object = model.W_SmallInteger(number) try: - interp.perform(w_object, benchmark) + w_result = interp.perform(w_object, benchmark) except interpreter.ReturnFromTopLevel, e: w_result = e.object + if w_result: assert isinstance(w_result, model.W_BytesObject) + print '\n' print w_result.as_string() return 0 return -1 From noreply at buildbot.pypy.org Fri Mar 8 10:23:47 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 10:23:47 +0100 (CET) Subject: [pypy-commit] pypy default: more datetime cleanups Message-ID: <20130308092347.CBA471C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62222:088bb74ed873 Date: 2013-03-08 03:36 -0500 http://bitbucket.org/pypy/pypy/changeset/088bb74ed873/ Log: more datetime cleanups diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -16,6 +16,7 @@ Thanks to Tim Peters for suggesting using it. """ +from __future__ import division import time as _time import math as _math import struct as _struct @@ -182,9 +183,9 @@ "methods require year >= %d" % (year, _MINYEARFMT, _MINYEARFMT)) # Don't call utcoffset() or tzname() unless actually needed. - freplace = None # the string to use for %f - zreplace = None # the string to use for %z - Zreplace = None # the string to use for %Z + freplace = None # the string to use for %f + zreplace = None # the string to use for %z + Zreplace = None # the string to use for %Z # Scan format for %z and %Z escapes, replacing as needed. newformat = [] @@ -577,7 +578,7 @@ def total_seconds(self): """Total seconds in the duration.""" return ((self.days * 86400 + self.seconds) * 10**6 + - self.microseconds) / 1e6 + self.microseconds) / 10**6 # Read-only field accessors @property @@ -647,12 +648,15 @@ __rmul__ = __mul__ + def _to_microseconds(self): + return ((self._days * (24*3600) + self._seconds) * 1000000 + + self._microseconds) + def __div__(self, other): - if isinstance(other, (int, long)): - usec = ((self._days * (24*3600L) + self._seconds) * 1000000 + - self._microseconds) - return timedelta(0, 0, usec // other) - return NotImplemented + if not isinstance(other, (int, long)): + return NotImplemented + usec = self._to_microseconds() + return timedelta(0, 0, usec // other) __floordiv__ = __div__ @@ -1255,7 +1259,7 @@ def __hash__(self): """Hash.""" tzoff = self._utcoffset() - if not tzoff: # zero or None + if not tzoff: # zero or None return hash(self._getstate()[0]) h, m = divmod(self.hour * 60 + self.minute - tzoff, 60) if 0 <= h < 24: @@ -1312,7 +1316,7 @@ """Format using strftime(). The date part of the timestamp passed to underlying strftime should not be used. """ - # The year must be >= 1900 else Python's strftime implementation + # The year must be >= _MINYEARFMT else Python's strftime implementation # can raise a bogus exception. timetuple = (1900, 1, 1, self._hour, self._minute, self._second, @@ -1395,9 +1399,9 @@ def __nonzero__(self): if self.second or self.microsecond: - return 1 + return True offset = self._utcoffset() or 0 - return self.hour * 60 + self.minute - offset != 0 + return self.hour * 60 + self.minute != offset # Pickle support. @@ -1613,8 +1617,8 @@ year, month, day = _check_date_fields(year, month, day) hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - return datetime(year, month, day, hour, minute, second, - microsecond, tzinfo) + return datetime(year, month, day, hour, minute, second, microsecond, + tzinfo) def astimezone(self, tz): if not isinstance(tz, tzinfo): @@ -1660,10 +1664,9 @@ Optional argument sep specifies the separator between date and time, default 'T'. """ - s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, - sep) + - _format_time(self._hour, self._minute, self._second, - self._microsecond)) + s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + + _format_time(self._hour, self._minute, self._second, + self._microsecond)) off = self._utcoffset() if off is not None: if off < 0: @@ -1677,7 +1680,7 @@ def __repr__(self): """Convert to formal string, for repr().""" - L = [self._year, self._month, self._day, # These are never zero + L = [self._year, self._month, self._day, # These are never zero self._hour, self._minute, self._second, self._microsecond] if L[-1] == 0: del L[-1] @@ -1920,7 +1923,7 @@ # XXX This could be done more efficiently THURSDAY = 3 firstday = _ymd2ord(year, 1, 1) - firstweekday = (firstday + 6) % 7 # See weekday() above + firstweekday = (firstday + 6) % 7 # See weekday() above week1monday = firstday - firstweekday if firstweekday > THURSDAY: week1monday += 7 From noreply at buildbot.pypy.org Fri Mar 8 10:23:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 10:23:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: more datetime cleanups Message-ID: <20130308092356.441E61C101B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62223:d9fa043f30c0 Date: 2013-03-08 03:35 -0500 http://bitbucket.org/pypy/pypy/changeset/d9fa043f30c0/ Log: more datetime cleanups diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -29,7 +29,7 @@ MINYEAR = 1 MAXYEAR = 9999 _MINYEARFMT = 1000 -_MAXORDINAL = 3652059 # date.max.toordinal() +_MAXORDINAL = 3652059 # date.max.toordinal() # Utility functions, adapted from Python's Demo/classes/Dates.py, which # also assumes the current Gregorian calendar indefinitely extended in @@ -183,9 +183,9 @@ "methods require year >= %d" % (year, _MINYEARFMT, _MINYEARFMT)) # Don't call utcoffset() or tzname() unless actually needed. - freplace = None # the string to use for %f - zreplace = None # the string to use for %z - Zreplace = None # the string to use for %Z + freplace = None # the string to use for %f + zreplace = None # the string to use for %z + Zreplace = None # the string to use for %Z # Scan format for %z and %Z escapes, replacing as needed. newformat = [] @@ -266,9 +266,9 @@ raise ValueError("tzinfo.%s() must return a whole number " "of minutes, got %s" % (name, offset)) if not -timedelta(1) < offset < timedelta(1): - raise ValueError("%s()=%s, must be must be strictly between" - " -timedelta(hours=24) and timedelta(hours=24)" - % (name, offset)) + raise ValueError("%s()=%s, must be must be strictly between " + "-timedelta(hours=24) and timedelta(hours=24)" % + (name, offset)) def _check_int_field(value): if isinstance(value, int): @@ -1158,7 +1158,7 @@ def __hash__(self): """Hash.""" tzoff = self.utcoffset() - if not tzoff: # zero or None + if not tzoff: # zero or None return hash(self._getstate()[0]) h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, timedelta(hours=1)) @@ -1220,7 +1220,7 @@ """Format using strftime(). The date part of the timestamp passed to underlying strftime should not be used. """ - # The year must be >= 1000 else Python's strftime implementation + # The year must be >= _MINYEARFMT else Python's strftime implementation # can raise a bogus exception. timetuple = (1900, 1, 1, self._hour, self._minute, self._second, @@ -1467,7 +1467,7 @@ def utctimetuple(self): "Return UTC time tuple compatible with time.gmtime()." offset = self.utcoffset() - if offset: + if offset: # neither None nor 0 self -= offset y, m, d = self.year, self.month, self.day hh, mm, ss = self.hour, self.minute, self.second @@ -1508,8 +1508,8 @@ year, month, day = _check_date_fields(year, month, day) hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - return datetime(year, month, day, hour, minute, second, - microsecond, tzinfo) + return datetime(year, month, day, hour, minute, second, microsecond, + tzinfo) def astimezone(self, tz): if not isinstance(tz, tzinfo): @@ -1555,10 +1555,9 @@ Optional argument sep specifies the separator between date and time, default 'T'. """ - s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, - sep) + - _format_time(self._hour, self._minute, self._second, - self._microsecond)) + s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + + _format_time(self._hour, self._minute, self._second, + self._microsecond)) off = self.utcoffset() if off is not None: if off.days < 0: @@ -1574,7 +1573,7 @@ def __repr__(self): """Convert to formal string, for repr().""" - L = [self._year, self._month, self._day, # These are never zero + L = [self._year, self._month, self._day, # These are never zero self._hour, self._minute, self._second, self._microsecond] if L[-1] == 0: del L[-1] @@ -1803,7 +1802,7 @@ # XXX This could be done more efficiently THURSDAY = 3 firstday = _ymd2ord(year, 1, 1) - firstweekday = (firstday + 6) % 7 # See weekday() above + firstweekday = (firstday + 6) % 7 # See weekday() above week1monday = firstday - firstweekday if firstweekday > THURSDAY: week1monday += 7 @@ -1824,13 +1823,12 @@ elif not isinstance(name, str): raise TypeError("name must be a string") if not cls._minoffset <= offset <= cls._maxoffset: - raise ValueError("offset must be a timedelta" - " strictly between -timedelta(hours=24) and" - " timedelta(hours=24).") - if (offset.microseconds != 0 or - offset.seconds % 60 != 0): - raise ValueError("offset must be a timedelta" - " representing a whole number of minutes") + raise ValueError("offset must be a timedelta " + "strictly between -timedelta(hours=24) and " + "timedelta(hours=24).") + if (offset.microseconds != 0 or offset.seconds % 60 != 0): + raise ValueError("offset must be a timedelta " + "representing a whole number of minutes") return cls._create(offset, name) @classmethod From noreply at buildbot.pypy.org Fri Mar 8 11:56:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 11:56:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: make sure _sha1.py is a rename of _sha.py Message-ID: <20130308105634.3E3CB1C106A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62224:4755120a3013 Date: 2013-03-08 05:34 -0500 http://bitbucket.org/pypy/pypy/changeset/4755120a3013/ Log: make sure _sha1.py is a rename of _sha.py diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha1.py rename from lib_pypy/_sha.py rename to lib_pypy/_sha1.py From noreply at buildbot.pypy.org Fri Mar 8 11:56:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 11:56:35 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130308105635.6FF321C1130@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62225:519f437454e2 Date: 2013-03-08 05:37 -0500 http://bitbucket.org/pypy/pypy/changeset/519f437454e2/ Log: merge heads From noreply at buildbot.pypy.org Fri Mar 8 11:56:36 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 11:56:36 +0100 (CET) Subject: [pypy-commit] pypy default: reduce diff with py3k Message-ID: <20130308105636.AB8681C106A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62226:5d07492ad82c Date: 2013-03-08 05:54 -0500 http://bitbucket.org/pypy/pypy/changeset/5d07492ad82c/ Log: reduce diff with py3k diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha.py --- a/lib_pypy/_sha.py +++ b/lib_pypy/_sha.py @@ -35,7 +35,7 @@ """ # After much testing, this algorithm was deemed to be the fastest. - s = '' + s = b'' pack = struct.pack while n > 0: s = pack('>I', n & 0xffffffff) + s diff --git a/lib_pypy/_sha512.py b/lib_pypy/_sha512.py --- a/lib_pypy/_sha512.py +++ b/lib_pypy/_sha512.py @@ -10,7 +10,7 @@ def new_shaobject(): return { - 'digest': [0L]*8, + 'digest': [0]*8, 'count_lo': 0, 'count_hi': 0, 'data': [0]* SHA_BLOCKSIZE, From noreply at buildbot.pypy.org Fri Mar 8 11:56:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 11:56:37 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308105637.E85031C106A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62227:f29a5fb79bf2 Date: 2013-03-08 05:56 -0500 http://bitbucket.org/pypy/pypy/changeset/f29a5fb79bf2/ Log: merge default From noreply at buildbot.pypy.org Fri Mar 8 13:34:17 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 13:34:17 +0100 (CET) Subject: [pypy-commit] cffi default: Since we have users, make sure we actually emit UserWarning, instead of just Message-ID: <20130308123417.D26CD1C39D4@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r1189:9396a71e3971 Date: 2013-03-08 14:33 +0200 http://bitbucket.org/cffi/cffi/changeset/9396a71e3971/ Log: Since we have users, make sure we actually emit UserWarning, instead of just crashing. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -1,4 +1,4 @@ -import types +import types, warnings try: callable @@ -231,7 +231,7 @@ """ return self._backend.buffer(cdata, size) - def callback(self, cdecl, error=None): + def callback(self, cdecl, python_callable=None, error=None): """Return a a decorator making a callback object. 'cdecl' must name a C function or function pointer type. The decorated Python function is turned into a of the specified @@ -246,9 +246,10 @@ return self._backend.callback(cdecl, python_callable, error) if isinstance(cdecl, basestring): cdecl = self._typeof(cdecl, consider_function_as_funcptr=True) - if isinstance(error, types.FunctionType): - raise TypeError("Not supported any more: ffi.callback('...', fn)." - " Use the decorator form: @ffi.callback('...')") + if python_callable is not None: + warnings.warn("Not supported any more: ffi.callback('...', fn)." + " Use the decorator form: @ffi.callback('...')") + return callback_decorator_wrap(python_callable) return callback_decorator_wrap def getctype(self, cdecl, replace_with=''): diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -811,6 +811,7 @@ res = a(1) # and the error reported to stderr assert res == 42 # + py.test.skip("this is deprecated, not removed yet") @ffi.callback("int(int)", 46) def a(n): raise Exception @@ -1272,6 +1273,7 @@ sz = ffi.sizeof("long") assert cb((1 << (sz*8-1)) - 1, -10) == 42 # + py.test.skip("Deprecated, not removed") py.test.raises(TypeError, ffi.callback, "int(int)", lambda n: n+1) py.test.raises(TypeError, ffi.callback, "int(int)", lambda n: n+1, error=42) From noreply at buildbot.pypy.org Fri Mar 8 13:43:42 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 13:43:42 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, tpape) store the last context when suspending, and raise to the trampoline when switching contexts Message-ID: <20130308124343.1665E1C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r143:683631ae4a75 Date: 2013-03-08 13:11 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/683631ae4a75/ Log: (tfel, tpape) store the last context when suspending, and raise to the trampoline when switching contexts diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -70,6 +70,9 @@ s_new_context.mark_returned() s_new_context = s_sender s_new_context.push(nlr.value) + except ProcessSwitch, p: + self.remaining_stack_depth = self.max_stack_depth + s_new_context = p.s_new_context def c_loop(self, s_context): # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) @@ -146,11 +149,17 @@ class StackOverflow(Exception): def __init__(self, s_top_context): self.s_context = s_top_context + class Return(Exception): def __init__(self, object, s_context): self.value = object self.s_target_context = s_context +class ProcessSwitch(Exception): + def __init__(self, s_context): + self.s_new_context = s_context + + def make_call_primitive_bytecode(primitive, selector, argcount): def callPrimitive(self, interp, current_bytecode): # WARNING: this is used for bytecodes for which it is safe to diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py --- a/spyvm/test/test_wrapper.py +++ b/spyvm/test/test_wrapper.py @@ -144,11 +144,13 @@ def test_suspend_active(self): process, old_process = self.make_processes(4, 2, space.w_false) - old_process.suspend(space.w_true) + w_fake_context = model.W_Object() + old_process.suspend(w_fake_context) process_list = wrapper.scheduler(space).get_process_list(old_process.priority()) assert process_list.first_link() is process_list.last_link() assert process_list.first_link() is space.w_nil assert old_process.my_list() is space.w_nil + assert old_process.suspended_context() is w_fake_context assert wrapper.scheduler(space).active_process() is process._w_self def new_process_consistency(self, process, old_process, w_active_context, @@ -181,7 +183,7 @@ def test_activate(self): process, old_process = self.make_processes(4, 2, space.w_false) - w_frame = process.activate(space.w_true) + w_frame = process.activate() self.new_process_consistency(process, old_process, w_frame, space.w_true, space.w_false) diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -71,13 +71,15 @@ process_list = sched.get_process_list(priority) process_list.add_process(self._w_self) - def activate(self, w_current_frame): + def activate(self): + from spyvm.interpreter import ProcessSwitch + assert not self.is_active_process() sched = scheduler(self.space) sched.store_active_process(self._w_self) w_frame = self.suspended_context() self.store_suspended_context(self.space.w_nil) self.store_my_list(self.space.w_nil) - return w_frame + raise ProcessSwitch(w_frame.as_context_get_shadow(self.space)) def deactivate(self, w_current_frame): self.put_to_sleep() @@ -90,7 +92,7 @@ priority = self.priority() if priority > active_priority: active_process.deactivate(w_current_frame) - return self.activate(w_current_frame) + return self.activate() else: self.put_to_sleep() return w_current_frame @@ -102,7 +104,8 @@ if self.is_active_process(): assert self.my_list().is_same_object(self.space.w_nil) w_process = scheduler(self.space).highest_priority_process() - return ProcessWrapper(self.space, w_process).activate(w_current_frame) + self.store_suspended_context(w_current_frame) + return ProcessWrapper(self.space, w_process).activate() else: process_list = ProcessListWrapper(self.space, self.my_list()) process_list.remove(self._w_self) From noreply at buildbot.pypy.org Fri Mar 8 13:43:46 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 13:43:46 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: translation fix Message-ID: <20130308124346.7F2D81C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r144:6f82341bf834 Date: 2013-03-08 13:14 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/6f82341bf834/ Log: translation fix diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -79,6 +79,7 @@ w_frame = self.suspended_context() self.store_suspended_context(self.space.w_nil) self.store_my_list(self.space.w_nil) + assert isinstance(w_frame, model.W_PointersObject) raise ProcessSwitch(w_frame.as_context_get_shadow(self.space)) def deactivate(self, w_current_frame): From noreply at buildbot.pypy.org Fri Mar 8 13:43:48 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 13:43:48 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fix wrapper tests that should now raise a ProcessSwitch to expect that raise and to use wrapped context objects Message-ID: <20130308124348.1A0C41C101B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r145:55b027170225 Date: 2013-03-08 13:40 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/55b027170225/ Log: fix wrapper tests that should now raise a ProcessSwitch to expect that raise and to use wrapped context objects diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py --- a/spyvm/test/test_wrapper.py +++ b/spyvm/test/test_wrapper.py @@ -1,11 +1,14 @@ import py -from spyvm import wrapper -from spyvm import model +from spyvm import wrapper, model, interpreter, objspace from spyvm.error import WrapperException, FatalError -from spyvm import objspace + +from spyvm.test.test_interpreter import new_frame as new_frame_tuple space = objspace.ObjSpace() +def new_frame(): + return new_frame_tuple("")[0] + def test_simpleread(): w_o = model.W_PointersObject(None, 2) w = wrapper.Wrapper(space, w_o) @@ -143,20 +146,20 @@ assert process.my_list() is space.w_nil def test_suspend_active(self): - process, old_process = self.make_processes(4, 2, space.w_false) - w_fake_context = model.W_Object() - old_process.suspend(w_fake_context) + suspended_context = new_frame() + process, old_process = self.make_processes(4, 2, suspended_context) + current_context = new_frame() + with py.test.raises(interpreter.ProcessSwitch): + old_process.suspend(current_context) process_list = wrapper.scheduler(space).get_process_list(old_process.priority()) assert process_list.first_link() is process_list.last_link() assert process_list.first_link() is space.w_nil assert old_process.my_list() is space.w_nil - assert old_process.suspended_context() is w_fake_context + assert old_process.suspended_context() is current_context assert wrapper.scheduler(space).active_process() is process._w_self - def new_process_consistency(self, process, old_process, w_active_context, - old_active_context, new_active_context): + def new_process_consistency(self, process, old_process, w_active_context): scheduler = wrapper.scheduler(space) - assert w_active_context is new_active_context assert scheduler.active_process() is process._w_self priority_list = wrapper.scheduler(space).get_process_list(process.priority()) assert priority_list.first_link() is priority_list.last_link() @@ -182,23 +185,29 @@ def test_activate(self): - process, old_process = self.make_processes(4, 2, space.w_false) - w_frame = process.activate() - self.new_process_consistency(process, old_process, w_frame, - space.w_true, space.w_false) + sleepingcontext = new_frame() + process, old_process = self.make_processes(4, 2, sleepingcontext) + try: + process.activate() + except interpreter.ProcessSwitch, e: + w_frame = e.s_new_context._w_self + self.new_process_consistency(process, old_process, w_frame) def test_resume(self): - process, old_process = self.make_processes(4, 2, space.w_false) - w_frame = process.resume(space.w_true) - self.new_process_consistency(process, old_process, w_frame, - space.w_true, space.w_false) - self.old_process_consistency(old_process, space.w_true) + sleepingcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, sleepingcontext) + try: + process.resume(currentcontext) + except interpreter.ProcessSwitch, e: + w_frame = e.s_new_context._w_self + self.new_process_consistency(process, old_process, w_frame) + self.old_process_consistency(old_process, currentcontext) # Does not reactivate old_process because lower priority w_frame = old_process.resume(w_frame) - self.new_process_consistency(process, old_process, w_frame, - space.w_true, space.w_false) - self.old_process_consistency(old_process, space.w_true) + self.new_process_consistency(process, old_process, w_frame) + self.old_process_consistency(old_process, currentcontext) def test_semaphore_excess_signal(self): semaphore = new_semaphore() @@ -219,8 +228,11 @@ def test_semaphore_wait(self): semaphore = new_semaphore() - process, old_process = self.make_processes(4, 2, space.w_false) - semaphore.wait(space.w_true) + suspendedcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, suspendedcontext) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) assert semaphore.first_link() is old_process._w_self assert wrapper.scheduler(space).active_process() is process._w_self @@ -228,11 +240,14 @@ semaphore = new_semaphore() self.space = space semaphore.signal(self) - process, old_process = self.make_processes(4, 2, space.w_false) - semaphore.wait(space.w_true) + suspendedcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, suspendedcontext) + semaphore.wait(currentcontext) assert semaphore.is_empty_list() assert wrapper.scheduler(space).active_process() is old_process._w_self - semaphore.wait(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) assert semaphore.first_link() is old_process._w_self assert wrapper.scheduler(space).active_process() is process._w_self @@ -240,21 +255,28 @@ def test_semaphore_wait_signal(self): semaphore = new_semaphore() - process, old_process = self.make_processes(4, 2, space.w_false) + suspendedcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, suspendedcontext) - semaphore.wait(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) + assert wrapper.scheduler(space).active_process() is process._w_self - semaphore.signal(space.w_true) + semaphore.signal(currentcontext) assert wrapper.scheduler(space).active_process() is process._w_self process_list = wrapper.scheduler(space).get_process_list(old_process.priority()) assert process_list.remove_first_link_of_list() is old_process._w_self process.write(2, space.wrap_int(1)) - old_process.resume(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + old_process.resume(currentcontext) assert wrapper.scheduler(space).active_process() is old_process._w_self - semaphore.wait(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) assert wrapper.scheduler(space).active_process() is process._w_self - semaphore.signal(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.signal(currentcontext) assert wrapper.scheduler(space).active_process() is old_process._w_self process_list = wrapper.scheduler(space).get_process_list(process.priority()) From noreply at buildbot.pypy.org Fri Mar 8 13:59:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:39 +0100 (CET) Subject: [pypy-commit] cffi default: Rename ffi.dlopen() into ffi.dlopen_abi_unchecked(), and make the Message-ID: <20130308125939.0F5281C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1190:64f8c3b134b0 Date: 2013-03-08 01:14 +0100 http://bitbucket.org/cffi/cffi/changeset/64f8c3b134b0/ Log: Rename ffi.dlopen() into ffi.dlopen_abi_unchecked(), and make the functionality stick as close as possible to the C-level dlopen(). diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -99,17 +99,19 @@ cache.clear() def dlopen(self, name, flags=0): - """Load and return a dynamic library identified by 'name'. - The standard C library can be loaded by passing None. + import warnings; warnings.warn( + "ffi.dlopen() will be removed; use ffi.dlopen_abi_unchecked()", + stacklevel=2) + return _make_ffi_library(self, name, flags, guess=True) + + def dlopen_abi_unchecked(self, filename, flags=0): + """Load and return a dynamic library file identified by 'filename'. + On Posix systems this works exactly like dlopen(); see dlopen(3). Note that functions and types declared by 'ffi.cdef()' are not linked to a particular library, just like C headers; in the library we only look for the actual (untyped) symbols. """ - assert isinstance(name, basestring) or name is None - lib, function_cache = _make_ffi_library(self, name, flags) - self._function_caches.append(function_cache) - self._libraries.append(lib) - return lib + return _make_ffi_library(self, filename, flags) def _typeof(self, cdecl, consider_function_as_funcptr=False): # string -> ctype object @@ -340,22 +342,26 @@ self._cdefsources.append(']') -def _make_ffi_library(ffi, libname, flags): +def _make_ffi_library(ffi, libname, flags, guess=False): import os - name = libname - if name is None: - name = 'c' # on Posix only + assert isinstance(libname, basestring) or libname is None backend = ffi._backend - try: - if '.' not in name and '/' not in name: - raise OSError - backendlib = backend.load_library(name, flags) - except OSError: - import ctypes.util - path = ctypes.util.find_library(name) - if path is None: - raise OSError("library not found: %r" % (name,)) - backendlib = backend.load_library(path, flags) + if guess: + _name = libname + if _name is None: + _name = 'c' # on Posix only + try: + if '.' not in _name and '/' not in _name: + raise OSError + backendlib = backend.load_library(_name, flags) + except OSError: + import ctypes.util + path = ctypes.util.find_library(_name) + if path is None: + raise OSError("library not found: %r" % (_name,)) + backendlib = backend.load_library(path, flags) + else: + backendlib = backend.load_library(libname, flags) # def make_accessor(name): key = 'function ' + name @@ -400,4 +406,6 @@ except UnicodeError: pass library = FFILibrary() - return library, library.__dict__ + ffi._function_caches.append(library.__dict__) + ffi._libraries.append(library) + return library diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -3,6 +3,7 @@ import math, os, sys import ctypes.util from cffi.backend_ctypes import CTypesBackend +from cffi.verifier import _get_so_suffix from testing.udir import udir try: @@ -47,6 +48,17 @@ x = m.sin(1.23) assert x == math.sin(1.23) + def test_sin_with_dlopen_abi_unchecked(self): + if _get_so_suffix() != ".so": + py.test.skip("no 'libm.so'") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + double sin(double x); + """) + m = ffi.dlopen_abi_unchecked("libm.so") + x = m.sin(1.23) + assert x == math.sin(1.23) + def test_sinf(self): if sys.platform == 'win32': py.test.skip("no 'sinf'") From noreply at buildbot.pypy.org Fri Mar 8 13:59:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:40 +0100 (CET) Subject: [pypy-commit] cffi default: Close this, which is going to become the branch "cffi-1.0". Message-ID: <20130308125940.2EF4D1C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1191:cb1afce73938 Date: 2013-03-08 13:52 +0100 http://bitbucket.org/cffi/cffi/changeset/cb1afce73938/ Log: Close this, which is going to become the branch "cffi-1.0". From noreply at buildbot.pypy.org Fri Mar 8 13:59:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:41 +0100 (CET) Subject: [pypy-commit] cffi cffi-1.0: Make a branch to move the most recent changes to. Message-ID: <20130308125941.405FF1C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cffi-1.0 Changeset: r1192:136faaa08f66 Date: 2013-03-08 13:53 +0100 http://bitbucket.org/cffi/cffi/changeset/136faaa08f66/ Log: Make a branch to move the most recent changes to. From noreply at buildbot.pypy.org Fri Mar 8 13:59:42 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:42 +0100 (CET) Subject: [pypy-commit] cffi cffi-1.0: Mark the places that would need proper "const" support Message-ID: <20130308125942.552921C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cffi-1.0 Changeset: r1193:d57199d005b4 Date: 2013-03-08 13:54 +0100 http://bitbucket.org/cffi/cffi/changeset/d57199d005b4/ Log: Mark the places that would need proper "const" support diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -182,6 +182,7 @@ isinstance(decl.type.type.type, pycparser.c_ast.IdentifierType) and decl.type.type.type.names == ['__dotdotdot__']): + # XXX may contain 'const': decl.type.quals realtype = model.unknown_ptr_type(decl.name) else: realtype = self._get_type(decl.type, name=decl.name) @@ -190,6 +191,7 @@ raise api.CDefError("unrecognized construct", decl) def _parse_decl(self, decl): + # XXX may contain 'const': decl.quals node = decl.type if isinstance(node, pycparser.c_ast.FuncDecl): tp = self._get_type(node, name=decl.name) @@ -276,11 +278,13 @@ # if isinstance(typenode, pycparser.c_ast.PtrDecl): # pointer type + # XXX may list 'const': typenode.quals (e.g. for 'int * const') const = (isinstance(typenode.type, pycparser.c_ast.TypeDecl) and 'const' in typenode.type.quals) return self._get_type_pointer(self._get_type(typenode.type), const) # if isinstance(typenode, pycparser.c_ast.TypeDecl): + # XXX may list 'const': typenode.quals type = typenode.type if isinstance(type, pycparser.c_ast.IdentifierType): # assume a primitive type. get it from .names, but reduce From noreply at buildbot.pypy.org Fri Mar 8 13:59:43 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:43 +0100 (CET) Subject: [pypy-commit] cffi default: Close this Message-ID: <20130308125943.7A1CF1C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1194:657bee6675c2 Date: 2013-03-08 13:56 +0100 http://bitbucket.org/cffi/cffi/changeset/657bee6675c2/ Log: Close this From noreply at buildbot.pypy.org Fri Mar 8 13:59:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:44 +0100 (CET) Subject: [pypy-commit] cffi cffi-1.0: merge heads Message-ID: <20130308125944.AE9EA1C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cffi-1.0 Changeset: r1195:2c7a859bc43a Date: 2013-03-08 13:56 +0100 http://bitbucket.org/cffi/cffi/changeset/2c7a859bc43a/ Log: merge heads diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -1,4 +1,4 @@ -import types +import types, warnings try: callable @@ -233,7 +233,7 @@ """ return self._backend.buffer(cdata, size) - def callback(self, cdecl, error=None): + def callback(self, cdecl, python_callable=None, error=None): """Return a a decorator making a callback object. 'cdecl' must name a C function or function pointer type. The decorated Python function is turned into a of the specified @@ -248,9 +248,10 @@ return self._backend.callback(cdecl, python_callable, error) if isinstance(cdecl, basestring): cdecl = self._typeof(cdecl, consider_function_as_funcptr=True) - if isinstance(error, types.FunctionType): - raise TypeError("Not supported any more: ffi.callback('...', fn)." - " Use the decorator form: @ffi.callback('...')") + if python_callable is not None: + warnings.warn("Not supported any more: ffi.callback('...', fn)." + " Use the decorator form: @ffi.callback('...')") + return callback_decorator_wrap(python_callable) return callback_decorator_wrap def getctype(self, cdecl, replace_with=''): diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -811,6 +811,7 @@ res = a(1) # and the error reported to stderr assert res == 42 # + py.test.skip("this is deprecated, not removed yet") @ffi.callback("int(int)", 46) def a(n): raise Exception @@ -1272,6 +1273,7 @@ sz = ffi.sizeof("long") assert cb((1 << (sz*8-1)) - 1, -10) == 42 # + py.test.skip("Deprecated, not removed") py.test.raises(TypeError, ffi.callback, "int(int)", lambda n: n+1) py.test.raises(TypeError, ffi.callback, "int(int)", lambda n: n+1, error=42) From noreply at buildbot.pypy.org Fri Mar 8 13:59:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 13:59:45 +0100 (CET) Subject: [pypy-commit] cffi default: A dummy checkin to make this the current 'default'. Message-ID: <20130308125945.C81571C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1196:76204cbe81fa Date: 2013-03-08 13:58 +0100 http://bitbucket.org/cffi/cffi/changeset/76204cbe81fa/ Log: A dummy checkin to make this the current 'default'. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1492,4 +1492,3 @@ * :ref:`genindex` * :ref:`search` - From noreply at buildbot.pypy.org Fri Mar 8 15:15:34 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 15:15:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, tpape) actually check that the vm keeps image name around Message-ID: <20130308141534.9FD031C39D9@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r146:010bf1facb18 Date: 2013-03-08 14:59 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/010bf1facb18/ Log: (tfel, tpape) actually check that the vm keeps image name around diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -32,7 +32,9 @@ if isinstance(x, str): return space.wrap_string(x) if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError - + +IMAGENAME = "anImage.image" + def mock(stack, context = None): mapped_stack = [wrap(x) for x in stack] if context is None: @@ -41,7 +43,7 @@ frame = context for i in range(len(stack)): frame.as_context_get_shadow(space).push(stack[i]) - interp = interpreter.Interpreter(space) + interp = interpreter.Interpreter(space, image_name=IMAGENAME) return (interp, frame, len(stack)) def prim(code, stack, context = None): @@ -428,7 +430,7 @@ def test_image_name(): w_v = prim(primitives.IMAGE_NAME, [2]) - assert w_v.bytes == [] + assert w_v.bytes == list(IMAGENAME) def test_clone(): w_obj = mockclass(space, 1, varsized=True).as_class_get_shadow(space).new(1) diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -51,7 +51,7 @@ def entry_point(argv): idx = 1 - image = None + path = None number = 0 benchmark = None @@ -73,20 +73,20 @@ _arg_missing(argv, idx, arg) benchmark = argv[idx + 1] idx += 1 - elif image is None: - image = argv[idx] + elif path is None: + path = argv[idx] else: _usage(argv) return -1 idx += 1 - if image is None: - image = "Squeak.image" + if path is None: + path = "Squeak.image" try: - f = open_file_as_stream(image) + f = open_file_as_stream(path) except OSError as e: - os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), image)) + os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path)) return 1 try: imagedata = f.readall() @@ -95,7 +95,7 @@ image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata)) image = create_image(space, image_reader) - interp = interpreter.Interpreter(space, image) + interp = interpreter.Interpreter(space, image, image_name=os.path.abspath(path)) if benchmark is not None: return _run_benchmark(interp, number, benchmark) else: From noreply at buildbot.pypy.org Fri Mar 8 15:15:35 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 15:15:35 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, tpape) add FILE_OPEN, CLOSE, and WRITE primitives Message-ID: <20130308141535.CD2961C39D9@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r147:596d12afe439 Date: 2013-03-08 15:15 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/596d12afe439/ Log: (tfel, tpape) add FILE_OPEN, CLOSE, and WRITE primitives diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -1,3 +1,4 @@ +import os import inspect import math import operator @@ -753,10 +754,35 @@ DIRECTORY_LOOKUP = 162 DIRECTORY_DELTE = 163 + at expose_primitive(FILE_CLOSE, unwrap_spec=[object, int]) +def func(interp, s_frame, w_rcvr, fd): + try: + os.close(fd) + return w_rcvr + except OSError: + raise PrimitiveFailedError() + + at expose_primitive(FILE_OPEN, unwrap_spec=[object, str, object]) +def func(interp, s_frame, w_rcvr, filename, w_writeable_flag): + try: + fd = os.open( + filename, + (os.O_RDWR | os.O_CREAT | os.O_TRUNC) if w_writeable_flag is interp.space.w_true else os.O_RDONLY + ) + return interp.space.wrap_int(fd) + except OSError: + raise PrimitiveFailedError() + + at expose_primitive(FILE_WRITE, unwrap_spec=[object, int, str, int, int]) +def func(interp, s_frame, w_rcvr, fd, src, start, count): + try: + os.write(fd, src[start - 1:start + count - 1]) + return w_rcvr + except OSError: + raise PrimitiveFailedError() @expose_primitive(DIRECTORY_DELIMITOR, unwrap_spec=[object]) def func(interp, s_frame, _): - import os.path return interp.space.wrap_char(os.path.sep) diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -1,4 +1,5 @@ import py +import os import math from spyvm.primitives import prim_table, PrimitiveFailedError from spyvm import model, shadow, interpreter @@ -440,12 +441,57 @@ w_obj.atput0(space, 0, space.wrap_int(2)) assert space.unwrap_int(w_v.at0(space, 0)) == 1 +def test_file_open_write(monkeypatch): + def open_write(filename, mode): + assert filename == "nonexistant" + assert mode == os.O_RDWR | os.O_CREAT | os.O_TRUNC + return 42 + monkeypatch.setattr(os, "open", open_write) + try: + w_c = prim(primitives.FILE_OPEN, [1, space.wrap_string("nonexistant"), space.w_true]) + finally: + monkeypatch.undo() + assert space.unwrap_int(w_c) == 42 + +def test_file_open_read(monkeypatch): + def open_read(filename, mode): + assert filename == "file" + assert mode == os.O_RDONLY + return 42 + monkeypatch.setattr(os, "open", open_read) + try: + w_c = prim(primitives.FILE_OPEN, [1, space.wrap_string("file"), space.w_false]) + finally: + monkeypatch.undo() + assert space.unwrap_int(w_c) == 42 + +def test_file_close(monkeypatch): + def close(fd): + assert fd == 42 + monkeypatch.setattr(os, "close", close) + try: + w_c = prim(primitives.FILE_CLOSE, [1, space.wrap_int(42)]) + finally: + monkeypatch.undo() + +def test_file_write(monkeypatch): + def write(fd, string): + assert fd == 42 + assert string == "ell" + monkeypatch.setattr(os, "write", write) + try: + w_c = prim( + primitives.FILE_WRITE, + [1, space.wrap_int(42), space.wrap_string("hello"), space.wrap_int(2), space.wrap_int(3)] + ) + finally: + monkeypatch.undo() + def test_directory_delimitor(): import os.path w_c = prim(primitives.DIRECTORY_DELIMITOR, [1]) assert space.unwrap_char(w_c) == os.path.sep - def test_primitive_closure_copyClosure(): from test_interpreter import new_frame w_frame, s_frame = new_frame("", From noreply at buildbot.pypy.org Fri Mar 8 15:23:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 15:23:39 +0100 (CET) Subject: [pypy-commit] pypy default: hg backout 0d391c72accf Message-ID: <20130308142339.212011C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62231:d3b56dccde34 Date: 2013-03-08 15:20 +0100 http://bitbucket.org/pypy/pypy/changeset/d3b56dccde34/ Log: hg backout 0d391c72accf 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 @@ -2644,17 +2644,6 @@ c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] -def test_FILE_forbidden(): - BFILE = new_struct_type("_IO_FILE") - BFILEP = new_pointer_type(BFILE) - BFunc = new_function_type((BFILEP,), BFILEP, False) - func = cast(BFunc, 0) - with open(__file__, "rb") as f: - e = py.test.raises(TypeError, func, f) - if '__pypy__' not in sys.builtin_module_names: - assert ('note that you cannot pass Python files directly ' - 'any more since CFFI 0.6') in str(e.value) - def test_version(): # this test is here mostly for PyPy assert __version__ == "0.6" From noreply at buildbot.pypy.org Fri Mar 8 15:23:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 15:23:40 +0100 (CET) Subject: [pypy-commit] pypy default: hg backout 87cc13e1bc5e Message-ID: <20130308142340.763621C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62232:0330fbbfcb0b Date: 2013-03-08 15:20 +0100 http://bitbucket.org/pypy/pypy/changeset/0330fbbfcb0b/ Log: hg backout 87cc13e1bc5e diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,8 +174,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['cache_array_type'] - _immutable_fields_ = ['cache_array_type?'] + _attrs_ = ['is_file', 'cache_array_type'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" cache_array_type = None @@ -186,6 +186,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE" or + ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -237,6 +239,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -245,14 +263,20 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + result = self.prepare_file(w_init) + if result: + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return False + return 0 itemsize = self.ctitem.size if itemsize <= 0: if isinstance(self.ctitem, ctypevoid.W_CTypeVoid): itemsize = 1 else: - return False + return 0 try: datasize = ovfcheck(length * itemsize) except OverflowError: @@ -266,7 +290,7 @@ lltype.free(result, flavor='raw') raise rffi.cast(rffi.CCHARPP, cdata)[0] = result - return True + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag @@ -274,7 +298,7 @@ ob = space.interpclass_w(w_ob) result = (not isinstance(ob, cdataobj.W_CData) and self._prepare_pointer_call_argument(w_ob, cdata)) - if not result: + if result == 0: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) return result @@ -304,3 +328,36 @@ if attrchar == 'i': # item return self.space.wrap(self.ctitem) return W_CTypePtrBase._fget(self, attrchar) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + + def close(self): + rffi_fclose(self.llf) + + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf 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 @@ -2497,7 +2497,6 @@ pass # win32 def test_FILE(): - """FILE is not supported natively any more.""" if sys.platform == "win32": py.test.skip("testing FILE not implemented") # @@ -2507,16 +2506,82 @@ BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.flush() # should not be needed + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + fw1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'rb', 256) + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("$FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() fw1 = posix.fdopen(fdw, 'wb', 256) - py.test.raises(TypeError, fputs, b"hello world\n", fw1) - fr1.close() + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert (res == fdw) == (sys.version_info < (3,)) fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) def test_GetLastError(): if sys.platform != "win32": diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from rpython.rtyper.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,8 +149,14 @@ del openstreams[stream] except KeyError: pass - # close the stream. - stream.close1(True) + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open From noreply at buildbot.pypy.org Fri Mar 8 15:23:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 15:23:41 +0100 (CET) Subject: [pypy-commit] pypy default: hg backout 1d661d485129 Message-ID: <20130308142341.A0AA21C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62233:6f52561333cb Date: 2013-03-08 15:20 +0100 http://bitbucket.org/pypy/pypy/changeset/6f52561333cb/ Log: hg backout 1d661d485129 diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -92,15 +92,20 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): + if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a " + "primitive cdata")) cdata2 = other._cdata + elif (misc.is_zero(space, w_other) and + not isinstance(self.ctype, W_CTypePrimitive)): + cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -154,6 +154,10 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): + if misc.is_zero(space, w_ob): + NULL = lltype.nullptr(rffi.CCHARP.TO) + rffi.cast(rffi.CCHARPP, cdata)[0] = NULL + return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -257,7 +261,15 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if misc.is_zero(space, w_init): + # Convert 0 to NULL. Note that passing 0 is not ambigous, + # despite the potential confusion: as a 'T*' argument, 0 means + # NULL, but as a 'T[]' argument it would mean "array of size 0" + # --- except that we specifically refuse to interpret numbers + # as the array size when passing arguments. + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -203,6 +203,11 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" +def is_zero(space, w_ob): + return ((space.isinstance_w(w_ob, space.w_int) or + space.isinstance_w(w_ob, space.w_long)) + and not space.is_true(w_ob)) + # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,8 +387,19 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - y = cast(p, 0) - assert (y == None) is False + +def test_cmp_pointer_with_0(): + p = new_pointer_type(new_primitive_type("int")) + x = cast(p, 0) + assert (x == 0) is True + assert (x != 0) is False + assert (0 == x) is True + assert (0 != x) is False + y = cast(p, 42) + assert (y == 0) is False + assert (y != 0) is True + assert (0 == y) is False + assert (0 != y) is True def test_invalid_indexing(): p = new_primitive_type("int") @@ -768,7 +779,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 != 0 + assert s.p4 == 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -781,11 +792,14 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - assert s.p4 + s.p4 = 0 + assert s.p4 == 0 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) + assert s.p4 == 0 + # + s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) - assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1003,10 +1017,11 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(cast(BVoidP, 0)) # NULL + res = f(0) # NULL + assert res == -42 + res = f(long(0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) - py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): From noreply at buildbot.pypy.org Fri Mar 8 15:23:43 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 15:23:43 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130308142343.20ADF1C39DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62234:3108a9e42aec Date: 2013-03-08 15:23 +0100 http://bitbucket.org/pypy/pypy/changeset/3108a9e42aec/ Log: merge heads diff --git a/lib_pypy/__init__.py b/lib_pypy/__init__.py --- a/lib_pypy/__init__.py +++ b/lib_pypy/__init__.py @@ -1,4 +1,4 @@ # This __init__.py shows up in PyPy's app-level standard library. # Let's try to prevent that confusion... if __name__ != 'lib_pypy': - raise ImportError, '__init__' + raise ImportError('__init__') diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -10,7 +10,7 @@ import operator try: - from thread import get_ident as _thread_ident + from threading import _get_ident as _thread_ident except ImportError: def _thread_ident(): return -1 @@ -97,7 +97,7 @@ def pop(self): if self.left is self.right and self.leftndx > self.rightndx: - raise IndexError, "pop from an empty deque" + raise IndexError("pop from an empty deque") x = self.right[self.rightndx] self.right[self.rightndx] = None self.length -= 1 @@ -118,7 +118,7 @@ def popleft(self): if self.left is self.right and self.leftndx > self.rightndx: - raise IndexError, "pop from an empty deque" + raise IndexError("pop from an empty deque") x = self.left[self.leftndx] self.left[self.leftndx] = None self.length -= 1 @@ -322,7 +322,7 @@ return type(self), (list(self), self.maxlen) def __hash__(self): - raise TypeError, "deque objects are unhashable" + raise TypeError("deque objects are unhashable") def __copy__(self): return self.__class__(self, self.maxlen) @@ -374,11 +374,11 @@ self.counter = len(deq) def giveup(): self.counter = 0 - raise RuntimeError, "deque mutated during iteration" + raise RuntimeError("deque mutated during iteration") self._gen = itergen(deq.state, giveup) def next(self): - res = self._gen.next() + res = next(self._gen) self.counter -= 1 return res diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py --- a/lib_pypy/_csv.py +++ b/lib_pypy/_csv.py @@ -225,7 +225,7 @@ self._parse_reset() while True: try: - line = self.input_iter.next() + line = next(self.input_iter) except StopIteration: # End of input OR exception if len(self.field) > 0: diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -3,9 +3,17 @@ This module contains functions that can read and write Python values in a binary format. The format is specific to Python, but independent of machine architecture issues (e.g., you can write a Python value to a file on a PC, transport the file to a Sun, and read it back there). Details of the format may change between Python versions. """ +# NOTE: This module is used in the Python3 interpreter, but also by +# the "sandboxed" process. It must work for Python2 as well. + import types from _codecs import utf_8_decode, utf_8_encode +try: + intern +except NameError: + from sys import intern + try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -49,7 +57,7 @@ if func: break else: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") func(self, x) def w_long64(self, x): @@ -72,7 +80,7 @@ def dump_none(self, x): self._write(TYPE_NONE) - dispatch[types.NoneType] = dump_none + dispatch[type(None)] = dump_none def dump_bool(self, x): if x: @@ -83,7 +91,7 @@ def dump_stopiter(self, x): if x is not StopIteration: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") self._write(TYPE_STOPITER) dispatch[type(StopIteration)] = dump_stopiter @@ -91,10 +99,11 @@ self._write(TYPE_ELLIPSIS) try: - dispatch[types.EllipsisType] = dump_ellipsis + dispatch[type(Ellipsis)] = dump_ellipsis except NameError: pass + # In Python3, this function is not used; see dump_long() below. def dump_int(self, x): y = x>>31 if y and y != -1: @@ -103,7 +112,7 @@ else: self._write(TYPE_INT) self.w_long(x) - dispatch[types.IntType] = dump_int + dispatch[int] = dump_int def dump_long(self, x): self._write(TYPE_LONG) @@ -118,27 +127,32 @@ self.w_long(len(digits) * sign) for d in digits: self.w_short(d) - dispatch[types.LongType] = dump_long + try: + long + except NameError: + dispatch[int] = dump_long + else: + dispatch[long] = dump_long def dump_float(self, x): write = self._write write(TYPE_FLOAT) - s = `x` + s = repr(x) write(chr(len(s))) write(s) - dispatch[types.FloatType] = dump_float + dispatch[float] = dump_float def dump_complex(self, x): write = self._write write(TYPE_COMPLEX) - s = `x.real` + s = repr(x.real) write(chr(len(s))) write(s) - s = `x.imag` + s = repr(x.imag) write(chr(len(s))) write(s) try: - dispatch[types.ComplexType] = dump_complex + dispatch[complex] = dump_complex except NameError: pass @@ -148,7 +162,7 @@ self._write(TYPE_STRING) self.w_long(len(x)) self._write(x) - dispatch[types.StringType] = dump_string + dispatch[bytes] = dump_string def dump_unicode(self, x): self._write(TYPE_UNICODE) @@ -156,21 +170,26 @@ s, len_s = utf_8_encode(x) self.w_long(len_s) self._write(s) - dispatch[types.UnicodeType] = dump_unicode + try: + unicode + except NameError: + dispatch[str] = dump_unicode + else: + dispatch[unicode] = dump_unicode def dump_tuple(self, x): self._write(TYPE_TUPLE) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.TupleType] = dump_tuple + dispatch[tuple] = dump_tuple def dump_list(self, x): self._write(TYPE_LIST) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.ListType] = dump_list + dispatch[list] = dump_list def dump_dict(self, x): self._write(TYPE_DICT) @@ -178,7 +197,7 @@ self.dump(key) self.dump(value) self._write(TYPE_NULL) - dispatch[types.DictionaryType] = dump_dict + dispatch[dict] = dump_dict def dump_code(self, x): self._write(TYPE_CODE) @@ -252,7 +271,7 @@ try: return self.dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) def r_short(self): lo = ord(self._read(1)) @@ -270,7 +289,7 @@ d = ord(s[3]) x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -280,14 +299,14 @@ b = ord(self._read(1)) c = ord(self._read(1)) d = ord(self._read(1)) - e = long(ord(self._read(1))) - f = long(ord(self._read(1))) - g = long(ord(self._read(1))) - h = long(ord(self._read(1))) + e = ord(self._read(1)) + f = ord(self._read(1)) + g = ord(self._read(1)) + h = ord(self._read(1)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x def load_null(self): @@ -324,10 +343,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = self.r_short() - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long @@ -459,7 +478,7 @@ self.bufpos += 4 x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -469,14 +488,14 @@ b = ord(_read1(self)) c = ord(_read1(self)) d = ord(_read1(self)) - e = long(ord(_read1(self))) - f = long(ord(_read1(self))) - g = long(ord(_read1(self))) - h = long(ord(_read1(self))) + e = ord(_read1(self)) + f = ord(_read1(self)) + g = ord(_read1(self)) + h = ord(_read1(self)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x _load_dispatch = {} @@ -498,7 +517,7 @@ self.bufpos += 1 return _load_dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) except IndexError: raise EOFError @@ -540,10 +559,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = _r_short(self) - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long diff --git a/lib_pypy/_md5.py b/lib_pypy/_md5.py --- a/lib_pypy/_md5.py +++ b/lib_pypy/_md5.py @@ -47,16 +47,16 @@ def _bytelist2long(list): "Transform a list of characters into a list of longs." - imax = len(list)/4 - hl = [0L] * imax + imax = len(list) // 4 + hl = [0] * imax j = 0 i = 0 while i < imax: - b0 = long(ord(list[j])) - b1 = (long(ord(list[j+1]))) << 8 - b2 = (long(ord(list[j+2]))) << 16 - b3 = (long(ord(list[j+3]))) << 24 + b0 = ord(list[j]) + b1 = ord(list[j+1]) << 8 + b2 = ord(list[j+2]) << 16 + b3 = ord(list[j+3]) << 24 hl[i] = b0 | b1 |b2 | b3 i = i+1 j = j+4 @@ -100,16 +100,16 @@ (now summed-up in one function). """ - res = 0L + res = 0 res = res + a + func(b, c, d) res = res + x res = res + ac - res = res & 0xffffffffL + res = res & 0xffffffff res = _rotateLeft(res, s) - res = res & 0xffffffffL + res = res & 0xffffffff res = res + b - return res & 0xffffffffL + return res & 0xffffffff class MD5Type: @@ -122,7 +122,7 @@ "Initialisation." # Initial message length in bits(!). - self.length = 0L + self.length = 0 self.count = [0, 0] # Initial empty message as a sequence of bytes (8 bit characters). @@ -136,15 +136,15 @@ def init(self): "Initialize the message-digest and set all fields to zero." - self.length = 0L + self.length = 0 self.count = [0, 0] self.input = [] # Load magic initialization constants. - self.A = 0x67452301L - self.B = 0xefcdab89L - self.C = 0x98badcfeL - self.D = 0x10325476L + self.A = 0x67452301 + self.B = 0xefcdab89 + self.C = 0x98badcfe + self.D = 0x10325476 def _transform(self, inp): @@ -161,90 +161,90 @@ S11, S12, S13, S14 = 7, 12, 17, 22 - a = XX(F, a, b, c, d, inp[ 0], S11, 0xD76AA478L) # 1 - d = XX(F, d, a, b, c, inp[ 1], S12, 0xE8C7B756L) # 2 - c = XX(F, c, d, a, b, inp[ 2], S13, 0x242070DBL) # 3 - b = XX(F, b, c, d, a, inp[ 3], S14, 0xC1BDCEEEL) # 4 - a = XX(F, a, b, c, d, inp[ 4], S11, 0xF57C0FAFL) # 5 - d = XX(F, d, a, b, c, inp[ 5], S12, 0x4787C62AL) # 6 - c = XX(F, c, d, a, b, inp[ 6], S13, 0xA8304613L) # 7 - b = XX(F, b, c, d, a, inp[ 7], S14, 0xFD469501L) # 8 - a = XX(F, a, b, c, d, inp[ 8], S11, 0x698098D8L) # 9 - d = XX(F, d, a, b, c, inp[ 9], S12, 0x8B44F7AFL) # 10 - c = XX(F, c, d, a, b, inp[10], S13, 0xFFFF5BB1L) # 11 - b = XX(F, b, c, d, a, inp[11], S14, 0x895CD7BEL) # 12 - a = XX(F, a, b, c, d, inp[12], S11, 0x6B901122L) # 13 - d = XX(F, d, a, b, c, inp[13], S12, 0xFD987193L) # 14 - c = XX(F, c, d, a, b, inp[14], S13, 0xA679438EL) # 15 - b = XX(F, b, c, d, a, inp[15], S14, 0x49B40821L) # 16 + a = XX(F, a, b, c, d, inp[ 0], S11, 0xD76AA478) # 1 + d = XX(F, d, a, b, c, inp[ 1], S12, 0xE8C7B756) # 2 + c = XX(F, c, d, a, b, inp[ 2], S13, 0x242070DB) # 3 + b = XX(F, b, c, d, a, inp[ 3], S14, 0xC1BDCEEE) # 4 + a = XX(F, a, b, c, d, inp[ 4], S11, 0xF57C0FAF) # 5 + d = XX(F, d, a, b, c, inp[ 5], S12, 0x4787C62A) # 6 + c = XX(F, c, d, a, b, inp[ 6], S13, 0xA8304613) # 7 + b = XX(F, b, c, d, a, inp[ 7], S14, 0xFD469501) # 8 + a = XX(F, a, b, c, d, inp[ 8], S11, 0x698098D8) # 9 + d = XX(F, d, a, b, c, inp[ 9], S12, 0x8B44F7AF) # 10 + c = XX(F, c, d, a, b, inp[10], S13, 0xFFFF5BB1) # 11 + b = XX(F, b, c, d, a, inp[11], S14, 0x895CD7BE) # 12 + a = XX(F, a, b, c, d, inp[12], S11, 0x6B901122) # 13 + d = XX(F, d, a, b, c, inp[13], S12, 0xFD987193) # 14 + c = XX(F, c, d, a, b, inp[14], S13, 0xA679438E) # 15 + b = XX(F, b, c, d, a, inp[15], S14, 0x49B40821) # 16 # Round 2. S21, S22, S23, S24 = 5, 9, 14, 20 - a = XX(G, a, b, c, d, inp[ 1], S21, 0xF61E2562L) # 17 - d = XX(G, d, a, b, c, inp[ 6], S22, 0xC040B340L) # 18 - c = XX(G, c, d, a, b, inp[11], S23, 0x265E5A51L) # 19 - b = XX(G, b, c, d, a, inp[ 0], S24, 0xE9B6C7AAL) # 20 - a = XX(G, a, b, c, d, inp[ 5], S21, 0xD62F105DL) # 21 - d = XX(G, d, a, b, c, inp[10], S22, 0x02441453L) # 22 - c = XX(G, c, d, a, b, inp[15], S23, 0xD8A1E681L) # 23 - b = XX(G, b, c, d, a, inp[ 4], S24, 0xE7D3FBC8L) # 24 - a = XX(G, a, b, c, d, inp[ 9], S21, 0x21E1CDE6L) # 25 - d = XX(G, d, a, b, c, inp[14], S22, 0xC33707D6L) # 26 - c = XX(G, c, d, a, b, inp[ 3], S23, 0xF4D50D87L) # 27 - b = XX(G, b, c, d, a, inp[ 8], S24, 0x455A14EDL) # 28 - a = XX(G, a, b, c, d, inp[13], S21, 0xA9E3E905L) # 29 - d = XX(G, d, a, b, c, inp[ 2], S22, 0xFCEFA3F8L) # 30 - c = XX(G, c, d, a, b, inp[ 7], S23, 0x676F02D9L) # 31 - b = XX(G, b, c, d, a, inp[12], S24, 0x8D2A4C8AL) # 32 + a = XX(G, a, b, c, d, inp[ 1], S21, 0xF61E2562) # 17 + d = XX(G, d, a, b, c, inp[ 6], S22, 0xC040B340) # 18 + c = XX(G, c, d, a, b, inp[11], S23, 0x265E5A51) # 19 + b = XX(G, b, c, d, a, inp[ 0], S24, 0xE9B6C7AA) # 20 + a = XX(G, a, b, c, d, inp[ 5], S21, 0xD62F105D) # 21 + d = XX(G, d, a, b, c, inp[10], S22, 0x02441453) # 22 + c = XX(G, c, d, a, b, inp[15], S23, 0xD8A1E681) # 23 + b = XX(G, b, c, d, a, inp[ 4], S24, 0xE7D3FBC8) # 24 + a = XX(G, a, b, c, d, inp[ 9], S21, 0x21E1CDE6) # 25 + d = XX(G, d, a, b, c, inp[14], S22, 0xC33707D6) # 26 + c = XX(G, c, d, a, b, inp[ 3], S23, 0xF4D50D87) # 27 + b = XX(G, b, c, d, a, inp[ 8], S24, 0x455A14ED) # 28 + a = XX(G, a, b, c, d, inp[13], S21, 0xA9E3E905) # 29 + d = XX(G, d, a, b, c, inp[ 2], S22, 0xFCEFA3F8) # 30 + c = XX(G, c, d, a, b, inp[ 7], S23, 0x676F02D9) # 31 + b = XX(G, b, c, d, a, inp[12], S24, 0x8D2A4C8A) # 32 # Round 3. S31, S32, S33, S34 = 4, 11, 16, 23 - a = XX(H, a, b, c, d, inp[ 5], S31, 0xFFFA3942L) # 33 - d = XX(H, d, a, b, c, inp[ 8], S32, 0x8771F681L) # 34 - c = XX(H, c, d, a, b, inp[11], S33, 0x6D9D6122L) # 35 - b = XX(H, b, c, d, a, inp[14], S34, 0xFDE5380CL) # 36 - a = XX(H, a, b, c, d, inp[ 1], S31, 0xA4BEEA44L) # 37 - d = XX(H, d, a, b, c, inp[ 4], S32, 0x4BDECFA9L) # 38 - c = XX(H, c, d, a, b, inp[ 7], S33, 0xF6BB4B60L) # 39 - b = XX(H, b, c, d, a, inp[10], S34, 0xBEBFBC70L) # 40 - a = XX(H, a, b, c, d, inp[13], S31, 0x289B7EC6L) # 41 - d = XX(H, d, a, b, c, inp[ 0], S32, 0xEAA127FAL) # 42 - c = XX(H, c, d, a, b, inp[ 3], S33, 0xD4EF3085L) # 43 - b = XX(H, b, c, d, a, inp[ 6], S34, 0x04881D05L) # 44 - a = XX(H, a, b, c, d, inp[ 9], S31, 0xD9D4D039L) # 45 - d = XX(H, d, a, b, c, inp[12], S32, 0xE6DB99E5L) # 46 - c = XX(H, c, d, a, b, inp[15], S33, 0x1FA27CF8L) # 47 - b = XX(H, b, c, d, a, inp[ 2], S34, 0xC4AC5665L) # 48 + a = XX(H, a, b, c, d, inp[ 5], S31, 0xFFFA3942) # 33 + d = XX(H, d, a, b, c, inp[ 8], S32, 0x8771F681) # 34 + c = XX(H, c, d, a, b, inp[11], S33, 0x6D9D6122) # 35 + b = XX(H, b, c, d, a, inp[14], S34, 0xFDE5380C) # 36 + a = XX(H, a, b, c, d, inp[ 1], S31, 0xA4BEEA44) # 37 + d = XX(H, d, a, b, c, inp[ 4], S32, 0x4BDECFA9) # 38 + c = XX(H, c, d, a, b, inp[ 7], S33, 0xF6BB4B60) # 39 + b = XX(H, b, c, d, a, inp[10], S34, 0xBEBFBC70) # 40 + a = XX(H, a, b, c, d, inp[13], S31, 0x289B7EC6) # 41 + d = XX(H, d, a, b, c, inp[ 0], S32, 0xEAA127FA) # 42 + c = XX(H, c, d, a, b, inp[ 3], S33, 0xD4EF3085) # 43 + b = XX(H, b, c, d, a, inp[ 6], S34, 0x04881D05) # 44 + a = XX(H, a, b, c, d, inp[ 9], S31, 0xD9D4D039) # 45 + d = XX(H, d, a, b, c, inp[12], S32, 0xE6DB99E5) # 46 + c = XX(H, c, d, a, b, inp[15], S33, 0x1FA27CF8) # 47 + b = XX(H, b, c, d, a, inp[ 2], S34, 0xC4AC5665) # 48 # Round 4. S41, S42, S43, S44 = 6, 10, 15, 21 - a = XX(I, a, b, c, d, inp[ 0], S41, 0xF4292244L) # 49 - d = XX(I, d, a, b, c, inp[ 7], S42, 0x432AFF97L) # 50 - c = XX(I, c, d, a, b, inp[14], S43, 0xAB9423A7L) # 51 - b = XX(I, b, c, d, a, inp[ 5], S44, 0xFC93A039L) # 52 - a = XX(I, a, b, c, d, inp[12], S41, 0x655B59C3L) # 53 - d = XX(I, d, a, b, c, inp[ 3], S42, 0x8F0CCC92L) # 54 - c = XX(I, c, d, a, b, inp[10], S43, 0xFFEFF47DL) # 55 - b = XX(I, b, c, d, a, inp[ 1], S44, 0x85845DD1L) # 56 - a = XX(I, a, b, c, d, inp[ 8], S41, 0x6FA87E4FL) # 57 - d = XX(I, d, a, b, c, inp[15], S42, 0xFE2CE6E0L) # 58 - c = XX(I, c, d, a, b, inp[ 6], S43, 0xA3014314L) # 59 - b = XX(I, b, c, d, a, inp[13], S44, 0x4E0811A1L) # 60 - a = XX(I, a, b, c, d, inp[ 4], S41, 0xF7537E82L) # 61 - d = XX(I, d, a, b, c, inp[11], S42, 0xBD3AF235L) # 62 - c = XX(I, c, d, a, b, inp[ 2], S43, 0x2AD7D2BBL) # 63 - b = XX(I, b, c, d, a, inp[ 9], S44, 0xEB86D391L) # 64 + a = XX(I, a, b, c, d, inp[ 0], S41, 0xF4292244) # 49 + d = XX(I, d, a, b, c, inp[ 7], S42, 0x432AFF97) # 50 + c = XX(I, c, d, a, b, inp[14], S43, 0xAB9423A7) # 51 + b = XX(I, b, c, d, a, inp[ 5], S44, 0xFC93A039) # 52 + a = XX(I, a, b, c, d, inp[12], S41, 0x655B59C3) # 53 + d = XX(I, d, a, b, c, inp[ 3], S42, 0x8F0CCC92) # 54 + c = XX(I, c, d, a, b, inp[10], S43, 0xFFEFF47D) # 55 + b = XX(I, b, c, d, a, inp[ 1], S44, 0x85845DD1) # 56 + a = XX(I, a, b, c, d, inp[ 8], S41, 0x6FA87E4F) # 57 + d = XX(I, d, a, b, c, inp[15], S42, 0xFE2CE6E0) # 58 + c = XX(I, c, d, a, b, inp[ 6], S43, 0xA3014314) # 59 + b = XX(I, b, c, d, a, inp[13], S44, 0x4E0811A1) # 60 + a = XX(I, a, b, c, d, inp[ 4], S41, 0xF7537E82) # 61 + d = XX(I, d, a, b, c, inp[11], S42, 0xBD3AF235) # 62 + c = XX(I, c, d, a, b, inp[ 2], S43, 0x2AD7D2BB) # 63 + b = XX(I, b, c, d, a, inp[ 9], S44, 0xEB86D391) # 64 - A = (A + a) & 0xffffffffL - B = (B + b) & 0xffffffffL - C = (C + c) & 0xffffffffL - D = (D + d) & 0xffffffffL + A = (A + a) & 0xffffffff + B = (B + b) & 0xffffffff + C = (C + c) & 0xffffffff + D = (D + d) & 0xffffffff self.A, self.B, self.C, self.D = A, B, C, D @@ -267,10 +267,10 @@ the hashed string. """ - leninBuf = long(len(inBuf)) + leninBuf = len(inBuf) # Compute number of bytes mod 64. - index = (self.count[0] >> 3) & 0x3FL + index = (self.count[0] >> 3) & 0x3F # Update number of bits. self.count[0] = self.count[0] + (leninBuf << 3) @@ -309,7 +309,7 @@ input = [] + self.input count = [] + self.count - index = (self.count[0] >> 3) & 0x3fL + index = (self.count[0] >> 3) & 0x3f if index < 56: padLen = 56 - index diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py --- a/lib_pypy/_pypy_wait.py +++ b/lib_pypy/_pypy_wait.py @@ -1,6 +1,6 @@ +from resource import _struct_rusage, struct_rusage from ctypes import CDLL, c_int, POINTER, byref from ctypes.util import find_library -from resource import _struct_rusage, struct_rusage __all__ = ["wait3", "wait4"] diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha.py --- a/lib_pypy/_sha.py +++ b/lib_pypy/_sha.py @@ -35,15 +35,15 @@ """ # After much testing, this algorithm was deemed to be the fastest. - s = '' + s = b'' pack = struct.pack while n > 0: - s = pack('>I', n & 0xffffffffL) + s + s = pack('>I', n & 0xffffffff) + s n = n >> 32 # Strip off leading zeros. for i in range(len(s)): - if s[i] <> '\000': + if s[i] != '\000': break else: # Only happens when n == 0. @@ -63,16 +63,16 @@ def _bytelist2longBigEndian(list): "Transform a list of characters into a list of longs." - imax = len(list)/4 - hl = [0L] * imax + imax = len(list) // 4 + hl = [0] * imax j = 0 i = 0 while i < imax: - b0 = long(ord(list[j])) << 24 - b1 = long(ord(list[j+1])) << 16 - b2 = long(ord(list[j+2])) << 8 - b3 = long(ord(list[j+3])) + b0 = ord(list[j]) << 24 + b1 = ord(list[j+1]) << 16 + b2 = ord(list[j+2]) << 8 + b3 = ord(list[j+3]) hl[i] = b0 | b1 | b2 | b3 i = i+1 j = j+4 @@ -108,10 +108,10 @@ # Constants to be used K = [ - 0x5A827999L, # ( 0 <= t <= 19) - 0x6ED9EBA1L, # (20 <= t <= 39) - 0x8F1BBCDCL, # (40 <= t <= 59) - 0xCA62C1D6L # (60 <= t <= 79) + 0x5A827999, # ( 0 <= t <= 19) + 0x6ED9EBA1, # (20 <= t <= 39) + 0x8F1BBCDC, # (40 <= t <= 59) + 0xCA62C1D6 # (60 <= t <= 79) ] class sha: @@ -124,7 +124,7 @@ "Initialisation." # Initial message length in bits(!). - self.length = 0L + self.length = 0 self.count = [0, 0] # Initial empty message as a sequence of bytes (8 bit characters). @@ -138,21 +138,21 @@ def init(self): "Initialize the message-digest and set all fields to zero." - self.length = 0L + self.length = 0 self.input = [] # Initial 160 bit message digest (5 times 32 bit). - self.H0 = 0x67452301L - self.H1 = 0xEFCDAB89L - self.H2 = 0x98BADCFEL - self.H3 = 0x10325476L - self.H4 = 0xC3D2E1F0L + self.H0 = 0x67452301 + self.H1 = 0xEFCDAB89 + self.H2 = 0x98BADCFE + self.H3 = 0x10325476 + self.H4 = 0xC3D2E1F0 def _transform(self, W): for t in range(16, 80): W.append(_rotateLeft( - W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1) & 0xffffffffL) + W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1) & 0xffffffff) A = self.H0 B = self.H1 @@ -166,49 +166,49 @@ TEMP = _rotateLeft(A, 5) + f[t/20] + E + W[t] + K[t/20] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff """ for t in range(0, 20): TEMP = _rotateLeft(A, 5) + ((B & C) | ((~ B) & D)) + E + W[t] + K[0] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff for t in range(20, 40): TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[1] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff for t in range(40, 60): TEMP = _rotateLeft(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff for t in range(60, 80): TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[3] E = D D = C - C = _rotateLeft(B, 30) & 0xffffffffL + C = _rotateLeft(B, 30) & 0xffffffff B = A - A = TEMP & 0xffffffffL + A = TEMP & 0xffffffff - self.H0 = (self.H0 + A) & 0xffffffffL - self.H1 = (self.H1 + B) & 0xffffffffL - self.H2 = (self.H2 + C) & 0xffffffffL - self.H3 = (self.H3 + D) & 0xffffffffL - self.H4 = (self.H4 + E) & 0xffffffffL + self.H0 = (self.H0 + A) & 0xffffffff + self.H1 = (self.H1 + B) & 0xffffffff + self.H2 = (self.H2 + C) & 0xffffffff + self.H3 = (self.H3 + D) & 0xffffffff + self.H4 = (self.H4 + E) & 0xffffffff # Down from here all methods follow the Python Standard Library @@ -230,10 +230,10 @@ to the hashed string. """ - leninBuf = long(len(inBuf)) + leninBuf = len(inBuf) # Compute number of bytes mod 64. - index = (self.count[1] >> 3) & 0x3FL + index = (self.count[1] >> 3) & 0x3F # Update number of bits. self.count[1] = self.count[1] + (leninBuf << 3) @@ -273,7 +273,7 @@ input = [] + self.input count = [] + self.count - index = (self.count[1] >> 3) & 0x3fL + index = (self.count[1] >> 3) & 0x3f if index < 56: padLen = 56 - index diff --git a/lib_pypy/_sha512.py b/lib_pypy/_sha512.py --- a/lib_pypy/_sha512.py +++ b/lib_pypy/_sha512.py @@ -10,7 +10,7 @@ def new_shaobject(): return { - 'digest': [0L]*8, + 'digest': [0]*8, 'count_lo': 0, 'count_hi': 0, 'data': [0]* SHA_BLOCKSIZE, diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1219,6 +1219,7 @@ val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_column_int64(self._statement, i) + val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_column_double(self._statement, i) elif typ == _lib.SQLITE_TEXT: @@ -1342,6 +1343,7 @@ val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_value_int64(params[i]) + val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_value_double(params[i]) elif typ == _lib.SQLITE_TEXT: diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -225,10 +225,7 @@ elif data == TRUE[1:]: val = True else: - try: - val = int(data) - except ValueError: - val = long(data) + val = int(data) self.append(val) dispatch[INT] = load_int diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -16,14 +16,20 @@ Thanks to Tim Peters for suggesting using it. """ +from __future__ import division import time as _time import math as _math +import struct as _struct + +def _cmp(x, y): + return 0 if x == y else 1 if x > y else -1 def _round(x): return _math.floor(x + 0.5) if x >= 0.0 else _math.ceil(x - 0.5) MINYEAR = 1 MAXYEAR = 9999 +_MINYEARFMT = 1900 # Utility functions, adapted from Python's Demo/classes/Dates.py, which # also assumes the current Gregorian calendar indefinitely extended in @@ -172,13 +178,14 @@ # Correctly substitute for %z and %Z escapes in strftime formats. def _wrap_strftime(object, format, timetuple): year = timetuple[0] - if year < 1900: - raise ValueError("year=%d is before 1900; the datetime strftime() " - "methods require year >= 1900" % year) - # Don't call _utcoffset() or tzname() unless actually needed. - freplace = None # the string to use for %f - zreplace = None # the string to use for %z - Zreplace = None # the string to use for %Z + if year < _MINYEARFMT: + raise ValueError("year=%d is before %d; the datetime strftime() " + "methods require year >= %d" % + (year, _MINYEARFMT, _MINYEARFMT)) + # Don't call utcoffset() or tzname() unless actually needed. + freplace = None # the string to use for %f + zreplace = None # the string to use for %z + Zreplace = None # the string to use for %Z # Scan format for %z and %Z escapes, replacing as needed. newformat = [] @@ -263,9 +270,9 @@ raise ValueError("tzinfo.%s() must return a whole number " "of minutes" % name) offset = minutes - if -1440 < offset < 1440: - return offset - raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) + if not -1440 < offset < 1440: + raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) + return offset def _check_int_field(value): if isinstance(value, int): @@ -571,7 +578,7 @@ def total_seconds(self): """Total seconds in the duration.""" return ((self.days * 86400 + self.seconds) * 10**6 + - self.microseconds) / 1e6 + self.microseconds) / 10**6 # Read-only field accessors @property @@ -641,12 +648,15 @@ __rmul__ = __mul__ + def _to_microseconds(self): + return ((self._days * (24*3600) + self._seconds) * 1000000 + + self._microseconds) + def __div__(self, other): - if isinstance(other, (int, long)): - usec = ((self._days * (24*3600L) + self._seconds) * 1000000 + - self._microseconds) - return timedelta(0, 0, usec // other) - return NotImplemented + if not isinstance(other, (int, long)): + return NotImplemented + usec = self._to_microseconds() + return timedelta(0, 0, usec // other) __floordiv__ = __div__ @@ -690,7 +700,7 @@ def _cmp(self, other): assert isinstance(other, timedelta) - return cmp(self._getstate(), other._getstate()) + return _cmp(self._getstate(), other._getstate()) def __hash__(self): return hash(self._getstate()) @@ -750,7 +760,8 @@ year, month, day (required, base 1) """ - if isinstance(year, str) and len(year) == 4: + if month is None and isinstance(year, bytes) and len(year) == 4 and \ + 1 <= ord(year[2]) <= 12: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -938,7 +949,7 @@ assert isinstance(other, date) y, m, d = self._year, self._month, self._day y2, m2, d2 = other._year, other._month, other._day - return cmp((y, m, d), (y2, m2, d2)) + return _cmp((y, m, d), (y2, m2, d2)) def __hash__(self): "Hash." @@ -1016,13 +1027,12 @@ def _getstate(self): yhi, ylo = divmod(self._year, 256) - return ("%c%c%c%c" % (yhi, ylo, self._month, self._day), ) + return (_struct.pack('4B', yhi, ylo, self._month, self._day),) def __setstate(self, string): - if len(string) != 4 or not (1 <= ord(string[2]) <= 12): - raise TypeError("not enough arguments") - self._month, self._day = ord(string[2]), ord(string[3]) - self._year = ord(string[0]) * 256 + ord(string[1]) + yhi, ylo, self._month, self._day = (ord(string[0]), ord(string[1]), + ord(string[2]), ord(string[3])) + self._year = yhi * 256 + ylo def __reduce__(self): return (self.__class__, self._getstate()) @@ -1140,7 +1150,7 @@ second, microsecond (default to zero) tzinfo (default to None) """ - if isinstance(hour, str): + if isinstance(hour, bytes) and len(hour) == 6 and ord(hour[0]) < 24: # Pickle support self = object.__new__(cls) self.__setstate(hour, minute or None) @@ -1235,21 +1245,21 @@ base_compare = myoff == otoff if base_compare: - return cmp((self._hour, self._minute, self._second, - self._microsecond), - (other._hour, other._minute, other._second, - other._microsecond)) + return _cmp((self._hour, self._minute, self._second, + self._microsecond), + (other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: raise TypeError("cannot compare naive and aware times") myhhmm = self._hour * 60 + self._minute - myoff othhmm = other._hour * 60 + other._minute - otoff - return cmp((myhhmm, self._second, self._microsecond), - (othhmm, other._second, other._microsecond)) + return _cmp((myhhmm, self._second, self._microsecond), + (othhmm, other._second, other._microsecond)) def __hash__(self): """Hash.""" tzoff = self._utcoffset() - if not tzoff: # zero or None + if not tzoff: # zero or None return hash(self._getstate()[0]) h, m = divmod(self.hour * 60 + self.minute - tzoff, 60) if 0 <= h < 24: @@ -1306,7 +1316,7 @@ """Format using strftime(). The date part of the timestamp passed to underlying strftime should not be used. """ - # The year must be >= 1900 else Python's strftime implementation + # The year must be >= _MINYEARFMT else Python's strftime implementation # can raise a bogus exception. timetuple = (1900, 1, 1, self._hour, self._minute, self._second, @@ -1389,29 +1399,27 @@ def __nonzero__(self): if self.second or self.microsecond: - return 1 + return True offset = self._utcoffset() or 0 - return self.hour * 60 + self.minute - offset != 0 + return self.hour * 60 + self.minute != offset # Pickle support. def _getstate(self): us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = ("%c" * 6) % (self._hour, self._minute, self._second, - us1, us2, us3) + basestate = _struct.pack('6B', self._hour, self._minute, self._second, + us1, us2, us3) if self._tzinfo is None: return (basestate,) else: return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - if len(string) != 6 or ord(string[0]) >= 24: - raise TypeError("an integer is required") - self._hour, self._minute, self._second = ord(string[0]), \ - ord(string[1]), ord(string[2]) - self._microsecond = (((ord(string[3]) << 8) | \ - ord(string[4])) << 8) | ord(string[5]) + self._hour, self._minute, self._second, us1, us2, us3 = ( + ord(string[0]), ord(string[1]), ord(string[2]), + ord(string[3]), ord(string[4]), ord(string[5])) + self._microsecond = (((us1 << 8) | us2) << 8) | us3 self._tzinfo = tzinfo def __reduce__(self): @@ -1433,7 +1441,8 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str) and len(year) == 10: + if isinstance(year, bytes) and len(year) == 10 and \ + 1 <= ord(year[2]) <= 12: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) @@ -1608,8 +1617,8 @@ year, month, day = _check_date_fields(year, month, day) hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - return datetime(year, month, day, hour, minute, second, - microsecond, tzinfo) + return datetime(year, month, day, hour, minute, second, microsecond, + tzinfo) def astimezone(self, tz): if not isinstance(tz, tzinfo): @@ -1655,10 +1664,9 @@ Optional argument sep specifies the separator between date and time, default 'T'. """ - s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, - sep) + - _format_time(self._hour, self._minute, self._second, - self._microsecond)) + s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + + _format_time(self._hour, self._minute, self._second, + self._microsecond)) off = self._utcoffset() if off is not None: if off < 0: @@ -1672,7 +1680,7 @@ def __repr__(self): """Convert to formal string, for repr().""" - L = [self._year, self._month, self._day, # These are never zero + L = [self._year, self._month, self._day, # These are never zero self._hour, self._minute, self._second, self._microsecond] if L[-1] == 0: del L[-1] @@ -1812,12 +1820,12 @@ base_compare = myoff == otoff if base_compare: - return cmp((self._year, self._month, self._day, - self._hour, self._minute, self._second, - self._microsecond), - (other._year, other._month, other._day, - other._hour, other._minute, other._second, - other._microsecond)) + return _cmp((self._year, self._month, self._day, + self._hour, self._minute, self._second, + self._microsecond), + (other._year, other._month, other._day, + other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: raise TypeError("cannot compare naive and aware datetimes") # XXX What follows could be done more efficiently... @@ -1883,20 +1891,22 @@ yhi, ylo = divmod(self._year, 256) us2, us3 = divmod(self._microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = ("%c" * 10) % (yhi, ylo, self._month, self._day, - self._hour, self._minute, self._second, - us1, us2, us3) + basestate = _struct.pack('10B', yhi, ylo, self._month, self._day, + self._hour, self._minute, self._second, + us1, us2, us3) if self._tzinfo is None: return (basestate,) else: return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - (self._month, self._day, self._hour, self._minute, - self._second) = (ord(string[2]), ord(string[3]), ord(string[4]), - ord(string[5]), ord(string[6])) - self._year = ord(string[0]) * 256 + ord(string[1]) - self._microsecond = (((ord(string[7]) << 8) | ord(string[8])) << 8) | ord(string[9]) + (yhi, ylo, self._month, self._day, self._hour, + self._minute, self._second, us1, us2, us3) = (ord(string[0]), + ord(string[1]), ord(string[2]), ord(string[3]), + ord(string[4]), ord(string[5]), ord(string[6]), + ord(string[7]), ord(string[8]), ord(string[9])) + self._year = yhi * 256 + ylo + self._microsecond = (((us1 << 8) | us2) << 8) | us3 self._tzinfo = tzinfo def __reduce__(self): @@ -1913,7 +1923,7 @@ # XXX This could be done more efficiently THURSDAY = 3 firstday = _ymd2ord(year, 1, 1) - firstweekday = (firstday + 6) % 7 # See weekday() above + firstweekday = (firstday + 6) % 7 # See weekday() above week1monday = firstday - firstweekday if firstweekday > THURSDAY: week1monday += 7 diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -111,7 +111,7 @@ # Internal stuff try: - from thread import _local + from threading import local as _local except ImportError: class _local(object): # assume no threads pass diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py --- a/lib_pypy/grp.py +++ b/lib_pypy/grp.py @@ -59,6 +59,12 @@ libc.getgrent.argtypes = [] libc.getgrent.restype = POINTER(GroupStruct) +libc.setgrent.argtypes = [] +libc.setgrent.restype = None + +libc.endgrent.argtypes = [] +libc.endgrent.restype = None + def _group_from_gstruct(res): i = 0 mem = [] diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py --- a/lib_pypy/stackless.py +++ b/lib_pypy/stackless.py @@ -93,7 +93,7 @@ try: - from thread import _local + from threading import local as _local except ImportError: class _local(object): # assume no threads pass @@ -433,16 +433,16 @@ def insert(self): if self.blocked: - raise RuntimeError, "You cannot run a blocked tasklet" + raise RuntimeError("You cannot run a blocked tasklet") if not self.alive: - raise RuntimeError, "You cannot run an unbound(dead) tasklet" + raise RuntimeError("You cannot run an unbound(dead) tasklet") _scheduler_append(self) def remove(self): if self.blocked: - raise RuntimeError, "You cannot remove a blocked tasklet." + raise RuntimeError("You cannot remove a blocked tasklet.") if self is getcurrent(): - raise RuntimeError, "The current tasklet cannot be removed." + raise RuntimeError("The current tasklet cannot be removed.") # not sure if I will revive this " Use t=tasklet().capture()" _scheduler_remove(self) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -4281,6 +4281,35 @@ """ self.optimize_loop(ops, expected) + def test_add_sub_ovf_second_operation_regular(self): + py.test.skip("Smalltalk would like this to pass") + # This situation occurs in Smalltalk because it uses 1-based indexing. + # The below code is equivalent to a loop over an array. + ops = """ + [i1] + i2 = int_sub(i1, 1) + escape(i2) + i3 = int_add_ovf(i1, 1) + guard_no_overflow() [] + jump(i3) + """ + preamble = """ + [i1] + i2 = int_sub(i1, 1) + escape(i2) + i3 = int_add_ovf(i1, 1) + guard_no_overflow() [] + jump(i3, i1) + """ + expected = """ + [i1, i2] + escape(i2) + i3 = int_add_ovf(i1, 1) + guard_no_overflow() [] + jump(i3, i1) + """ + self.optimize_loop(ops, expected, preamble) + def test_add_sub_ovf_virtual_unroll(self): ops = """ [p15] From noreply at buildbot.pypy.org Fri Mar 8 15:23:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 15:23:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: random ARM stuff + fix the test for llgraph Message-ID: <20130308142353.A4C831C39DF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62235:5b53a1c77730 Date: 2013-03-08 16:21 +0200 http://bitbucket.org/pypy/pypy/changeset/5b53a1c77730/ Log: random ARM stuff + fix the test for llgraph diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -352,7 +352,6 @@ self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): - XXX mc = ARMv7Builder() if self.cpu.supports_floats: vfp_regs = r.all_vfp_regs @@ -1286,6 +1285,8 @@ # malloc_slowpath in case we called malloc_slowpath, which returns the # new value of nursery_free_adr in r1 and the adr of the new object in # r0. + XXX # push gcmap + self.mc.BL(self.malloc_slowpath, c=c.HI) self.mc.gen_load_int(r.ip.value, nursery_free_adr) diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -3813,7 +3813,7 @@ def raising(): bridge = parse(""" [i1, i2] - guard_exception(ConstClass(xtp), descr=faildescr2) [i1, i2] + px = guard_exception(ConstClass(xtp), descr=faildescr2) [i1, i2] i3 = int_add(i1, i2) i4 = int_add(i1, i3) i5 = int_add(i1, i4) From noreply at buildbot.pypy.org Fri Mar 8 15:23:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 15:23:54 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the test Message-ID: <20130308142354.DBF741C39DF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62236:557de6bbfcc1 Date: 2013-03-08 16:22 +0200 http://bitbucket.org/pypy/pypy/changeset/557de6bbfcc1/ Log: fix the test diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -106,6 +106,8 @@ pass class BaseFakeCPU(object): + JITFRAME_FIXED_SIZE = 0 + def __init__(self): self.tracker = FakeTracker() self._cache = {} From noreply at buildbot.pypy.org Fri Mar 8 15:28:06 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 15:28:06 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: raise appropriate errors if calling FILE_WRITE prim with negative bounds Message-ID: <20130308142806.B5EA11C39DF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r148:0974cda2a4eb Date: 2013-03-08 15:23 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0974cda2a4eb/ Log: raise appropriate errors if calling FILE_WRITE prim with negative bounds diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -758,9 +758,9 @@ def func(interp, s_frame, w_rcvr, fd): try: os.close(fd) - return w_rcvr except OSError: raise PrimitiveFailedError() + return w_rcvr @expose_primitive(FILE_OPEN, unwrap_spec=[object, str, object]) def func(interp, s_frame, w_rcvr, filename, w_writeable_flag): @@ -769,17 +769,21 @@ filename, (os.O_RDWR | os.O_CREAT | os.O_TRUNC) if w_writeable_flag is interp.space.w_true else os.O_RDONLY ) - return interp.space.wrap_int(fd) except OSError: raise PrimitiveFailedError() + return interp.space.wrap_int(fd) @expose_primitive(FILE_WRITE, unwrap_spec=[object, int, str, int, int]) def func(interp, s_frame, w_rcvr, fd, src, start, count): + start = start - 1 + end = start + count + if end < 0 or start < 0: + raise PrimitiveFailedError() try: - os.write(fd, src[start - 1:start + count - 1]) - return w_rcvr + os.write(fd, src[start:end]) except OSError: raise PrimitiveFailedError() + return w_rcvr @expose_primitive(DIRECTORY_DELIMITOR, unwrap_spec=[object]) def func(interp, s_frame, _): diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -487,6 +487,18 @@ finally: monkeypatch.undo() +def test_file_write_errors(monkeypatch): + with py.test.raises(PrimitiveFailedError): + w_c = prim( + primitives.FILE_WRITE, + [1, space.wrap_int(42), space.wrap_string("hello"), space.wrap_int(-1), space.wrap_int(3)] + ) + with py.test.raises(PrimitiveFailedError): + w_c = prim( + primitives.FILE_WRITE, + [1, space.wrap_int(42), space.wrap_string("hello"), space.wrap_int(2), space.wrap_int(-1)] + ) + def test_directory_delimitor(): import os.path w_c = prim(primitives.DIRECTORY_DELIMITOR, [1]) From noreply at buildbot.pypy.org Fri Mar 8 15:28:07 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 15:28:07 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fix translation Message-ID: <20130308142807.EF2391C39DF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r149:097e9933d921 Date: 2013-03-08 15:26 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/097e9933d921/ Log: fix translation diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -764,11 +764,12 @@ @expose_primitive(FILE_OPEN, unwrap_spec=[object, str, object]) def func(interp, s_frame, w_rcvr, filename, w_writeable_flag): + if w_writeable_flag is interp.space.w_true: + mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC + else: + mode = os.O_RDONLY try: - fd = os.open( - filename, - (os.O_RDWR | os.O_CREAT | os.O_TRUNC) if w_writeable_flag is interp.space.w_true else os.O_RDONLY - ) + fd = os.open(filename, mode, 0666) except OSError: raise PrimitiveFailedError() return interp.space.wrap_int(fd) From noreply at buildbot.pypy.org Fri Mar 8 15:28:09 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 15:28:09 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: update mini.image, to include Preferences>>logDebuggerStackToFile to return true, so we get a SqueakDebug.log Message-ID: <20130308142809.65A821C39DF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r150:dc390b7d8345 Date: 2013-03-08 15:27 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/dc390b7d8345/ Log: update mini.image, to include Preferences>>logDebuggerStackToFile to return true, so we get a SqueakDebug.log diff --git a/images/mini.image b/images/mini.image index ef63740cadf1c61bd59bdf34a7ff21a801cc727d..4e0739b0aa769798ae904fee0eff0b0eac8c8368 GIT binary patch [cut] From noreply at buildbot.pypy.org Fri Mar 8 17:12:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:30 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix test_continuelet Message-ID: <20130308161230.958F51C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62237:27c0ece2e24f Date: 2013-03-08 17:08 +0200 http://bitbucket.org/pypy/pypy/changeset/27c0ece2e24f/ Log: fix test_continuelet diff --git a/rpython/rlib/_stacklet_n_a.py b/rpython/rlib/_stacklet_n_a.py --- a/rpython/rlib/_stacklet_n_a.py +++ b/rpython/rlib/_stacklet_n_a.py @@ -14,8 +14,8 @@ return h new._annspecialcase_ = 'specialize:arg(1)' - def switch(thrd, h): - h = _c.switch(thrd._thrd, h) + def switch(h): + h = _c.switch(h) if not h: raise MemoryError return h From noreply at buildbot.pypy.org Fri Mar 8 17:12:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix codewriter tests Message-ID: <20130308161231.CEC861C39DF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62238:860d24d10cc7 Date: 2013-03-08 17:11 +0200 http://bitbucket.org/pypy/pypy/changeset/860d24d10cc7/ Log: fix codewriter tests diff --git a/rpython/jit/codewriter/test/test_call.py b/rpython/jit/codewriter/test/test_call.py --- a/rpython/jit/codewriter/test/test_call.py +++ b/rpython/jit/codewriter/test/test_call.py @@ -223,7 +223,7 @@ from rpython.jit.backend.llgraph.runner import LLGraphCPU from rpython.translator.platform import CompilationError try: - from rpython.rlib._rffi_stacklet import switch, thread_handle, handle + from rpython.rlib._rffi_stacklet import switch, handle except CompilationError as e: if "Unsupported platform!" in e.out: py.test.skip("Unsupported platform!") @@ -231,7 +231,7 @@ raise e @jit.dont_look_inside def f(): - switch(rffi.cast(thread_handle, 0), rffi.cast(handle, 0)) + switch(rffi.cast(handle, 0)) rtyper = support.annotate(f, []) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) diff --git a/rpython/jit/codewriter/test/test_codewriter.py b/rpython/jit/codewriter/test/test_codewriter.py --- a/rpython/jit/codewriter/test/test_codewriter.py +++ b/rpython/jit/codewriter/test/test_codewriter.py @@ -34,6 +34,10 @@ class FakeCPU: def __init__(self, rtyper): self.rtyper = rtyper + + class tracker: + pass + calldescrof = FakeCallDescr fielddescrof = FakeFieldDescr sizeof = FakeSizeDescr diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py --- a/rpython/jit/codewriter/test/test_flatten.py +++ b/rpython/jit/codewriter/test/test_flatten.py @@ -47,6 +47,9 @@ return c_func, lltype.Signed class FakeCPU: + class tracker: + pass + def __init__(self, rtyper): rtyper._builtin_func_for_spec_cache = FakeDict() self.rtyper = rtyper diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -33,6 +33,9 @@ instance_reprs = {} class FakeCPU: + class tracker: + pass + rtyper = FakeRTyper() def calldescrof(self, FUNC, ARGS, RESULT): return ('calldescr', FUNC, ARGS, RESULT) From noreply at buildbot.pypy.org Fri Mar 8 17:12:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: we want to reset jf_guard_exc on the new frame, not on the old one Message-ID: <20130308161233.13E6F1C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62239:b80e318576e5 Date: 2013-03-08 17:35 +0200 http://bitbucket.org/pypy/pypy/changeset/b80e318576e5/ Log: we want to reset jf_guard_exc on the new frame, not on the old one diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -160,9 +160,9 @@ self._store_and_reset_exception(mc, None, ebx, ecx) mc.CALL(imm(self.cpu.realloc_frame)) + mc.MOV_rr(ebp.value, eax.value) self._restore_exception(mc, None, ebx, ecx) mc.ADD_ri(esp.value, (align - 1) * WORD) - mc.MOV_rr(ebp.value, eax.value) mc.MOV_bi(extra_ofs, 0) From noreply at buildbot.pypy.org Fri Mar 8 17:12:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a corresponding fix Message-ID: <20130308161234.3F4CA1C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62240:23b4373b308f Date: 2013-03-08 17:37 +0200 http://bitbucket.org/pypy/pypy/changeset/23b4373b308f/ Log: a corresponding fix diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -3861,3 +3861,4 @@ frame = self.cpu.execute_token(looptoken, 1, 2, 3) descr = self.cpu.get_latest_descr(frame) assert descr.identifier == 42 + assert not self.cpu.grab_exc_value(frame) From noreply at buildbot.pypy.org Fri Mar 8 17:12:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:35 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix test_compile Message-ID: <20130308161235.6A4351C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62241:0a95a0180cb5 Date: 2013-03-08 17:38 +0200 http://bitbucket.org/pypy/pypy/changeset/0a95a0180cb5/ Log: fix test_compile diff --git a/rpython/jit/metainterp/test/test_compile.py b/rpython/jit/metainterp/test/test_compile.py --- a/rpython/jit/metainterp/test/test_compile.py +++ b/rpython/jit/metainterp/test/test_compile.py @@ -11,6 +11,9 @@ from rpython.jit.metainterp.optimizeopt import ALL_OPTS_DICT class FakeCPU(object): + class tracker: + pass + ts = typesystem.llhelper def __init__(self): self.seen = [] @@ -77,8 +80,8 @@ metainterp.history = History() metainterp.history.operations = loop.operations[:-1] metainterp.history.inputargs = loop.inputargs[:] - cpu._all_size_descrs_with_vtable = ( - LLtypeMixin.cpu._all_size_descrs_with_vtable) + cpu.tracker._all_size_descrs_with_vtable = ( + LLtypeMixin.cpu.tracker._all_size_descrs_with_vtable) # greenkey = 'faked' target_token = compile_loop(metainterp, greenkey, 0, From noreply at buildbot.pypy.org Fri Mar 8 17:12:36 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:36 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: I think this is what we want wrt keepalives Message-ID: <20130308161236.A4A711C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62242:f5b6f4d291a6 Date: 2013-03-08 17:55 +0200 http://bitbucket.org/pypy/pypy/changeset/f5b6f4d291a6/ Log: I think this is what we want wrt keepalives 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 @@ -22,7 +22,6 @@ # We need to clone the list of operations because the # front-end will mutate them under our feet again. We also # need to make sure things get freed. - self.alldescrs = [] def mapping(box, _cache={}): if isinstance(box, Const) or box is None: return box @@ -36,9 +35,10 @@ self.operations = [] for op in operations: if op.getdescr() is not None: - # XXX is this hack needed any more? - self.alldescrs.append(op.getdescr()) - newdescr = WeakrefDescr(op.getdescr()) + if op.is_guard(): + newdescr = op.getdescr() + else: + newdescr = WeakrefDescr(op.getdescr()) else: newdescr = None newop = op.copy_and_change(op.getopnum(), @@ -939,7 +939,7 @@ def _getdescr(op): d = op.getdescr() - if d is not None: + if d is not None and isinstance(d, WeakrefDescr): d = d.realdescrref() assert d is not None, "the descr disappeared: %r" % (op,) return d From noreply at buildbot.pypy.org Fri Mar 8 17:12:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:37 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: one more tracker Message-ID: <20130308161237.C8BFC1C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62243:3bac9266084e Date: 2013-03-08 17:56 +0200 http://bitbucket.org/pypy/pypy/changeset/3bac9266084e/ Log: one more tracker diff --git a/rpython/jit/metainterp/test/test_warmspot.py b/rpython/jit/metainterp/test/test_warmspot.py --- a/rpython/jit/metainterp/test/test_warmspot.py +++ b/rpython/jit/metainterp/test/test_warmspot.py @@ -611,6 +611,9 @@ translate_support_code = False stats = "stats" + class tracker: + pass + def get_latest_descr(self, deadframe): assert isinstance(deadframe, FakeDeadFrame) return self.get_fail_descr_from_number(deadframe._no) From noreply at buildbot.pypy.org Fri Mar 8 17:12:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Mar 2013 17:12:39 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix test_oparser Message-ID: <20130308161239.052F41C39D3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62244:bae92e3bf1c1 Date: 2013-03-08 17:57 +0200 http://bitbucket.org/pypy/pypy/changeset/bae92e3bf1c1/ Log: fix test_oparser diff --git a/rpython/jit/tool/oparser_model.py b/rpython/jit/tool/oparser_model.py --- a/rpython/jit/tool/oparser_model.py +++ b/rpython/jit/tool/oparser_model.py @@ -48,9 +48,11 @@ class BasicFailDescr(object): I_am_a_descr = True + final_descr = False class BasicFinalDescr(object): I_am_a_descr = True + final_descr = True class Box(object): _counter = 0 From noreply at buildbot.pypy.org Fri Mar 8 17:15:02 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 8 Mar 2013 17:15:02 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, lwassermann): added conditional printing of results and additional time-measuring of perform Message-ID: <20130308161502.454A41C39DF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r151:b4e0907d6045 Date: 2013-03-08 15:34 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/b4e0907d6045/ Log: (cfbolz, lwassermann): added conditional printing of results and additional time-measuring of perform diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -1,4 +1,4 @@ -import sys +import sys, time import os from rpython.rlib.streamio import open_file_as_stream @@ -10,14 +10,17 @@ def _run_benchmark(interp, number, benchmark): w_object = model.W_SmallInteger(number) + t1 = time.time() try: w_result = interp.perform(w_object, benchmark) except interpreter.ReturnFromTopLevel, e: w_result = e.object + t2 = time.time() if w_result: - assert isinstance(w_result, model.W_BytesObject) - print '\n' - print w_result.as_string() + if isinstance(w_result, model.W_BytesObject): + print '\n' + print w_result.as_string() + print "took %s seconds" % (t2 - t1) return 0 return -1 From noreply at buildbot.pypy.org Fri Mar 8 17:15:03 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 8 Mar 2013 17:15:03 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: created a caching shadow specialy for arrays which seldom change, like the special messages array Message-ID: <20130308161503.77C401C39DF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r152:ec80277220dc Date: 2013-03-08 15:35 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ec80277220dc/ Log: created a caching shadow specialy for arrays which seldom change, like the special messages array diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -1,3 +1,4 @@ +from rpython.rlib.jit import elidable # ___________________________________________________________________________ # Slot Names @@ -149,7 +150,7 @@ 'at:put:', 'size', 'next', 'nextPut:', 'atEnd', '==', 'class', 'blockCopy:', 'value', 'value:', 'do:', 'new', 'new:', 'x', 'y'] - + at elidable def find_selectorindex(selector): return SPECIAL_SELECTORS.index(selector) * 2 find_selectorindex._annspecialcase_ = "specialize:memo" diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -365,6 +365,10 @@ from spyvm.shadow import MethodDictionaryShadow return self.as_special_get_shadow(space, MethodDictionaryShadow) + def as_cached_array_get_shadow(self, space): + from spyvm.shadow import CachedArrayShadow + return self.as_special_get_shadow(space, CachedArrayShadow) + def become(self, w_other): if not isinstance(w_other, W_PointersObject): return False diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -149,6 +149,7 @@ self.w_two = model.W_SmallInteger(2) w_special_selectors = model.W_PointersObject( self.classtable['w_Array'], len(constants.SPECIAL_SELECTORS) * 2) + w_special_selectors.as_cached_array_get_shadow(self) self.w_special_selectors = w_special_selectors self.objtable = {} diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -892,3 +892,28 @@ s_new = MethodContextShadow.make_context( space, self, receiver, arguments, sender) return s_new + +class CachedArrayShadow(AbstractCachingShadow): + _attr_ = ['version'] + + def __init__(self, space, w_self): + AbstractCachingShadow.__init__(self, space, w_self) + self.version = 0 + + def fetch(self, n0): + jit.promote(self) + version = self.version + jit.promote(version) + return self.safe_fetch(n0, version) + + @jit.elidable + def safe_fetch(self, n0, version): + assert version is self.version + return self._w_self._fetch(n0) + + def store(self, n0, w_value): + self.version = self.version + 1 + return self._w_self._store(n0, w_value) + + def update_shadow(self): + self.version = self.version + 1 \ No newline at end of file diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -58,7 +58,7 @@ image = create_testimage(space) interp = interpreter.Interpreter(space, image) - w_selector = interp.perform(space.wrap_string('loopTest'), "asSymbol") + w_selector = interp.perform(space.wrap_string('loopTest3'), "asSymbol") assert isinstance(w_selector, model.W_BytesObject) def interp_w(): interp.perform(model.W_SmallInteger(1000), w_selector) diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -44,3 +44,14 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes + +Optimizations: +use integer tagging primitives to get more compact code: + def wrap_int(self, val): + from rpython.rlib import rerased + try: + return model.W_SmallInteger(rerased.erase_int(val)) + except OverflowError: + raise WrappingError("integer too large to fit into a tagged pointer") + +make classes \ No newline at end of file From noreply at buildbot.pypy.org Fri Mar 8 17:15:04 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 8 Mar 2013 17:15:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: renamed CachedArrayShadow, added test, changed version field from int to Version-object Message-ID: <20130308161504.89DD51C39DF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r153:ff4a899fcfd9 Date: 2013-03-08 17:00 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ff4a899fcfd9/ Log: renamed CachedArrayShadow, added test, changed version field from int to Version-object moved adding a CachedObjectShadow to special selectors array from now on, only objects of varsized classes without instance variables can be special selectors array (e.g. instances of Array) diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -150,7 +150,7 @@ 'at:put:', 'size', 'next', 'nextPut:', 'atEnd', '==', 'class', 'blockCopy:', 'value', 'value:', 'do:', 'new', 'new:', 'x', 'y'] - at elidable + def find_selectorindex(selector): return SPECIAL_SELECTORS.index(selector) * 2 find_selectorindex._annspecialcase_ = "specialize:memo" diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -365,9 +365,9 @@ from spyvm.shadow import MethodDictionaryShadow return self.as_special_get_shadow(space, MethodDictionaryShadow) - def as_cached_array_get_shadow(self, space): - from spyvm.shadow import CachedArrayShadow - return self.as_special_get_shadow(space, CachedArrayShadow) + def as_cached_object_get_shadow(self, space): + from spyvm.shadow import CachedObjectShadow + return self.as_special_get_shadow(space, CachedObjectShadow) def become(self, w_other): if not isinstance(w_other, W_PointersObject): diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -149,7 +149,6 @@ self.w_two = model.W_SmallInteger(2) w_special_selectors = model.W_PointersObject( self.classtable['w_Array'], len(constants.SPECIAL_SELECTORS) * 2) - w_special_selectors.as_cached_array_get_shadow(self) self.w_special_selectors = w_special_selectors self.objtable = {} @@ -163,7 +162,8 @@ @specialize.arg(1) def get_special_selector(self, selector): i0 = constants.find_selectorindex(selector) - return self.w_special_selectors.at0(self, i0) + self.w_special_selectors.as_cached_object_get_shadow(self) + return self.w_special_selectors.fetch(self, i0) # methods for wrapping and unwrapping stuff diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -893,12 +893,15 @@ space, self, receiver, arguments, sender) return s_new -class CachedArrayShadow(AbstractCachingShadow): - _attr_ = ['version'] +class Version: + pass + +class CachedObjectShadow(AbstractCachingShadow): + _immutable_fields_ = ['version?'] def __init__(self, space, w_self): AbstractCachingShadow.__init__(self, space, w_self) - self.version = 0 + self.version = Version() def fetch(self, n0): jit.promote(self) @@ -912,8 +915,8 @@ return self._w_self._fetch(n0) def store(self, n0, w_value): - self.version = self.version + 1 + self.version = Version() return self._w_self._store(n0, w_value) def update_shadow(self): - self.version = self.version + 1 \ No newline at end of file + self.version = Version() \ No newline at end of file diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -491,6 +491,9 @@ self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" + else: + #XXX invalidate shadow here + pass return self.w_object def fillin_w_object(self): diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -207,3 +207,13 @@ shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abx" + +def test_cached_object_shadow(): + w_o = space.wrap_list([0, 1, 2, 3, 4, 5, 6, 7]) + s_o = w_o.as_cached_object_get_shadow(space) + version = s_o.version + for i in range(w_o.size()): + assert w_o.at0(space, i) == i + w_o.atput0(space, 0, 8) + assert version is not s_o.version + assert w_o.at0(space, 0) == 8 \ No newline at end of file diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -54,4 +54,8 @@ except OverflowError: raise WrappingError("integer too large to fit into a tagged pointer") -make classes \ No newline at end of file +make classes + + +Unclarities: +[ ] should image loading invalidate the shadows of the precreated objects? \ No newline at end of file From noreply at buildbot.pypy.org Fri Mar 8 17:15:06 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 8 Mar 2013 17:15:06 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merged Message-ID: <20130308161506.007D61C39DF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r154:9e0d98ab4de6 Date: 2013-03-08 17:12 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/9e0d98ab4de6/ Log: merged diff --git a/images/mini.image b/images/mini.image index ef63740cadf1c61bd59bdf34a7ff21a801cc727d..4e0739b0aa769798ae904fee0eff0b0eac8c8368 GIT binary patch [cut] diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -70,6 +70,9 @@ s_new_context.mark_returned() s_new_context = s_sender s_new_context.push(nlr.value) + except ProcessSwitch, p: + self.remaining_stack_depth = self.max_stack_depth + s_new_context = p.s_new_context def c_loop(self, s_context): # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) @@ -146,11 +149,17 @@ class StackOverflow(Exception): def __init__(self, s_top_context): self.s_context = s_top_context + class Return(Exception): def __init__(self, object, s_context): self.value = object self.s_target_context = s_context +class ProcessSwitch(Exception): + def __init__(self, s_context): + self.s_new_context = s_context + + def make_call_primitive_bytecode(primitive, selector, argcount): def callPrimitive(self, interp, current_bytecode): # WARNING: this is used for bytecodes for which it is safe to diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -1,3 +1,4 @@ +import os import inspect import math import operator @@ -753,10 +754,40 @@ DIRECTORY_LOOKUP = 162 DIRECTORY_DELTE = 163 + at expose_primitive(FILE_CLOSE, unwrap_spec=[object, int]) +def func(interp, s_frame, w_rcvr, fd): + try: + os.close(fd) + except OSError: + raise PrimitiveFailedError() + return w_rcvr + + at expose_primitive(FILE_OPEN, unwrap_spec=[object, str, object]) +def func(interp, s_frame, w_rcvr, filename, w_writeable_flag): + if w_writeable_flag is interp.space.w_true: + mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC + else: + mode = os.O_RDONLY + try: + fd = os.open(filename, mode, 0666) + except OSError: + raise PrimitiveFailedError() + return interp.space.wrap_int(fd) + + at expose_primitive(FILE_WRITE, unwrap_spec=[object, int, str, int, int]) +def func(interp, s_frame, w_rcvr, fd, src, start, count): + start = start - 1 + end = start + count + if end < 0 or start < 0: + raise PrimitiveFailedError() + try: + os.write(fd, src[start:end]) + except OSError: + raise PrimitiveFailedError() + return w_rcvr @expose_primitive(DIRECTORY_DELIMITOR, unwrap_spec=[object]) def func(interp, s_frame, _): - import os.path return interp.space.wrap_char(os.path.sep) diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -47,9 +47,9 @@ def test_read_header(): reader = open_miniimage(space) reader.read_header() - assert reader.endofmemory == 0x93174 - assert reader.oldbaseaddress == 0x6649000 - assert reader.specialobjectspointer == 0x6668380 + assert reader.endofmemory == 655196 + assert reader.oldbaseaddress == -1220960256 + assert reader.specialobjectspointer == -1220832384 def test_read_all_header(): reader = open_miniimage(space) diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -1,4 +1,5 @@ import py +import os import math from spyvm.primitives import prim_table, PrimitiveFailedError from spyvm import model, shadow, interpreter @@ -32,7 +33,9 @@ if isinstance(x, str): return space.wrap_string(x) if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError - + +IMAGENAME = "anImage.image" + def mock(stack, context = None): mapped_stack = [wrap(x) for x in stack] if context is None: @@ -41,7 +44,7 @@ frame = context for i in range(len(stack)): frame.as_context_get_shadow(space).push(stack[i]) - interp = interpreter.Interpreter(space) + interp = interpreter.Interpreter(space, image_name=IMAGENAME) return (interp, frame, len(stack)) def prim(code, stack, context = None): @@ -428,7 +431,7 @@ def test_image_name(): w_v = prim(primitives.IMAGE_NAME, [2]) - assert w_v.bytes == [] + assert w_v.bytes == list(IMAGENAME) def test_clone(): w_obj = mockclass(space, 1, varsized=True).as_class_get_shadow(space).new(1) @@ -438,12 +441,69 @@ w_obj.atput0(space, 0, space.wrap_int(2)) assert space.unwrap_int(w_v.at0(space, 0)) == 1 +def test_file_open_write(monkeypatch): + def open_write(filename, mode): + assert filename == "nonexistant" + assert mode == os.O_RDWR | os.O_CREAT | os.O_TRUNC + return 42 + monkeypatch.setattr(os, "open", open_write) + try: + w_c = prim(primitives.FILE_OPEN, [1, space.wrap_string("nonexistant"), space.w_true]) + finally: + monkeypatch.undo() + assert space.unwrap_int(w_c) == 42 + +def test_file_open_read(monkeypatch): + def open_read(filename, mode): + assert filename == "file" + assert mode == os.O_RDONLY + return 42 + monkeypatch.setattr(os, "open", open_read) + try: + w_c = prim(primitives.FILE_OPEN, [1, space.wrap_string("file"), space.w_false]) + finally: + monkeypatch.undo() + assert space.unwrap_int(w_c) == 42 + +def test_file_close(monkeypatch): + def close(fd): + assert fd == 42 + monkeypatch.setattr(os, "close", close) + try: + w_c = prim(primitives.FILE_CLOSE, [1, space.wrap_int(42)]) + finally: + monkeypatch.undo() + +def test_file_write(monkeypatch): + def write(fd, string): + assert fd == 42 + assert string == "ell" + monkeypatch.setattr(os, "write", write) + try: + w_c = prim( + primitives.FILE_WRITE, + [1, space.wrap_int(42), space.wrap_string("hello"), space.wrap_int(2), space.wrap_int(3)] + ) + finally: + monkeypatch.undo() + +def test_file_write_errors(monkeypatch): + with py.test.raises(PrimitiveFailedError): + w_c = prim( + primitives.FILE_WRITE, + [1, space.wrap_int(42), space.wrap_string("hello"), space.wrap_int(-1), space.wrap_int(3)] + ) + with py.test.raises(PrimitiveFailedError): + w_c = prim( + primitives.FILE_WRITE, + [1, space.wrap_int(42), space.wrap_string("hello"), space.wrap_int(2), space.wrap_int(-1)] + ) + def test_directory_delimitor(): import os.path w_c = prim(primitives.DIRECTORY_DELIMITOR, [1]) assert space.unwrap_char(w_c) == os.path.sep - def test_primitive_closure_copyClosure(): from test_interpreter import new_frame w_frame, s_frame = new_frame("", diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py --- a/spyvm/test/test_wrapper.py +++ b/spyvm/test/test_wrapper.py @@ -1,11 +1,14 @@ import py -from spyvm import wrapper -from spyvm import model +from spyvm import wrapper, model, interpreter, objspace from spyvm.error import WrapperException, FatalError -from spyvm import objspace + +from spyvm.test.test_interpreter import new_frame as new_frame_tuple space = objspace.ObjSpace() +def new_frame(): + return new_frame_tuple("")[0] + def test_simpleread(): w_o = model.W_PointersObject(None, 2) w = wrapper.Wrapper(space, w_o) @@ -143,18 +146,20 @@ assert process.my_list() is space.w_nil def test_suspend_active(self): - process, old_process = self.make_processes(4, 2, space.w_false) - old_process.suspend(space.w_true) + suspended_context = new_frame() + process, old_process = self.make_processes(4, 2, suspended_context) + current_context = new_frame() + with py.test.raises(interpreter.ProcessSwitch): + old_process.suspend(current_context) process_list = wrapper.scheduler(space).get_process_list(old_process.priority()) assert process_list.first_link() is process_list.last_link() assert process_list.first_link() is space.w_nil assert old_process.my_list() is space.w_nil + assert old_process.suspended_context() is current_context assert wrapper.scheduler(space).active_process() is process._w_self - def new_process_consistency(self, process, old_process, w_active_context, - old_active_context, new_active_context): + def new_process_consistency(self, process, old_process, w_active_context): scheduler = wrapper.scheduler(space) - assert w_active_context is new_active_context assert scheduler.active_process() is process._w_self priority_list = wrapper.scheduler(space).get_process_list(process.priority()) assert priority_list.first_link() is priority_list.last_link() @@ -180,23 +185,29 @@ def test_activate(self): - process, old_process = self.make_processes(4, 2, space.w_false) - w_frame = process.activate(space.w_true) - self.new_process_consistency(process, old_process, w_frame, - space.w_true, space.w_false) + sleepingcontext = new_frame() + process, old_process = self.make_processes(4, 2, sleepingcontext) + try: + process.activate() + except interpreter.ProcessSwitch, e: + w_frame = e.s_new_context._w_self + self.new_process_consistency(process, old_process, w_frame) def test_resume(self): - process, old_process = self.make_processes(4, 2, space.w_false) - w_frame = process.resume(space.w_true) - self.new_process_consistency(process, old_process, w_frame, - space.w_true, space.w_false) - self.old_process_consistency(old_process, space.w_true) + sleepingcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, sleepingcontext) + try: + process.resume(currentcontext) + except interpreter.ProcessSwitch, e: + w_frame = e.s_new_context._w_self + self.new_process_consistency(process, old_process, w_frame) + self.old_process_consistency(old_process, currentcontext) # Does not reactivate old_process because lower priority w_frame = old_process.resume(w_frame) - self.new_process_consistency(process, old_process, w_frame, - space.w_true, space.w_false) - self.old_process_consistency(old_process, space.w_true) + self.new_process_consistency(process, old_process, w_frame) + self.old_process_consistency(old_process, currentcontext) def test_semaphore_excess_signal(self): semaphore = new_semaphore() @@ -217,8 +228,11 @@ def test_semaphore_wait(self): semaphore = new_semaphore() - process, old_process = self.make_processes(4, 2, space.w_false) - semaphore.wait(space.w_true) + suspendedcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, suspendedcontext) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) assert semaphore.first_link() is old_process._w_self assert wrapper.scheduler(space).active_process() is process._w_self @@ -226,11 +240,14 @@ semaphore = new_semaphore() self.space = space semaphore.signal(self) - process, old_process = self.make_processes(4, 2, space.w_false) - semaphore.wait(space.w_true) + suspendedcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, suspendedcontext) + semaphore.wait(currentcontext) assert semaphore.is_empty_list() assert wrapper.scheduler(space).active_process() is old_process._w_self - semaphore.wait(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) assert semaphore.first_link() is old_process._w_self assert wrapper.scheduler(space).active_process() is process._w_self @@ -238,21 +255,28 @@ def test_semaphore_wait_signal(self): semaphore = new_semaphore() - process, old_process = self.make_processes(4, 2, space.w_false) + suspendedcontext = new_frame() + currentcontext = new_frame() + process, old_process = self.make_processes(4, 2, suspendedcontext) - semaphore.wait(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) + assert wrapper.scheduler(space).active_process() is process._w_self - semaphore.signal(space.w_true) + semaphore.signal(currentcontext) assert wrapper.scheduler(space).active_process() is process._w_self process_list = wrapper.scheduler(space).get_process_list(old_process.priority()) assert process_list.remove_first_link_of_list() is old_process._w_self process.write(2, space.wrap_int(1)) - old_process.resume(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + old_process.resume(currentcontext) assert wrapper.scheduler(space).active_process() is old_process._w_self - semaphore.wait(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.wait(currentcontext) assert wrapper.scheduler(space).active_process() is process._w_self - semaphore.signal(space.w_true) + with py.test.raises(interpreter.ProcessSwitch): + semaphore.signal(currentcontext) assert wrapper.scheduler(space).active_process() is old_process._w_self process_list = wrapper.scheduler(space).get_process_list(process.priority()) diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -71,13 +71,16 @@ process_list = sched.get_process_list(priority) process_list.add_process(self._w_self) - def activate(self, w_current_frame): + def activate(self): + from spyvm.interpreter import ProcessSwitch + assert not self.is_active_process() sched = scheduler(self.space) sched.store_active_process(self._w_self) w_frame = self.suspended_context() self.store_suspended_context(self.space.w_nil) self.store_my_list(self.space.w_nil) - return w_frame + assert isinstance(w_frame, model.W_PointersObject) + raise ProcessSwitch(w_frame.as_context_get_shadow(self.space)) def deactivate(self, w_current_frame): self.put_to_sleep() @@ -90,7 +93,7 @@ priority = self.priority() if priority > active_priority: active_process.deactivate(w_current_frame) - return self.activate(w_current_frame) + return self.activate() else: self.put_to_sleep() return w_current_frame @@ -102,7 +105,8 @@ if self.is_active_process(): assert self.my_list().is_same_object(self.space.w_nil) w_process = scheduler(self.space).highest_priority_process() - return ProcessWrapper(self.space, w_process).activate(w_current_frame) + self.store_suspended_context(w_current_frame) + return ProcessWrapper(self.space, w_process).activate() else: process_list = ProcessListWrapper(self.space, self.my_list()) process_list.remove(self._w_self) diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -54,7 +54,7 @@ def entry_point(argv): idx = 1 - image = None + path = None number = 0 benchmark = None @@ -76,20 +76,20 @@ _arg_missing(argv, idx, arg) benchmark = argv[idx + 1] idx += 1 - elif image is None: - image = argv[idx] + elif path is None: + path = argv[idx] else: _usage(argv) return -1 idx += 1 - if image is None: - image = "Squeak.image" + if path is None: + path = "Squeak.image" try: - f = open_file_as_stream(image) + f = open_file_as_stream(path) except OSError as e: - os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), image)) + os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path)) return 1 try: imagedata = f.readall() @@ -98,7 +98,7 @@ image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata)) image = create_image(space, image_reader) - interp = interpreter.Interpreter(space, image) + interp = interpreter.Interpreter(space, image, image_name=os.path.abspath(path)) if benchmark is not None: return _run_benchmark(interp, number, benchmark) else: From noreply at buildbot.pypy.org Fri Mar 8 18:04:00 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 18:04:00 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, krono) add INTERRUPT_SEMAPHORE Message-ID: <20130308170400.565681C39D9@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r155:7b8972a221d1 Date: 2013-03-08 15:57 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/7b8972a221d1/ Log: (tfel, krono) add INTERRUPT_SEMAPHORE diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -133,6 +133,7 @@ "special_selectors": SO_SPECIAL_SELECTORS_ARRAY, "smalltalkdict" : SO_SMALLTALK, "display" : SO_DISPLAY_OBJECT, + "interrupt_semaphore" : SO_USER_INTERRUPT_SEMAPHORE, } LONG_BIT = 32 diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -675,11 +675,11 @@ # ___________________________________________________________________________ -# Squeak Miscellaneous Primitives (128-149) +# Squeak Miscellaneous Primitives (128-134) BECOME = 128 FULL_GC = 130 INC_GC = 131 -CLONE = 148 +INTERRUPT_SEMAPHORE = 134 @expose_primitive(BECOME, unwrap_spec=[object, object]) def func(interp, s_frame, w_rcvr, w_new): @@ -710,12 +710,16 @@ rgc.collect() return fake_bytes_left(interp) - at expose_primitive(CLONE, unwrap_spec=[object]) -def func(interp, s_frame, w_arg): - return w_arg.clone(interp.space) + at expose_primitive(INTERRUPT_SEMAPHORE, unwrap_spec=[object, object]) +def func(interp, s_frame, w_rcvr, w_semaphore): + if w_semaphore.getclass(interp.space).is_same_object(interp.space.w_Semaphore): + interp.space.objtable['w_interrupt_semaphore'] = w_semaphore + else: + interp.space.objtable['w_interrupt_semaphore'] = interp.space.w_nil + return w_rcvr #____________________________________________________________________________ -# Time Primitives +# Time Primitives (135 - 137) MILLISECOND_CLOCK = 135 SECONDS_CLOCK = 137 @@ -735,6 +739,16 @@ sec_since_1901 = sec_since_epoch + secs_between_1901_and_1970 return interp.space.wrap_uint(sec_since_1901) + +#____________________________________________________________________________ +# Misc Primitives (138 - 149) +CLONE = 148 + + at expose_primitive(CLONE, unwrap_spec=[object]) +def func(interp, s_frame, w_arg): + return w_arg.clone(interp.space) + + # ___________________________________________________________________________ # File primitives (150-169) # (XXX they are obsolete in Squeak and done with a plugin) diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -403,6 +403,17 @@ # Should not fail :-) prim(primitives.FULL_GC, [42]) # Dummy arg +def test_interrupt_semaphore(): + prim(primitives.INTERRUPT_SEMAPHORE, [1, space.w_true]) + assert space.objtable["w_interrupt_semaphore"] is space.w_nil + + class SemaphoreInst(model.W_Object): + def getclass(self, space): + return space.w_Semaphore + w_semaphore = SemaphoreInst() + prim(primitives.INTERRUPT_SEMAPHORE, [1, w_semaphore]) + assert space.objtable["w_interrupt_semaphore"] is w_semaphore + def test_seconds_clock(): import time now = int(time.time()) @@ -442,7 +453,7 @@ assert space.unwrap_int(w_v.at0(space, 0)) == 1 def test_file_open_write(monkeypatch): - def open_write(filename, mode): + def open_write(filename, mode, perm): assert filename == "nonexistant" assert mode == os.O_RDWR | os.O_CREAT | os.O_TRUNC return 42 @@ -454,7 +465,7 @@ assert space.unwrap_int(w_c) == 42 def test_file_open_read(monkeypatch): - def open_read(filename, mode): + def open_read(filename, mode, perm): assert filename == "file" assert mode == os.O_RDONLY return 42 From noreply at buildbot.pypy.org Fri Mar 8 18:04:01 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 8 Mar 2013 18:04:01 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge default Message-ID: <20130308170401.799261C39DF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r156:c0b6fb0e6d02 Date: 2013-03-08 18:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c0b6fb0e6d02/ Log: merge default diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -1,3 +1,4 @@ +from rpython.rlib.jit import elidable # ___________________________________________________________________________ # Slot Names diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -365,6 +365,10 @@ from spyvm.shadow import MethodDictionaryShadow return self.as_special_get_shadow(space, MethodDictionaryShadow) + def as_cached_object_get_shadow(self, space): + from spyvm.shadow import CachedObjectShadow + return self.as_special_get_shadow(space, CachedObjectShadow) + def become(self, w_other): if not isinstance(w_other, W_PointersObject): return False diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -162,7 +162,8 @@ @specialize.arg(1) def get_special_selector(self, selector): i0 = constants.find_selectorindex(selector) - return self.w_special_selectors.at0(self, i0) + self.w_special_selectors.as_cached_object_get_shadow(self) + return self.w_special_selectors.fetch(self, i0) # methods for wrapping and unwrapping stuff diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -892,3 +892,31 @@ s_new = MethodContextShadow.make_context( space, self, receiver, arguments, sender) return s_new + +class Version: + pass + +class CachedObjectShadow(AbstractCachingShadow): + _immutable_fields_ = ['version?'] + + def __init__(self, space, w_self): + AbstractCachingShadow.__init__(self, space, w_self) + self.version = Version() + + def fetch(self, n0): + jit.promote(self) + version = self.version + jit.promote(version) + return self.safe_fetch(n0, version) + + @jit.elidable + def safe_fetch(self, n0, version): + assert version is self.version + return self._w_self._fetch(n0) + + def store(self, n0, w_value): + self.version = Version() + return self._w_self._store(n0, w_value) + + def update_shadow(self): + self.version = Version() \ No newline at end of file diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -491,6 +491,9 @@ self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" + else: + #XXX invalidate shadow here + pass return self.w_object def fillin_w_object(self): diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -58,7 +58,7 @@ image = create_testimage(space) interp = interpreter.Interpreter(space, image) - w_selector = interp.perform(space.wrap_string('loopTest'), "asSymbol") + w_selector = interp.perform(space.wrap_string('loopTest3'), "asSymbol") assert isinstance(w_selector, model.W_BytesObject) def interp_w(): interp.perform(model.W_SmallInteger(1000), w_selector) diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -47,9 +47,9 @@ def test_read_header(): reader = open_miniimage(space) reader.read_header() - assert reader.endofmemory == 0x93174 - assert reader.oldbaseaddress == 0x6649000 - assert reader.specialobjectspointer == 0x6668380 + assert reader.endofmemory == 655196 + assert reader.oldbaseaddress == -1220960256 + assert reader.specialobjectspointer == -1220832384 def test_read_all_header(): reader = open_miniimage(space) diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -207,3 +207,13 @@ shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abx" + +def test_cached_object_shadow(): + w_o = space.wrap_list([0, 1, 2, 3, 4, 5, 6, 7]) + s_o = w_o.as_cached_object_get_shadow(space) + version = s_o.version + for i in range(w_o.size()): + assert w_o.at0(space, i) == i + w_o.atput0(space, 0, 8) + assert version is not s_o.version + assert w_o.at0(space, 0) == 8 \ No newline at end of file diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -44,3 +44,18 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes + +Optimizations: +use integer tagging primitives to get more compact code: + def wrap_int(self, val): + from rpython.rlib import rerased + try: + return model.W_SmallInteger(rerased.erase_int(val)) + except OverflowError: + raise WrappingError("integer too large to fit into a tagged pointer") + +make classes + + +Unclarities: +[ ] should image loading invalidate the shadows of the precreated objects? \ No newline at end of file diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -1,4 +1,4 @@ -import sys +import sys, time import os from rpython.rlib.streamio import open_file_as_stream @@ -10,14 +10,17 @@ def _run_benchmark(interp, number, benchmark): w_object = model.W_SmallInteger(number) + t1 = time.time() try: w_result = interp.perform(w_object, benchmark) except interpreter.ReturnFromTopLevel, e: w_result = e.object + t2 = time.time() if w_result: - assert isinstance(w_result, model.W_BytesObject) - print '\n' - print w_result.as_string() + if isinstance(w_result, model.W_BytesObject): + print '\n' + print w_result.as_string() + print "took %s seconds" % (t2 - t1) return 0 return -1 From noreply at buildbot.pypy.org Fri Mar 8 18:28:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Mar 2013 18:28:50 +0100 (CET) Subject: [pypy-commit] cffi default: Check that the backend's version matches the frontend's Message-ID: <20130308172850.F36411C39D3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1197:3c435f7639fc Date: 2013-03-08 18:28 +0100 http://bitbucket.org/cffi/cffi/changeset/3c435f7639fc/ Log: Check that the backend's version matches the frontend's diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -53,6 +53,8 @@ # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with # _cffi_backend.so compiled. import _cffi_backend as backend + from . import __version__ + assert backend.__version__ == __version__ # (If you insist you can also try to pass the option # 'backend=backend_ctypes.CTypesBackend()', but don't # rely on it! It's probably not going to work well.) From noreply at buildbot.pypy.org Fri Mar 8 21:32:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 21:32:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308203251.BEAE01C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62245:17454c649f51 Date: 2013-03-08 14:56 -0500 http://bitbucket.org/pypy/pypy/changeset/17454c649f51/ Log: merge default diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -92,15 +92,20 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): + if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a " + "primitive cdata")) cdata2 = other._cdata + elif (misc.is_zero(space, w_other) and + not isinstance(self.ctype, W_CTypePrimitive)): + cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -156,6 +156,10 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): + if misc.is_zero(space, w_ob): + NULL = lltype.nullptr(rffi.CCHARP.TO) + rffi.cast(rffi.CCHARPP, cdata)[0] = NULL + return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -176,8 +180,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['cache_array_type'] - _immutable_fields_ = ['cache_array_type?'] + _attrs_ = ['is_file', 'cache_array_type'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" cache_array_type = None @@ -188,6 +192,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE" or + ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -239,23 +245,53 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if misc.is_zero(space, w_init): + # Convert 0 to NULL. Note that passing 0 is not ambigous, + # despite the potential confusion: as a 'T*' argument, 0 means + # NULL, but as a 'T[]' argument it would mean "array of size 0" + # --- except that we specifically refuse to interpret numbers + # as the array size when passing arguments. + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif (space.isinstance_w(w_init, space.w_unicode) or space.isinstance_w(w_init, space.w_bytes)): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + result = self.prepare_file(w_init) + if result: + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return False + return 0 itemsize = self.ctitem.size if itemsize <= 0: if isinstance(self.ctitem, ctypevoid.W_CTypeVoid): itemsize = 1 else: - return False + return 0 try: datasize = ovfcheck(length * itemsize) except OverflowError: @@ -269,7 +305,7 @@ lltype.free(result, flavor='raw') raise rffi.cast(rffi.CCHARPP, cdata)[0] = result - return True + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag @@ -277,7 +313,7 @@ ob = space.interpclass_w(w_ob) result = (not isinstance(ob, cdataobj.W_CData) and self._prepare_pointer_call_argument(w_ob, cdata)) - if not result: + if result == 0: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) return result @@ -307,3 +343,36 @@ if attrchar == 'i': # item return self.space.wrap(self.ctitem) return W_CTypePtrBase._fget(self, attrchar) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + + def close(self): + rffi_fclose(self.llf) + + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -209,6 +209,11 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" +def is_zero(space, w_ob): + return ((space.isinstance_w(w_ob, space.w_int) or + space.isinstance_w(w_ob, space.w_long)) + and not space.is_true(w_ob)) + # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,8 +387,19 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - y = cast(p, 0) - assert (y == None) is False + +def test_cmp_pointer_with_0(): + p = new_pointer_type(new_primitive_type("int")) + x = cast(p, 0) + assert (x == 0) is True + assert (x != 0) is False + assert (0 == x) is True + assert (0 != x) is False + y = cast(p, 42) + assert (y == 0) is False + assert (y != 0) is True + assert (0 == y) is False + assert (0 != y) is True def test_invalid_indexing(): p = new_primitive_type("int") @@ -768,7 +779,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 != 0 + assert s.p4 == 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -781,11 +792,14 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - assert s.p4 + s.p4 = 0 + assert s.p4 == 0 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) + assert s.p4 == 0 + # + s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) - assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1003,10 +1017,11 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(cast(BVoidP, 0)) # NULL + res = f(0) # NULL + assert res == -42 + res = f(long(0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) - py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): @@ -2497,7 +2512,6 @@ pass # win32 def test_FILE(): - """FILE is not supported natively any more.""" if sys.platform == "win32": py.test.skip("testing FILE not implemented") # @@ -2507,16 +2521,82 @@ BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.flush() # should not be needed + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + fw1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'rb', 256) + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("$FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() fw1 = posix.fdopen(fdw, 'wb', 256) - py.test.raises(TypeError, fputs, b"hello world\n", fw1) - fr1.close() + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert (res == fdw) == (sys.version_info < (3,)) fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) def test_GetLastError(): if sys.platform != "win32": @@ -2644,17 +2724,6 @@ c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] -def test_FILE_forbidden(): - BFILE = new_struct_type("_IO_FILE") - BFILEP = new_pointer_type(BFILE) - BFunc = new_function_type((BFILEP,), BFILEP, False) - func = cast(BFunc, 0) - with open(__file__, "rb") as f: - e = py.test.raises(TypeError, func, f) - if '__pypy__' not in sys.builtin_module_names: - assert ('note that you cannot pass Python files directly ' - 'any more since CFFI 0.6') in str(e.value) - def test_version(): # this test is here mostly for PyPy assert __version__ == "0.6" diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,7 +1,20 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from rpython.rtyper.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -4281,6 +4281,35 @@ """ self.optimize_loop(ops, expected) + def test_add_sub_ovf_second_operation_regular(self): + py.test.skip("Smalltalk would like this to pass") + # This situation occurs in Smalltalk because it uses 1-based indexing. + # The below code is equivalent to a loop over an array. + ops = """ + [i1] + i2 = int_sub(i1, 1) + escape(i2) + i3 = int_add_ovf(i1, 1) + guard_no_overflow() [] + jump(i3) + """ + preamble = """ + [i1] + i2 = int_sub(i1, 1) + escape(i2) + i3 = int_add_ovf(i1, 1) + guard_no_overflow() [] + jump(i3, i1) + """ + expected = """ + [i1, i2] + escape(i2) + i3 = int_add_ovf(i1, 1) + guard_no_overflow() [] + jump(i3, i1) + """ + self.optimize_loop(ops, expected, preamble) + def test_add_sub_ovf_virtual_unroll(self): ops = """ [p15] From noreply at buildbot.pypy.org Fri Mar 8 21:32:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 21:32:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: reapply py3k modifications to _cffi_backend that were lost in the delete/backout Message-ID: <20130308203253.4125C1C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62246:15f23fecd782 Date: 2013-03-08 15:27 -0500 http://bitbucket.org/pypy/pypy/changeset/15f23fecd782/ Log: reapply py3k modifications to _cffi_backend that were lost in the delete/backout diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -253,10 +253,10 @@ return W_CTypePtrBase.cast(self, w_ob) def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File + from pypy.module._io.interp_iobase import W_IOBase from pypy.module._cffi_backend import ctypefunc ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): + if isinstance(ob, W_IOBase): return prepare_file_argument(self.space, ob) else: return lltype.nullptr(rffi.CCHARP.TO) @@ -364,15 +364,20 @@ rffi_fclose(self.llf) -def prepare_file_argument(space, fileobj): - fileobj.direct_flush() +def prepare_file_argument(space, w_fileobj): + fileobj = space.interpclass_w(w_fileobj) + from pypy.module._io.interp_iobase import W_IOBase + assert isinstance(fileobj, W_IOBase) + space.call_method(w_fileobj, "flush") if fileobj.cffi_fileobj is None: - fd = fileobj.direct_fileno() + fd = space.int_w(space.call_method(w_fileobj, "fileno")) if fd < 0: raise OperationError(space.w_ValueError, space.wrap("file has no OS file descriptor")) + fd = os.dup(fd) + mode = space.str_w(space.getattr(w_fileobj, space.wrap("mode"))) try: - fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + fileobj.cffi_fileobj = CffiFileObj(fd, mode) except OSError, e: raise wrap_oserror(space, e) return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -210,9 +210,7 @@ ovf_msg = "long too big to convert" def is_zero(space, w_ob): - return ((space.isinstance_w(w_ob, space.w_int) or - space.isinstance_w(w_ob, space.w_long)) - and not space.is_true(w_ob)) + return space.isinstance_w(w_ob, space.w_int) and not space.is_true(w_ob) # ____________________________________________________________ diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -37,6 +37,8 @@ raise unsupported(space, "File or stream is not seekable") class W_IOBase(Wrappable): + cffi_fileobj = None # pypy/module/_cffi_backend + def __init__(self, space): # XXX: IOBase thinks it has to maintain its own internal state in # `__IOBase_closed` and call flush() by itself, but it is redundant @@ -106,6 +108,12 @@ def close_w(self, space): if self._CLOSED(): return + + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + if cffifo is not None: + cffifo.close() + try: space.call_method(self, "flush") finally: From noreply at buildbot.pypy.org Fri Mar 8 21:32:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 21:32:54 +0100 (CET) Subject: [pypy-commit] pypy default: unused Message-ID: <20130308203254.B33111C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62247:c601befd5a3a Date: 2013-03-08 15:31 -0500 http://bitbucket.org/pypy/pypy/changeset/c601befd5a3a/ Log: unused diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -252,7 +252,6 @@ def prepare_file(self, w_ob): from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc ob = self.space.interpclass_w(w_ob) if isinstance(ob, W_File): return prepare_file_argument(self.space, ob) From noreply at buildbot.pypy.org Fri Mar 8 21:32:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 21:32:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308203256.11C1E1C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62248:9e3022ea2ccb Date: 2013-03-08 15:32 -0500 http://bitbucket.org/pypy/pypy/changeset/9e3022ea2ccb/ Log: merge default diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -254,7 +254,6 @@ def prepare_file(self, w_ob): from pypy.module._io.interp_iobase import W_IOBase - from pypy.module._cffi_backend import ctypefunc ob = self.space.interpclass_w(w_ob) if isinstance(ob, W_IOBase): return prepare_file_argument(self.space, ob) From noreply at buildbot.pypy.org Fri Mar 8 22:48:23 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 8 Mar 2013 22:48:23 +0100 (CET) Subject: [pypy-commit] pypy default: fix missing derived properties: apply the properies after the ranges are Message-ID: <20130308214823.9C7EE1C39D3@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62249:120699246fbe Date: 2013-03-08 13:43 -0800 http://bitbucket.org/pypy/pypy/changeset/120699246fbe/ Log: fix missing derived properties: apply the properies after the ranges are expanded diff --git a/rpython/rlib/unicodedata/generate_unicodedb.py b/rpython/rlib/unicodedata/generate_unicodedb.py --- a/rpython/rlib/unicodedata/generate_unicodedb.py +++ b/rpython/rlib/unicodedata/generate_unicodedb.py @@ -169,6 +169,13 @@ else: table[int(code, 16)].east_asian_width = width + # Expand ranges + for (first, last), char in ranges.iteritems(): + for code in range(first, last + 1): + assert table[code] is None, 'Multiply defined character %04X' % code + + table[code] = char + # Read Derived Core Properties: for line in derived_core_properties_file: line = line.split('#', 1)[0].strip() @@ -190,13 +197,6 @@ continue table[char].properties += (p,) - # Expand ranges - for (first, last), char in ranges.iteritems(): - for code in range(first, last + 1): - assert table[code] is None, 'Multiply defined character %04X' % code - - table[code] = char - defaultChar = Unicodechar(['0000', None, 'Cn'] + [''] * 12) for code in range(len(table)): if table[code] is None: diff --git a/rpython/rlib/unicodedata/test/test_unicodedata.py b/rpython/rlib/unicodedata/test/test_unicodedata.py --- a/rpython/rlib/unicodedata/test/test_unicodedata.py +++ b/rpython/rlib/unicodedata/test/test_unicodedata.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import random import unicodedata @@ -51,6 +52,8 @@ assert unicodedb_5_2_0.isxidcontinue(ord('_')) assert unicodedb_5_2_0.isxidcontinue(ord('0')) assert not unicodedb_5_2_0.isxidcontinue(ord('(')) + oc = ord(u'日') + assert unicodedb_5_2_0.isxidstart(oc) def test_compare_functions(self): def getX(fun, code): diff --git a/rpython/rlib/unicodedata/unicodedb_3_2_0.py b/rpython/rlib/unicodedata/unicodedb_3_2_0.py --- a/rpython/rlib/unicodedata/unicodedb_3_2_0.py +++ b/rpython/rlib/unicodedata/unicodedb_3_2_0.py @@ -16052,9 +16052,8 @@ ('Lo', 'L', 'H', 7170, 0), ('Lo', 'L', 'N', 6146, 0), ('Lo', 'L', 'N', 7170, 0), -('Lo', 'L', 'W', 4098, 0), -('Lo', 'L', 'W', 4162, 0), ('Lo', 'L', 'W', 7170, 0), +('Lo', 'L', 'W', 7234, 0), ('Lo', 'R', 'N', 7170, 0), ('Lt', 'L', 'N', 7186, 0), ('Lu', 'L', 'A', 7178, 0), @@ -16251,144 +16250,144 @@ _db_pgtbl = ( '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x08\x08\x08\x08\x08\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%\x08\x08\x08&\'()*+,,,,,,,,,,,,' ',,,,,,,,,,,,,-./,0,1,,234,,,,,56,,78,,,9,,,,,,,,,,,:,,;,,,,,,,,,' -'<,,,=,,,,,,,>?,,,,,,,,@,,,,,,,,ABBBBC\x08\x08\x08\x08\x08\x08\x08,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,DEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFBGHIJKL' -'\x08\x08\x08MN\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08OP\x08\x08QRST\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'<,,,=,,,,,,,>?,,,,,,,,@,,,,,,,,A,,,,B\x08\x08\x08\x08\x08\x08\x08,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,CDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEE,FGHIJK' +'\x08\x08\x08LM\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08NO\x08\x08PQRS\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,U\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08BBV\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'W\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,T\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08,,U\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'V\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEW' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEW' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x02\x03\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xe2\xaa\xaa\xa2\xb9\xa2\xaa\xaa\xb1\x8f\xaa\xc3\x9b\x86\x9b\x9emmmmmmmmmm\x9b\xaa\xce\xcd\xce\xaa' -'\xaa((((((((((((((((((((((((((\xb1\xaa\x8f\xbe\x83\xbe\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\xb1\xcd\x8f\xcd\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xdf\xa5\xb9\xb9\xb5\xb9\xda\xd6\xbb\xd9\x10\x96\xcd\x88\xd6\xbe\xd1\xc0uu\xbb\x12\xd6\xa6\xbbu\x10\x93{{{\xa5' -"''''''%'''''''''%''''''\xc6%'''''%\x10\x10\x10\x12\x12\x12\x12\x10\x12\x10\x10\x10\x12\x10\x10\x12\x12\x10\x12\x10\x10\x12\x12\x12\xc6\x10\x10\x10\x12\x10\x12\x10\x12" -"'\x10'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x10'\x10'\x12'\x12'\x12'\x10'\x12'\x12'\x12'\x12'\x12%\x10'\x12'\x10'\x12'\x12'\x10%\x10'\x12'\x12\x10'\x12'\x12'\x12%" -"\x10%\x10'\x10'\x12'\x10\x10%\x10'\x10'\x12'\x12%\x10'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12%\x10'\x12'\x10'\x12'\x12'\x12'\x12'\x12'\x12''\x12'\x12'\x12\x12" -"\x12''\x12'\x12''\x12'''\x12\x12''''\x12''\x12'''\x12\x12\x12''\x12''\x12'\x12'\x12''\x12'\x12\x12'\x12''\x12'''\x12'\x12''\x12\x12\x1f'\x12\x12\x12" -"\x1f\x1f\x1f\x1f'$\x12'$\x12'$\x12'\x10'\x10'\x10'\x10'\x10'\x10'\x10'\x10\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12'$\x12'\x12'''\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r\r\r\r\r\r\r" +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x02\x03\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xe1\xa9\xa9\xa1\xb8\xa1\xa9\xa9\xb0\x8e\xa9\xc2\x9a\x85\x9a\x9dllllllllll\x9a\xa9\xcd\xcc\xcd\xa9' +"\xa9''''''''''''''''''''''''''\xb0\xa9\x8e\xbd\x82\xbd\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\xb0\xcc\x8e\xcc\x01" +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xde\xa4\xb8\xb8\xb4\xb8\xd9\xd5\xba\xd8\x10\x95\xcc\x87\xd5\xbd\xd0\xbftt\xba\x12\xd5\xa5\xbat\x10\x92zzz\xa4' +'&&&&&&$&&&&&&&&&$&&&&&&\xc5$&&&&&$\x10\x10\x10\x12\x12\x12\x12\x10\x12\x10\x10\x10\x12\x10\x10\x12\x12\x10\x12\x10\x10\x12\x12\x12\xc5\x10\x10\x10\x12\x10\x12\x10\x12' +'&\x10&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x10&\x10&\x12&\x12&\x12&\x10&\x12&\x12&\x12&\x12&\x12$\x10&\x12&\x10&\x12&\x12&\x10$\x10&\x12&\x12\x10&\x12&\x12&\x12$' +'\x10$\x10&\x10&\x12&\x10\x10$\x10&\x10&\x12&\x12$\x10&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12$\x10&\x12&\x10&\x12&\x12&\x12&\x12&\x12&\x12&&\x12&\x12&\x12\x12' +'\x12&&\x12&\x12&&\x12&&&\x12\x12&&&&\x12&&\x12&&&\x12\x12\x12&&\x12&&\x12&\x12&\x12&&\x12&\x12\x12&\x12&&\x12&&&\x12&\x12&&\x12\x12\x1f&\x12\x12\x12' +'\x1f\x1f\x1f\x1f&#\x12&#\x12&#\x12&\x10&\x10&\x10&\x10&\x10&\x10&\x10&\x10\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12&#\x12&\x12&&&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' -'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\x19\x19\x19\x19\x19\x19\x19\x19\x19\xbd\xbd\x19\x19\x19\x19\x19' -'\x19\x19\xbd\xbd\xbb\xbd\xbd\xbb\xbd\xbb\xbb\xbb\xbd\xbb\xbd\xbd\x15\x19\xbd\xbd\xbd\xbd\xbd\xbd\xbb\xbb\xbb\xbb\xbd\xbb\xbd\xbb\x19\x19\x19\x19\x19\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x19\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'222222222222222222222311113011111//1111//11111111111.....1111222' -'222226211122211-\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r5542222222222222\r\r\r\r\xbd\xbd\r\r\r\r\x18\r\r\r\xa9\r' -"\r\r\r\r\xbd\xbd'\xa9'''\r'\r''\x12%%%%%%%%%%%%%%%%%\r%%%%%%%''\x12\x12\x12\x12\x12\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10\x12\x10\x10\x10\x10\x10\x10\x10\x12\x12\x12\x12\x12\r\x12\x12'''\x12\x12\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12\x12\x12\x12'\x12\xcb\r\r\r\r\r\r\r\r\r" -"'%''''''''''''''%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12\xd4cccc\r,,'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"''\x12'\x12'\x12'\x12'\x12'\x12'\x12\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r'\x12\r\r\r\r\r\r" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r'''''''''''''''" -"'''''''''''''''''''''''\r\r\x19\xa4\xa4\xa4\xa4\xa4\xa4\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -'\x12\x12\x12\x12\x12\x12\x12\x12\r\xa4\x89\r\r\r\r\r\r`cccc`ccca`cccccc\r`````cc`ccabc;<=>?@ABCD\rEFG\xacH' -'\xacIJ\xacc\r\r\r\r\r\r\r\r\r\r\r###########################\r\r\r\r\r###\xac\xac\r\r\r\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\x9a\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x97\r\r\r\x97\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r' -'\x14\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1cLMNOPQRScc`\r\r\r\r\r\r\r\r\r\rjjjjjjjjjj\xa1\x98\x98\x97\x1c\x1cT\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\x19\x19\x19\x19\x19\x19\x19\x19\x19\xbc\xbc\x19\x19\x19\x19\x19' +'\x19\x19\xbc\xbc\xba\xbc\xbc\xba\xbc\xba\xba\xba\xbc\xba\xbc\xbc\x15\x19\xbc\xbc\xbc\xbc\xbc\xbc\xba\xba\xba\xba\xbc\xba\xbc\xba\x19\x19\x19\x19\x19\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\x19\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'111111111111111111111200002/00000..0000..00000000000-----0000111' +'111115100011100,\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r4431111111111111\r\r\r\r\xbc\xbc\r\r\r\r\x18\r\r\r\xa8\r' +'\r\r\r\r\xbc\xbc&\xa8&&&\r&\r&&\x12$$$$$$$$$$$$$$$$$\r$$$$$$$&&\x12\x12\x12\x12\x12\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x12\x10\x10\x10\x10\x10\x10\x10\x12\x12\x12\x12\x12\r\x12\x12&&&\x12\x12\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12\x12\x12\x12&\x12\xca\r\r\r\r\r\r\r\r\r' +'&$&&&&&&&&&&&&&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12\xd3bbbb\r++&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r&\x12\r\r\r\r\r\r' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r&&&&&&&&&&&&&&&' +'&&&&&&&&&&&&&&&&&&&&&&&\r\r\x19\xa3\xa3\xa3\xa3\xa3\xa3\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\r\xa3\x88\r\r\r\r\r\r_bbbb_bbb`_bbbbbb\r_____bb_bb`ab:;<=>?@ABC\rDEF\xabG' +'\xabHI\xabb\r\r\r\r\r\r\r\r\r\r\r"""""""""""""""""""""""""""\r\r\r\r\r"""\xab\xab\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\x99\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x96\r\r\r\x96\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r' +'\x14\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1cKLMNOPQRbb_\r\r\r\r\r\r\r\r\r\riiiiiiiiii\xa0\x97\x97\x96\x1c\x1cS\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x97\x1cccccccc\x04,cccc`c\x14\x14cc\xd9`cc`\r\rllllllllll\x1c\x1c\x1c\xd0\xd0\r' -'\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\r\x05\x1cU\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\rc`cc`cc```c``c`c' -'cc`c`c`c`cc\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c77777777777\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x96\x1cbbbbbbb\x04+bbbb_b\x14\x14bb\xd8_bb_\r\rkkkkkkkkkk\x1c\x1c\x1c\xcf\xcf\r' +'\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\r\x05\x1cT\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\rb_bb_bb___b__b_b' +'bb_b_b_b_bb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c66666666666\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r77)\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r9\x1f))' -')77777777)))):\r\r\x1fc`cc\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77\xa4\xa4nnnnnnnnnn\xa4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r7))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r\r\x1f\x1f\x1f\x1f\r\r9\r))' -')7777\r\r))\r\r)):\r\r\r\r\r\r\r\r\r)\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f77\r\rnnnnnnnnnn\x1f\x1f\xb8\xb8yyyyxy\xd4\r\r\r\r\r' -'\r\r7\r\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\r9\r))' -')77\r\r\r\r77\r\r77:\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\r\r\r\r\r\r\rnnnnnnnnnn77\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' -'\r77)\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r9\x1f))' -')77777\r77)\r)):\r\r\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\r\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r7))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\r\r9\x1f)7' -')777\r\r\r))\r\r)):\r\r\r\r\r\r\r\r7)\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f\r\r\r\rnnnnnnnnnn\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r7\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\r\x1f\r\x1f\x1f\r\r\r\x1f\x1f\r\r\r\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\r\r\r))' -'7))\r\r\r)))\r))):\r\r\r\r\r\r\r\r\r)\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rnnnnnnnnnyyy\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r)))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r77' -'7))))\r777\r777:\r\r\r\r\r\r\rVW\r\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r)7' -')))))\r7))\r))7:\r\r\r\r\r\r\r))\r\r\r\r\r\r\r\x1f\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r))' -')777\r\r)))\r))):\r\r\r\r\r\r\r\r\r)\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r:\r\r\r\r)))777\r7\r))))))))\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r))\xa4\r\r\r\r\r\r\r\r\r\r\r' -'\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f7\x1f\x1e7777XX:\r\r\r\r\xb8' -'\x1f\x1f\x1f\x1f\x1f\x1f\x197YYYY777\xa4nnnnnnnnnn\xa4\xa4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\x1f\x1f\r\x1f\r\r\x1f\x1f\r\x1f\r\r\x1f\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\r\x1f\r\r\x1f\x1f\r\x1f\x1f\x1f\x1f7\x1f\x1e7777ZZ\r77\x1f\r\r' -'\x1f\x1f\x1f\x1f\x1f\r\x19\r[[[[77\r\rnnnnnnnnnn\r\r\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\xd4\xd4\xd4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xd4\xd4\xd4\xd4\xd4``\xd4\xd4\xd4\xd4\xd4\xd4nnnnnnnnnnyyyyyyyyyy\xd4`\xd4`\xd4_\xaf\x8d\xaf\x8d))' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\\]7^77777]]]]7)' -']7cc:\xa4cc\x1f\x1f\x1f\x1f\r\r\r\r77777777\r777777777777777777777777777777777777\r\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4`\xd4\xd4\xd4\xd4\xd4\xd4\r\r\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r)7777)7\r\r\r79):\r\r\r\r\r\r' -'nnnnnnnnnn\xa4\xa4\xa4\xa4\xa4\xa4\x1f\x1f\x1f\x1f\x1f\x1f))77\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r''''''''''''''''''''''''''''''''" -"''''''\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\xa4\r\r\r\r" -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""\r\r\r\r\r"\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\r66(\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r8\x1f((' +'(66666666((((9\r\r\x1fb_bb\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f66\xa3\xa3mmmmmmmmmm\xa3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r6((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r\r\x1f\x1f\x1f\x1f\r\r8\r((' +'(6666\r\r((\r\r((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f66\r\rmmmmmmmmmm\x1f\x1f\xb7\xb7xxxxwx\xd3\r\r\r\r\r' +'\r\r6\r\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\r8\r((' +'(66\r\r\r\r66\r\r669\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\r\r\r\r\r\r\rmmmmmmmmmm66\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' +'\r66(\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r8\x1f((' +'(66666\r66(\r((9\r\r\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\r\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r6((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\r\r8\x1f(6' +'(666\r\r\r((\r\r((9\r\r\r\r\r\r\r\r6(\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f\r\r\r\rmmmmmmmmmm\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r6\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\r\x1f\r\x1f\x1f\r\r\r\x1f\x1f\r\r\r\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\r\r\r((' +'6((\r\r\r(((\r(((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rmmmmmmmmmxxx\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r(((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r66' +'6((((\r666\r6669\r\r\r\r\r\r\rUV\r\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r(6' +'(((((\r6((\r((69\r\r\r\r\r\r\r((\r\r\r\r\r\r\r\x1f\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r((' +'(666\r\r(((\r(((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r9\r\r\r\r(((666\r6\r((((((((\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r((\xa3\r\r\r\r\r\r\r\r\r\r\r' +'\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f6\x1f\x1e6666WW9\r\r\r\r\xb7' +'\x1f\x1f\x1f\x1f\x1f\x1f\x196XXXX666\xa3mmmmmmmmmm\xa3\xa3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\x1f\x1f\r\x1f\r\r\x1f\x1f\r\x1f\r\r\x1f\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\r\x1f\r\r\x1f\x1f\r\x1f\x1f\x1f\x1f6\x1f\x1e6666YY\r66\x1f\r\r' +'\x1f\x1f\x1f\x1f\x1f\r\x19\rZZZZ66\r\rmmmmmmmmmm\r\r\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\xd3\xd3\xd3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xd3\xd3\xd3\xd3\xd3__\xd3\xd3\xd3\xd3\xd3\xd3mmmmmmmmmmxxxxxxxxxx\xd3_\xd3_\xd3^\xae\x8c\xae\x8c((' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r[\\6]66666\\\\\\\\6(' +'\\6bb9\xa3bb\x1f\x1f\x1f\x1f\r\r\r\r66666666\r666666666666666666666666666666666666\r\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3_\xd3\xd3\xd3\xd3\xd3\xd3\r\r\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r(6666(6\r\r\r68(9\r\r\r\r\r\r' +'mmmmmmmmmm\xa3\xa3\xa3\xa3\xa3\xa3\x1f\x1f\x1f\x1f\x1f\x1f((66\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&' +'&&&&&&\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\xa3\r\r\r\r' +' ' +' \r\r\r\r\r \x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' @@ -16396,7 +16395,7 @@ '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r' '\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4nnnnnnnnnyyyyyyyyyyy\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3mmmmmmmmmxxxxxxxxxxx\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' '\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' @@ -16408,93 +16407,93 @@ '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa4\xa4\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r' -'\xe1\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xaf\x8d\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa4\xa4\xa4qqq\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f77:\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77:\xa4\xa4\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r77\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f)))7777777))' -'))))))7))777777777:7\xa4\xa4\xa4\x19\xa4\xa4\xa4\xb8\x1f\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xa9\xa9\xa9\xa9\xa9\xa9\x89\xa9\xa9\xa9\xa9777\x05\rnnnnnnnnnn\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa3\xa3\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r' +'\xe0\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xae\x8c\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa3\xa3\xa3ppp\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f669\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f669\xa3\xa3\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f66\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r66\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f(((6666666((' +'((((((6((66666666696\xa3\xa3\xa3\x19\xa3\xa3\xa3\xb7\x1f\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xa8\xa8\xa8\xa8\xa8\xa8\x88\xa8\xa8\xa8\xa8666\x05\rmmmmmmmmmm\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x19\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fa\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r" -"\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\r\r''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\x12\x12''''''''" -"\x12\x12\x12\x12\x12\x12\r\r''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12\r'\r'\r'\r'\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r" -"\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\r\x12\x12''''$\xbd\x12\xbd" -"\xbd\xbd\x12\x12\x12\r\x12\x12''''$\xbd\xbd\xbd\x12\x12\x12\x12\r\r\x12\x12''''\r\xbd\xbd\xbd\x12\x12\x12\x12\x12\x12\x12\x12'''''\xbd\xbd\xbd\r\r\x12\x12\x12\r\x12\x12''''$\xbd\xbd\r" -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xde\x05\x05\x06\n\x88\x89\x89\x88\x88\x88\xa5\xa9\x94\x92\xaf\x95\x94\x92\xaf\x95\xa5\xa5\xa5\xa9\xa5\xa5\xa5\xa5\xdc\xdd\x07\x0b\t\x08\x0c\xe1\x9f\xa1\x9f\x9f\xa1\xa5\xa9\xa9\xa9\x96\x93\xa5\xa9\xa9\xa5\x82' -'\x82\xa9\xa9\xa9\xcb\xb0\x8e\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xcb\r\r\r\r\xa9\r\r\r\r\r\r\r\xe1\x05\x05\x05\x05\r\r\r\r\r\r\x05\x05\x05\x05\x05\x05w\x12\r\ruwwwww\xc2\xc2\xcb\xb0\x8e\x10' -'wuuuuwwwww\xc2\xc2\xcb\xb0\x8e\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb8\xb8\xb5\xb8\xb8\xb8\xb8\xb8\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rcc88cccc888cc,,,,c,,,88c`c8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"\xd9\xd9'\xd6\xd9\xd6\xd9'\xd9\xd6\x12'''\x12\x12'''\x10\xd9'\xd6\xd9\xd9'''''\xd9\xd9\xd9\xd6\xd6\xd9'\xd9%\xd9'\xd9'%''\xd2\x12''\xd9'\x12\x1f\x1f\x1f\x1f\x12\xd9\r\r\x12''" -"\xcc\xcb\xcb\xcb\xcb'\x12\x12\x12\x12\xd9\xcb\r\r\r\r\r\r\r{{}}}}}}{{{{}ooooooooooooqqqqooooooooooqqqqqq" -'qqqp\r\r\r\r\r\r\r\r\r\r\r\r\xc6\xc6\xc6\xc6\xc6\xd6\xd6\xd6\xd6\xd6\xcb\xcb\xd9\xd9\xd9\xd9\xcb\xd9\xd9\xcb\xd9\xd9\xcb\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xd9\xd9\xc6\xd9\xc6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xc6\xcc\xc7\xc7\xcc\xcb\xcb\xc6\xc7\xcc\xcc\xc7\xcc\xcc\xcb\xc6\xcb\xc7\xc2\xc2\xcb\xc7\xcc\xcb\xcb\xcb\xc7\xcc\xcc\xc7\xc6\xc7\xc7\xcc\xcc\xc6\xcc\xc6\xcc\xc6\xc6\xc6\xc6\xc7\xc7\xcc\xc7\xcc\xcc\xcc\xcc\xcc\xc6\xc6\xc6\xc6\xcb\xcc\xcb\xcc\xc7\xc7\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xc7\xcc\xcc\xcc\xc7\xcb\xcb\xcb\xcb\xcb\xc7\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xc7\xc6\xcc\xcb\xc7\xc7\xc7\xc7\xcc\xcc\xc7\xc7\xcb\xcb\xc7\xc7\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xc7\xc7\xcc\xcc\xc7\xc7\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xc6\xcb\xcb\xcc\xc6\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xc6\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xc7' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcc\xcc\xcc\xcc\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcc\xcc\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xb3\x91\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd9\xcb\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd4\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xaf\x8d\xa9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rtttttttttssssssssssstttttttttsss' -'sssssssstttttttttsssssssssss\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' -'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3v{{{{{{{{{{|||||||||{\r' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd6\xc6\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9' -'\xd6\xc6\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd9\xd9\xd6\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd9\xd9\r\r\xd9\xd9\r\xd9\xd9\xd9\xd6\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd6\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd6\xd6\xd6\xd9\xd6\xd6\xd6\xd6\xd9\xd6\xd6\xd9\xc6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12\x12\x12\x12\x12\x12\r\r\r\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r' +'\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\r\r&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&' +'\x12\x12\x12\x12\x12\x12\r\r&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12\r&\r&\r&\r&\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r' +'\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\r\x12\x12&&&&#\xbc\x12\xbc' +'\xbc\xbc\x12\x12\x12\r\x12\x12&&&&#\xbc\xbc\xbc\x12\x12\x12\x12\r\r\x12\x12&&&&\r\xbc\xbc\xbc\x12\x12\x12\x12\x12\x12\x12\x12&&&&&\xbc\xbc\xbc\r\r\x12\x12\x12\r\x12\x12&&&&#\xbc\xbc\r' +'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xdd\x05\x05\x06\n\x87\x88\x88\x87\x87\x87\xa4\xa8\x93\x91\xae\x94\x93\x91\xae\x94\xa4\xa4\xa4\xa8\xa4\xa4\xa4\xa4\xdb\xdc\x07\x0b\t\x08\x0c\xe0\x9e\xa0\x9e\x9e\xa0\xa4\xa8\xa8\xa8\x95\x92\xa4\xa8\xa8\xa4\x81' +'\x81\xa8\xa8\xa8\xca\xaf\x8d\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xca\r\r\r\r\xa8\r\r\r\r\r\r\r\xe0\x05\x05\x05\x05\r\r\r\r\r\r\x05\x05\x05\x05\x05\x05v\x12\r\rtvvvvv\xc1\xc1\xca\xaf\x8d\x10' +'vttttvvvvv\xc1\xc1\xca\xaf\x8d\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb4\xb7\xb7\xb7\xb7\xb7\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rbb77bbbb777bb++++b+++77b_b7\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8&\xd5\xd8\xd5\xd8&\xd8\xd5\x12&&&\x12\x12&&&\x10\xd8&\xd5\xd8\xd8&&&&&\xd8\xd8\xd8\xd5\xd5\xd8&\xd8$\xd8&\xd8&$&&\xd1\x12&&\xd8&\x12\x1f\x1f\x1f\x1f\x12\xd8\r\r\x12&&' +'\xcb\xca\xca\xca\xca&\x12\x12\x12\x12\xd8\xca\r\r\r\r\r\r\rzz||||||zzzz|nnnnnnnnnnnnppppnnnnnnnnnnpppppp' +'pppo\r\r\r\r\r\r\r\r\r\r\r\r\xc5\xc5\xc5\xc5\xc5\xd5\xd5\xd5\xd5\xd5\xca\xca\xd8\xd8\xd8\xd8\xca\xd8\xd8\xca\xd8\xd8\xca\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xd8\xd8\xc5\xd8\xc5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xc5\xcb\xc6\xc6\xcb\xca\xca\xc5\xc6\xcb\xcb\xc6\xcb\xcb\xca\xc5\xca\xc6\xc1\xc1\xca\xc6\xcb\xca\xca\xca\xc6\xcb\xcb\xc6\xc5\xc6\xc6\xcb\xcb\xc5\xcb\xc5\xcb\xc5\xc5\xc5\xc5\xc6\xc6\xcb\xc6\xcb\xcb\xcb\xcb\xcb\xc5\xc5\xc5\xc5\xca\xcb\xca\xcb\xc6\xc6\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xc6\xcb\xcb\xcb\xc6\xca\xca\xca\xca\xca\xc6\xcb\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xc6\xc5\xcb\xca\xc6\xc6\xc6\xc6\xcb\xcb\xc6\xc6\xca\xca\xc6\xc6\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xc6\xc6\xcb\xcb\xc6\xc6\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xca\xca\xc5\xca\xca\xcb\xc5\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xc5\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xc6' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xcb\xcb\xcb\xcb\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xcb\xcb\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xb2\x90\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd8\xca\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd3\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xae\x8c\xa8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rsssssssssrrrrrrrrrrrsssssssssrrr' +'rrrrrrrrsssssssssrrrrrrrrrrr\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2uzzzzzzzzzz{{{{{{{{{z\r' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd5\xc5\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8' +'\xd5\xc5\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd8\xd8\xd5\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca' +'\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd8\xd8\r\r\xd8\xd8\r\xd8\xd8\xd8\xd5\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd5\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd5\xd5\xd5\xd8\xd5\xd5\xd5\xd5\xd8\xd5\xd5\xd8\xc5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\r\xd9\xd9\xd9\xd9\r\r\r\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e|||||||||{' -'~~~~~~~~~}~~~~~~~~~}\xd9\r\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xb1\x8f\xb1\x8f\xb1\x8f\r\r\r\r\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcb\xcb\xcb\xb0\x8e\xb1\x8f\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcb\xcb\xb0\x8e\xb0\x8e\xcc\xcb\xcb\xcb\xcb\xcc\xcb\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xb0\x8e\xcb\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcb\xcc\xcb\xcb\xcc\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcb\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcb\xcb' +'\r\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\r\xd8\xd8\xd8\xd8\r\r\r\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d{{{{{{{{{z' +'}}}}}}}}}|}}}}}}}}}|\xd8\r\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xca\xca\xca\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xb0\x8e\xb0\x8e\xb0\x8e\r\r\r\r\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xaf\x8d\xb0\x8e\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xca\xca\xca\xca\xca\xca\xca' +'\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xca\xca\xaf\x8d\xaf\x8d\xcb\xca\xca\xca\xca\xcb\xca\xcb\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xaf\x8d\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xcb\xcb\xca\xca\xcb\xca\xcb\xca\xca\xcb\xca\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xca\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xca\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca\xca\xca\xca\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xcb\xca\xca' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r' -'\xe0\xab\xab\xab\xdb\x1a"r\xb3\x91\xb3\x91\xb3\x91\xb3\x91\xb3\x91\xdb\xdb\xb3\x91\xb3\x91\xb3\x91\xb3\x91\x8a\xb2\x90\x90\xdbrrrrrrrrrehifgg\x8a\x1a\x1a\x1a\x1a\x1a\xdb\xdbrrr\x1a"\xab\xdb\xd9' -'\r"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""""""""""""\r\rdd\xbf\xbf\x1a\x1a"\x8a"""""""""""""""""""""""""""""""' -'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""\x84\x1a\x1a\x1a"' -'\r\r\r\r\r""""""""""""""""""""""""""""""""""""""""\r\r\r\r"""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""""\r\xd5\xd5zzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5""""""""""""""""""""""""\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r""""""""""""""""' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\rzzzzzzzzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\r\r\r\r\r\r\r\r\r\r\r\r\r\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\xd5' -'zzzzzzzzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\r\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\r\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r' +'\xdf\xaa\xaa\xaa\xda\x1a q\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xda\xda\xb2\x90\xb2\x90\xb2\x90\xb2\x90\x89\xb1\x8f\x8f\xdaqqqqqqqqqdgheff\x89\x1a\x1a\x1a\x1a\x1a\xda\xdaqqq\x1a \xaa\xda\xd8' +'\r ' +' \r\rcc\xbe\xbe\x1a\x1a \x89 ' +' \x83\x1a\x1a\x1a ' +'\r\r\r\r\r \r\r\r\r ' +' ' +' \r\xd4\xd4yyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4 \r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r ' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\ryyyyyyyyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r~~~~~~~~~~~~~~~\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\xd4' +'yyyyyyyyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4~~~~~~~~~~~~~~~' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r' ' ' ' ' ' ' @@ -16583,14 +16582,10 @@ ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""\r\r\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' ' +' ' +' \r\r\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' ' ' ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' @@ -16603,67 +16598,67 @@ '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' -'""""""""""""""""""""""""""""""""""""""""""""""\r\r""""""""""""""""' -'"""""""""""""""""""""""""""""""""""""""""""\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' \r\r ' +' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\x12\x12\x12\x12\x12\r\r\r\r\r#K##########\xc2#############\r#####\r#\r' -'##\r##\r##########\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' +'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\x12\x12\x12\x12\x12\r\r\r\r\r"J""""""""""\xc1"""""""""""""\r"""""\r"\r' +'""\r""\r""""""""""\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\xaf\x8d' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\xae\x8c' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\xb4\r\r\r' -'----------------\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rcccc\r\r\r\r\r\r\r\r\r\r\r\r\xab\x8a\x8a\x84\x84\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2' -'\x90\xb2\x90\xb2\x90\xab\xab\r\r\xab\xab\xab\xab\x84\x84\x84\x9c\xab\x9c\r\xab\x9c\xab\xab\x8a\xb2\x90\xb2\x90\xb2\x90\xa3\xab\xab\xc4\x87\xcf\xcf\xcf\r\xab\xba\xa3\xab\r\r\r\r\x1b\x1c\x1b\x1c\x1b\r\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\xb3\r\r\r' +',,,,,,,,,,,,,,,,\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rbbbb\r\r\r\r\r\r\r\r\r\r\r\r\xaa\x89\x89\x83\x83\xb1\x8f\xb1\x8f\xb1\x8f\xb1\x8f\xb1\x8f\xb1' +'\x8f\xb1\x8f\xb1\x8f\xaa\xaa\r\r\xaa\xaa\xaa\xaa\x83\x83\x83\x9b\xaa\x9b\r\xaa\x9b\xaa\xaa\x89\xb1\x8f\xb1\x8f\xb1\x8f\xa2\xaa\xaa\xc3\x86\xce\xce\xce\r\xaa\xb9\xa2\xaa\r\r\r\r\x1b\x1c\x1b\x1c\x1b\r\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\x05' -'\r\xa7\xa7\xa0\xb6\xa0\xa7\xa7\xad\x8b\xa7\xc1\x99\x85\x99\x9dkkkkkkkkkk\x99\xa7\xc9\xc8\xc9\xa7\xa7&&&&&&&&&&&&&&&&&&&&&&&&&&\xad\xa7\x8b\xbc\x80' -'\xbc\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xad\xc8\x8b\xc8\xad\x8b\xa8\xae\x8c\xa8\x81\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x17\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' +'\r\xa6\xa6\x9f\xb5\x9f\xa6\xa6\xac\x8a\xa6\xc0\x98\x84\x98\x9cjjjjjjjjjj\x98\xa6\xc8\xc7\xc8\xa6\xa6%%%%%%%%%%%%%%%%%%%%%%%%%%\xac\xa6\x8a\xbb\x7f' +'\xbb\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xac\xc7\x8a\xc7\xac\x8a\xa7\xad\x8b\xa7\x80\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x17\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' '\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\r' -'\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\r\r\r\xb6\xb6\xc8\xbc\xd7\xb6\xb6\r\xd8\xca\xca\xca\xca\xd8\xd8\r\r\r\r\r\r\r\r\r\r\x05\x05\x05\xd9\xd6\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\ryyyy\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fp\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\r\r\r\xb5\xb5\xc7\xbb\xd6\xb5\xb5\r\xd7\xc9\xc9\xc9\xc9\xd7\xd7\r\r\r\r\r\r\r\r\r\r\x05\x05\x05\xd8\xd5\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\rxxxx\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fo\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"''''''''''''''''''''''''''''''''''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" +'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4**888\xd4\xd4\xd4+*****\x05\x05\x05\x05\x05\x05\x05\x05`````' -'```\xd4\xd4ccccc``\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4cccc\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''" -"''''''''''''''\x12\x12\x12\x12\x12\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''" -"''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12'\r''\r\r'\r\r''\r\r''''\r''''''''\x12\x12\x12\x12\r\x12\r\x12\x12\x12" -"\x12\r\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12''\r''''\r\r''''''''\r'''''''\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''\r''''\r" -"'''''\r'\r\r\r'''''''\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''" -"''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''" -"''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''" -"''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r''''''''''''''''''''''''" -"'\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -'\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12\r\r\r\rllllllllllllllllllllllllllllllllllllllllllllllllll' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\r\r\r\r\r\r\r' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3))777\xd3\xd3\xd3*)))))\x05\x05\x05\x05\x05\x05\x05\x05_____' +'___\xd3\xd3bbbbb__\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3bbbb\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&' +'&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&' +'&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&\r&&\r\r&\r\r&&\r\r&&&&\r&&&&&&&&\x12\x12\x12\x12\r\x12\r\x12\x12\x12' +'\x12\r\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12&&\r&&&&\r\r&&&&&&&&\r&&&&&&&\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&\r&&&&\r' +'&&&&&\r&\r\r\r&&&&&&&\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&' +'&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&' +'&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&' +'&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r&&&&&&&&&&&&&&&&&&&&&&&&' +'&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12\r\r\r\rkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' ' ' ' ' ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'""""""""""""""""""""""""""""""\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' diff --git a/rpython/rlib/unicodedata/unicodedb_5_2_0.py b/rpython/rlib/unicodedata/unicodedb_5_2_0.py --- a/rpython/rlib/unicodedata/unicodedb_5_2_0.py +++ b/rpython/rlib/unicodedata/unicodedb_5_2_0.py @@ -134550,8 +134550,6 @@ ('Lo', 'L', 'H', 7170, 0), ('Lo', 'L', 'N', 6146, 0), ('Lo', 'L', 'N', 7170, 0), -('Lo', 'L', 'W', 4098, 0), -('Lo', 'L', 'W', 4162, 0), ('Lo', 'L', 'W', 7170, 0), ('Lo', 'L', 'W', 7234, 0), ('Lo', 'R', 'N', 7170, 0), @@ -134764,155 +134762,155 @@ _db_pgtbl = ( '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123455565575555' '555555555555589:5;5<55=5>55555?@55AB555C5555555D555E55F555555555' -'G555H5555555IJ55555555K55555555LMNNNO\x15PQRSTU55555555555555555555' -'55555555555555555555555VWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXYZ[\\]^_' -'`abcdeeefghijekeleeeeeeeeeeeeeee\x15\x15\x15mneeeeeeeeeee\x15\x15\x15\x15oeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeepqrstuvweeeeeeeeeeeeeeeeeeeeeeeexyzeeeeeeeeeeeee' -'{|5555555}~\x7f55555555555555555555555\x8055555\x8155555555555555555\x825555' -'5555555555555555555555555555555555\x8355555555555555555555555555555' -'55555555555555555555555555555555555555\x845555555555555555\x85\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x87N\x88\x86\x86\x86\x86\x89' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x89' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'\x8a\x8beeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x8c' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x8c' +'G555H5555555IJ55555555K55555555LM555N\x15OPQRST55555555555555555555' +'55555555555555555555555UVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWXYZ[\\]^' +'_`abcdddefghidjdkddddddddddddddd\x15\x15\x15lmddddddddddd\x15\x15\x15\x15nddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'ddddddddddddddddopqrstuvddddddddddddddddddddddddwxyddddddddddddd' +'z{5555555|}~55555555555555555555555\x7f55555\x8055555555555555555\x815555' +'5555555555555555555555555555555555\x8255555555555555555555555555555' +'55555555555555555555555555555555555555\x835555555555555555\x84\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x7f5\x86\x85\x85\x85\x85\x87' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x87' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'\x88\x89dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\x8a' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\x8a' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xf9\xbb\xbb\xb2\xca\xb2\xbb\xbb\xc2\xa1\xbb\xd6\xad\x97\xad\xad{{{{{{{{{{\xad\xbb\xe3\xe2\xe3\xbb' -'\xbb11111111111111111111111111\xc2\xbb\xa1\xd0\x94\xd0\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc2\xe2\xa1\xe2\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf6\xb5\xca\xca\xc6\xca\xf2\xed\xcd\xf0\x14\xa8\xe2\x06\xed\xd0\xe7\xd8\x86\x86\xcd\x16\xed\xb6\xcd\x86\x14\xa5\x8b\x8b\x8b\xb5' -'000000.000000000.000000\xdb.00000.\x14\x14\x14\x16\x16\x16\x16\x14\x16\x14\x14\x14\x16\x14\x14\x16\x16\x14\x16\x14\x14\x16\x16\x16\xdb\x14\x14\x14\x16\x14\x16\x14\x16' -'0\x140\x160\x160\x160\x160\x160\x160\x160\x140\x140\x160\x160\x160\x140\x160\x160\x160\x160\x16.\x140\x160\x140\x160\x160\x14.\x140\x160\x16\x140\x160\x160\x16.' -'\x14.\x140\x140\x160\x14\x14.\x140\x140\x160\x16.\x140\x160\x160\x160\x160\x160\x160\x160\x160\x16.\x140\x160\x140\x160\x160\x160\x160\x160\x1600\x160\x160\x16\x16' -"\x1600\x160\x1600\x16000\x16\x160000\x1600\x16000\x16\x16\x1600\x1600\x160\x160\x1600\x160\x16\x160\x1600\x16000\x160\x1600\x16\x16'0\x16\x16\x16" -"''''0-\x160-\x160-\x160\x140\x140\x140\x140\x140\x140\x140\x14\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x160-\x160\x16000\x160\x160\x160\x16" -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x16\x16\x1600\x1600\x16' -'\x160\x160000\x160\x160\x160\x160\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xf7\xb9\xb9\xb0\xc8\xb0\xb9\xb9\xc0\x9f\xb9\xd4\xab\x95\xab\xabyyyyyyyyyy\xab\xb9\xe1\xe0\xe1\xb9' +'\xb9//////////////////////////\xc0\xb9\x9f\xce\x92\xce\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc0\xe0\x9f\xe0\x01' +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf4\xb3\xc8\xc8\xc4\xc8\xf0\xeb\xcb\xee\x14\xa6\xe0\x06\xeb\xce\xe5\xd6\x84\x84\xcb\x16\xeb\xb4\xcb\x84\x14\xa3\x89\x89\x89\xb3' +'......,.........,......\xd9,.....,\x14\x14\x14\x16\x16\x16\x16\x14\x16\x14\x14\x14\x16\x14\x14\x16\x16\x14\x16\x14\x14\x16\x16\x16\xd9\x14\x14\x14\x16\x14\x16\x14\x16' +'.\x14.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x14.\x14.\x16.\x16.\x16.\x14.\x16.\x16.\x16.\x16.\x16,\x14.\x16.\x14.\x16.\x16.\x14,\x14.\x16.\x16\x14.\x16.\x16.\x16,' +'\x14,\x14.\x14.\x16.\x14\x14,\x14.\x14.\x16.\x16,\x14.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16,\x14.\x16.\x14.\x16.\x16.\x16.\x16.\x16.\x16..\x16.\x16.\x16\x16' +"\x16..\x16.\x16..\x16...\x16\x16....\x16..\x16...\x16\x16\x16..\x16..\x16.\x16.\x16..\x16.\x16\x16.\x16..\x16...\x16.\x16..\x16\x16'.\x16\x16\x16" +"''''.+\x16.+\x16.+\x16.\x14.\x14.\x14.\x14.\x14.\x14.\x14.\x14\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16.+\x16.\x16...\x16.\x16.\x16.\x16" +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16\x16\x16..\x16..\x16' +'\x16.\x16....\x16.\x16.\x16.\x16.\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d!!\x1d\x1d\x1d\x1d\x1d" -'\x1d\x1d\xcf\xcf\xcd\xcf!\x1f!\x1f\x1f\x1f!\x1f!!\x19\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcd\xcd\xcd\xcd\xcf\xcd\xcf\xcd\x1d\x1d\x1d\x1d\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcf!\xcf\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' -'=====================><<<<>;<<<<<::<<<<::<<<<<<<<<<<99999<<<<===' -'=====A=<<<===<<8===<<<<=><<=?@@?@@?=============0\x160\x16!\xcf0\x16\x10\x10\x1c\x16\x16\x16\xb9\x10' -'\x10\x10\x10\x10\xcf\xcf0\xba000\x100\x1000\x16.................\x10.......00\x16\x16\x16\x16\x16\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' -'\x14\x14\x16\x14\x14\x14\x14\x14\x14\x14\x16\x16\x16\x16\x160\x16\x16000\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x160\x16\xe00\x1600\x16\x16000' -'0.00000000000000................................\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' -'\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x16\xebppppp660\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'00\x160\x160\x160\x160\x160\x160\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10000000000000000' -'00000000000000000000000\x10\x10\x1d\xb4\xb4\xb4\xb4\xb4\xb4\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x10\xb4\x9a\x10\x10\x10\x10\x10\x10mppppmpppnmppppppmmmmmmppmppnopFGHIJKLMNOOPQR\x9cS' -'\xbdTU\xbdpm\xbdN\x10\x10\x10\x10\x10\x10\x10\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10,,,\xbd\xbd\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x05\x05\x05\x05\x10\x10\xe0\xe0\xd2\xb1\xb1\xc5\xac\xa9\xf0\xf0ppppppppZ[\\\xa9\x10\x10\xa9\xa9\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'\x18$$$$$$$$$$WXYZ[\\]^ppmmpppppmpp\x10xxxxxxxxxx\xb1\xaa\xaa\xa9$$_$$$$$$$$$$$$$$$' +'\x1d\x1d\xcd\xcd\xcb\xcd!\x1f!\x1f\x1f\x1f!\x1f!!\x19\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcb\xcb\xcb\xcb\xcd\xcb\xcd\xcb\x1d\x1d\x1d\x1d\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcd!\xcd\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd' +';;;;;;;;;;;;;;;;;;;;;<::::<9:::::88::::88:::::::::::77777::::;;;' +';;;;;?;:::;;;::6;;;::::;<::;=>>=>>=;;;;;;;;;;;;;.\x16.\x16!\xcd.\x16\x10\x10\x1c\x16\x16\x16\xb7\x10' +'\x10\x10\x10\x10\xcd\xcd.\xb8...\x10.\x10..\x16,,,,,,,,,,,,,,,,,\x10,,,,,,,..\x16\x16\x16\x16\x16\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' +'\x14\x14\x16\x14\x14\x14\x14\x14\x14\x14\x16\x16\x16\x16\x16.\x16\x16...\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16.\x16\xde.\x16..\x16\x16...' +'.,..............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' +'\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16\xe9nnnnn44.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'..\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10...............' +'.......................\x10\x10\x1d\xb2\xb2\xb2\xb2\xb2\xb2\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x10\xb2\x98\x10\x10\x10\x10\x10\x10knnnnknnnlknnnnnnkkkkkknnknnlmnDEFGHIJKLMMNOP\x9aQ' +'\xbbRS\xbbnk\xbbL\x10\x10\x10\x10\x10\x10\x10\x10***************************\x10\x10\x10\x10\x10***\xbb\xbb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x05\x05\x05\x05\x10\x10\xde\xde\xd0\xaf\xaf\xc3\xaa\xa7\xee\xeennnnnnnnXYZ\xa7\x10\x10\xa7\xa7\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'\x18$$$$$$$$$$UVWXYZ[\\nnkknnnnnknn\x10vvvvvvvvvv\xaf\xa8\xa8\xa7$$]$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$\xa9$ppppppp\x056ppppmp\x18\x18pp\xf0mppm$$zzzzzzzzzz$$$\xe6\xe6$' -'\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\x10\x07$`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$pmppmppmmmpmmpmp' -'ppmpmpmpmpp\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$BBBBBBBBBBB$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'}}}}}}}}}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,pppppppmp""\xf0\xb9\xb9\xb9"\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,pppp"ppppppppp"ppp"ppppp\x10\x10\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x10' +'$$$$$$$$$$$$$$$$$$$$\xa7$nnnnnnn\x054nnnnkn\x18\x18nn\xeeknnk$$xxxxxxxxxx$$$\xe4\xe4$' +'\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\x10\x07$^$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$nknnknnkkknkknkn' +'nnknknknknn\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@@@@@@@@@@$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'{{{{{{{{{{*********************************nnnnnnnkn""\xee\xb7\xb7\xb7"\x10\x10\x10\x10\x10' +'**********************nnnn"nnnnnnnnn"nnn"nnnnn\x10\x10\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BBB2''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10D'22" -"2BBBBBBBB2222E2\x10'pmppB\x10\x10''''''''''BB\xb4\xb4||||||||||\xb4\x1d'\x10\x10\x10\x10\x10\x10'''''''" -"\x10B22\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10'\x10\x10\x10''''\x10\x10D'22" -"2BBBB\x10\x1022\x10\x1022E'\x10\x10\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10''\x10'''BB\x10\x10||||||||||''\xc9\xc9\x88\x88\x88\x88\x88\x88\xeb\xc9\x10\x10\x10\x10" -"\x10BB2\x10''''''\x10\x10\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10''\x10''\x10\x10D\x1022" -"2BB\x10\x10\x10\x10BB\x10\x10BBE\x10\x10\x10B\x10\x10\x10\x10\x10\x10\x10''''\x10'\x10\x10\x10\x10\x10\x10\x10||||||||||BB'''B\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10BB2\x10'''''''''\x10'''\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10D'22" -"2BBBBB\x10BB2\x1022E\x10\x10'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x10\xc9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10B22\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10D'2B" -"2BBBB\x10\x1022\x10\x1022E\x10\x10\x10\x10\x10\x10\x10\x10B2\x10\x10\x10\x10''\x10'''BB\x10\x10||||||||||\xeb'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10B'\x10''''''\x10\x10\x10'''\x10''''\x10\x10\x10''\x10'\x10''\x10\x10\x10''\x10\x10\x10'''\x10\x10\x10''''''''''''\x10\x10\x10\x1022" -"B22\x10\x10\x10222\x10222E\x10\x10'\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10||||||||||\x88\x88\x88\xf0\xf0\xf0\xf0\xf0\xf0\xc9\xf0\x10\x10\x10\x10\x10" -"\x10222\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10\x10'BB" -"B2222\x10BBB\x10BBBE\x10\x10\x10\x10\x10\x10\x10ab\x10''\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x10\x10\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xeb" -"\x10\x1022\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10D'27" -"22222\x10722\x1022BE\x10\x10\x10\x10\x10\x10\x1022\x10\x10\x10\x10\x10\x10\x10'\x10''BB\x10\x10||||||||||\x10\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x1022\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''''''''\x10\x10\x10'22" -"2BBBB\x10222\x10222E\x10\x10\x10\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x88\x88\x88\x88\x88\x88\x10\x10\x10\xeb''''''" -"\x10\x1022\x10''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''\x10'''''''''\x10'\x10\x10" -"'''''''\x10\x10\x10E\x10\x10\x10\x10222BBB\x10B\x1022222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1022\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10''''''''''''''''''''''''''''''''''''''''''''''''B'&BBBBccE\x10\x10\x10\x10\xc9" -"''''''\x1dBddddBBB\xb4||||||||||\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10''\x10'\x10\x10''\x10'\x10\x10'\x10\x10\x10\x10\x10\x10''''\x10'''''''\x10'''\x10'\x10'\x10\x10''\x10''''B'&BBBBee\x10BB'\x10\x10" -"'''''\x10\x1d\x10ffffBB\x10\x10||||||||||\x10\x10''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'\xeb\xeb\xeb\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\xebmm\xeb\xeb\xeb\xeb\xeb\xeb||||||||||\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xebm\xebm\xebl\xc1\xa0\xc1\xa022" -"''''''''\x10''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10ghBiBBBBBhhhhB2" -"hBppE\xb4pp''''\x10\x10\x10\x10BBBBBBBB\x10BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x10\xeb\xeb" -'\xeb\xeb\xeb\xeb\xeb\xebm\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\xeb\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''''''''''22BBBB2BBBBBD2EE22BB'" -"||||||||||\xb4\xb4\xb4\xb4\xb4\xb4''''''22BB''''BBB'222''2222222'''BBBB'''''''''''" -"''B22BB222222m'2||||||||||222B\xeb\xeb00000000000000000000000000000000" -"000000\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''''''''''''''''''''''''''''''''\xb4\x1d\x10\x10\x10" -'****************************************************************' -"********************************''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''*****''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''******" +"@@@0''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10B'00" +"0@@@@@@@@0000C0\x10'nknn@\x10\x10''''''''''@@\xb2\xb2zzzzzzzzzz\xb2\x1d'\x10\x10\x10\x10\x10\x10'''''''" +"\x10 at 00\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10'\x10\x10\x10''''\x10\x10B'00" +"0@@@@\x10\x1000\x10\x1000C'\x10\x10\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10''\x10'''@@\x10\x10zzzzzzzzzz''\xc7\xc7\x86\x86\x86\x86\x86\x86\xe9\xc7\x10\x10\x10\x10" +"\x10@@0\x10''''''\x10\x10\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10''\x10''\x10\x10B\x1000" +"0@@\x10\x10\x10\x10@@\x10\x10@@C\x10\x10\x10@\x10\x10\x10\x10\x10\x10\x10''''\x10'\x10\x10\x10\x10\x10\x10\x10zzzzzzzzzz@@'''@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10@@0\x10'''''''''\x10'''\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10B'00" +"0@@@@@\x10@@0\x1000C\x10\x10'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x10\xc7\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10 at 00\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10B'0@" +"0@@@@\x10\x1000\x10\x1000C\x10\x10\x10\x10\x10\x10\x10\x10 at 0\x10\x10\x10\x10''\x10'''@@\x10\x10zzzzzzzzzz\xe9'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x10@'\x10''''''\x10\x10\x10'''\x10''''\x10\x10\x10''\x10'\x10''\x10\x10\x10''\x10\x10\x10'''\x10\x10\x10''''''''''''\x10\x10\x10\x1000" +"@00\x10\x10\x10000\x10000C\x10\x10'\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10zzzzzzzzzz\x86\x86\x86\xee\xee\xee\xee\xee\xee\xc7\xee\x10\x10\x10\x10\x10" +"\x10000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10\x10'@@" +"@0000\x10@@@\x10@@@C\x10\x10\x10\x10\x10\x10\x10_`\x10''\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x10\x10\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xe9" +"\x10\x1000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10B'05" +"00000\x10500\x1000 at C\x10\x10\x10\x10\x10\x10\x1000\x10\x10\x10\x10\x10\x10\x10'\x10''@@\x10\x10zzzzzzzzzz\x10\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x1000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''''''''\x10\x10\x10'00" +"0@@@@\x10000\x10000C\x10\x10\x10\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x86\x86\x86\x86\x86\x86\x10\x10\x10\xe9''''''" +"\x10\x1000\x10''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''\x10'''''''''\x10'\x10\x10" +"'''''''\x10\x10\x10C\x10\x10\x10\x10000@@@\x10@\x1000000000\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1000\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10''''''''''''''''''''''''''''''''''''''''''''''''@'&@@@@aaC\x10\x10\x10\x10\xc7" +"''''''\x1d at bbbb@@@\xb2zzzzzzzzzz\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10''\x10'\x10\x10''\x10'\x10\x10'\x10\x10\x10\x10\x10\x10''''\x10'''''''\x10'''\x10'\x10'\x10\x10''\x10''''@'&@@@@cc\x10@@'\x10\x10" +"'''''\x10\x1d\x10dddd@@\x10\x10zzzzzzzzzz\x10\x10''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'\xe9\xe9\xe9\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\xe9kk\xe9\xe9\xe9\xe9\xe9\xe9zzzzzzzzzz\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\xe9k\xe9k\xe9j\xbf\x9e\xbf\x9e00" +"''''''''\x10''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10ef at g@@@@@ffff at 0" +"f at nnC\xb2nn''''\x10\x10\x10\x10@@@@@@@@\x10@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\x10\xe9\xe9" +'\xe9\xe9\xe9\xe9\xe9\xe9k\xe9\xe9\xe9\xe9\xe9\xe9\x10\xe9\xe9\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''''''''''''''''00@@@@0@@@@@B0CC00@@'" +"zzzzzzzzzz\xb2\xb2\xb2\xb2\xb2\xb2''''''00@@''''@@@'000''0000000'''@@@@'''''''''''" +"''@00@@000000k'0zzzzzzzzzz000@\xe9\xe9................................" +"......\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''''''''''''''''''''''''''''''''\xb2\x1d\x10\x10\x10" +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +"((((((((((((((((((((((((((((((((''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''(((((''''''''''''''''''''''''" +"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''((((((" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''\x10''''\x10\x10'''''''\x10'\x10''''\x10\x10''''''''''''''''''''''''''''''''" "'''''''''\x10''''\x10\x10'''''''''''''''''''''''''''''''''\x10''''\x10\x10'''''''\x10" "'\x10''''\x10\x10'''''''''''''''\x10''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''\x10''''\x10\x10''''''''''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''\x10\x10\x10\x10p\xeb\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x89\x89\x89\x89\x89\x89\x89\x89\x89\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10" -"''''''''''''''''\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''\x10\x10\x10\x10n\xe9\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x87\x87\x87\x87\x87\x87\x87\x87\x87\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10" +"''''''''''''''''\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x9a'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" +"\x98'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" @@ -134921,125 +134919,125 @@ "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''''''''''''\xb4\xb4'''''''''''''''''" -"\xf8''''''''''''''''''''''''''\xc1\xa0\x10\x10\x10''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''''''''''\xb4\xb4\xb4\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''\x10''''BBE\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''BBE\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''BB\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''\x10'''\x10BB\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''''''\x08\x082BBBBBBB22" -"222222B22BBBBBBBBBEB\xb4\xb4\xb4\x1d\xb4\xb4\xb4\xc9'p\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x10\x10\x10\x10\x10\x10" -"\xb9\xb9\xb9\xb9\xb9\xb9\x9a\xb9\xb9\xb9\xb9BBB\xf8\x10||||||||||\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''''''\xb2\xb2'''''''''''''''''" +"\xf6''''''''''''''''''''''''''\xbf\x9e\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''''\xb2\xb2\xb2~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'''''''''''''\x10''''@@C\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''@@C\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''@@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''\x10'''\x10@@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''''''\x08\x080@@@@@@@00" +"000000 at 00@@@@@@@@@C@\xb2\xb2\xb2\x1d\xb2\xb2\xb2\xc7'n\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x10\x10\x10\x10\x10\x10" +"\xb7\xb7\xb7\xb7\xb7\xb7\x98\xb7\xb7\xb7\xb7@@@\xf6\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" "'''\x1d''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''''''''''''''o'\x10\x10\x10\x10\x10''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''m'\x10\x10\x10\x10\x10''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''\x10\x10\x10BBB2222BB222\x10\x10\x10\x1022B222222npm\x10\x10\x10\x10" -"\xf0\x10\x10\x10\xb9\xb9||||||||||''''''''''''''''''''''''''''''\x10\x10'''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x102222222222222222" -"2'''''''22\x10\x10\x10\x10\x10\x10|||||||||||\x10\x10\x10\xb9\xb9\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" -"'''''''''''''''''''''''pm222\x10\x10\xb4\xb4''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''2B2BBBBBBB\x10E2B22BBBBBBBB222222BBpppppppp\x10\x10m" -'||||||||||\x10\x10\x10\x10\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x1d\xb4\xb4\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''\x10\x10\x10@@@0000@@000\x10\x10\x10\x1000 at 000000lnk\x10\x10\x10\x10" +"\xee\x10\x10\x10\xb7\xb7zzzzzzzzzz''''''''''''''''''''''''''''''\x10\x10'''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x100000000000000000" +"0'''''''00\x10\x10\x10\x10\x10\x10zzzzzzzzzzz\x10\x10\x10\xb7\xb7\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee" +"'''''''''''''''''''''''nk000\x10\x10\xb2\xb2''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''0 at 0@@@@@@@\x10C0 at 00@@@@@@@@000000@@nnnnnnnn\x10\x10k" +'zzzzzzzzzz\x10\x10\x10\x10\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x1d\xb2\xb2\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BBBB2'''''''''''''''''''''''''''''''''''''''''''''''D2BBBBB2B222" -"22B23'''''''\x10\x10\x10\x10||||||||||\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebpmppppppp\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10" -"BB2''''''''''''''''''''''''''''''2BBBB22BB3\x10\x10\x10''||||||||||\x10\x10\x10\x10\x10\x10" +"@@@@0'''''''''''''''''''''''''''''''''''''''''''''''B0@@@@@0 at 000" +"00 at 01'''''''\x10\x10\x10\x10zzzzzzzzzz\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9nknnnnnnn\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10" +"@@0''''''''''''''''''''''''''''''0@@@@00@@1\x10\x10\x10''zzzzzzzzzz\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"''''''''''''''''''''''''''''''''''''22222222BBBBBBBB22BD\x10\x10\x10\xb4\xb4\xb4\xb4\xb4" -"||||||||||\x10\x10\x10'''||||||||||''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb4\xb4" +"''''''''''''''''''''''''''''''''''''00000000@@@@@@@@00 at B\x10\x10\x10\xb2\xb2\xb2\xb2\xb2" +"zzzzzzzzzz\x10\x10\x10'''zzzzzzzzzz''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb2\xb2" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10ppp\xb4Cmmmmmppmmmmp2CCCCCCC''''m''''2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10nnn\xb2Akkkkknnkkkkn0AAAAAAA''''k''''0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' '\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' -'ppmpppppppmppqkmjpppppppppppppppppppppp\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10mpm' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x16\x16\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x10\x10000000\x10\x10\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x16\x1600000000' -'\x16\x16\x16\x16\x16\x16\x10\x10000000\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16\x100\x100\x100\x100\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10' -'\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x10\x16\x160000-\xcf\x16\xcf' -'\xcf\xcf\x16\x16\x16\x10\x16\x160000-\xcf\xcf\xcf\x16\x16\x16\x16\x10\x10\x16\x160000\x10\xcf\xcf\xcf\x16\x16\x16\x16\x16\x16\x16\x1600000\xcf\xcf\xcf\x10\x10\x16\x16\x16\x10\x16\x160000-\xcf\xcf\x10' -'\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\x07\x07\x07\x08\r\x99\x9a\x9a\x99\x99\x99\xb5\xb9\xa6\xa4\xc0\xa7\xa6\xa4\xc0\xa7\xb5\xb5\xb5\xb9\xb5\xb5\xb5\xb5\xf4\xf5\t\x0e\x0c\n\x0f\xf6\xaf\xb1\xaf\xaf\xb1\xb5\xb9\xb9\xb9\xa8\xa5\xb5\xb9\xb9\xb5\x93' -'\x93\xb9\xb9\xb9\xd3\xc1\xa0\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xe0\xb9\x93\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xf8\x07\x07\x07\x07\x07\x10\x10\x10\x10\x10\x07\x07\x07\x07\x07\x07\x87\x1d\x10\x10\x86\x87\x87\x87\x87\x87\xd5\xd5\xe0\xc1\xa0\x19' -'\x87\x86\x86\x86\x86\x87\x87\x87\x87\x87\xd5\xd5\xe0\xc1\xa0\x10\x1d\x1d\x1d\x1d\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc8\xc9\xc9\xc6\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10ppCCppppCCCpp6666p666CCpmpCCmmmmp\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"\xf0\xf00\xed\xf0\xed\xf00\xf0\xed\x16000\x16\x16000\x14\xf00\xed\xf0\xf100000\xf0\xf0\xf0\xed\xed\xf00\xf0.\xf00\xf00.00\xe9\x160000\x16''''\x16\xf0\xf0\x16\x1600" -'\xe1\xe0\xe0\xe0\xe00\x16\x16\x16\x16\xf0\xe0\xf0\xf0\x16\xeb\x8d\x8d\x8d\x8b\x8b\x8d\x8d\x8d\x8d\x8d\x8d\x8b\x8b\x8b\x8b\x8d~~~~~~~~~~~~\x80\x80\x80\x80~~~~~~~~~~\x80\x80\x80\x80\x80\x80' -'\x80\x80\x800\x16\x80\x80\x80\x80\x8b\x10\x10\x10\x10\x10\x10\xdb\xdb\xdb\xdb\xdb\xed\xed\xed\xed\xed\xe0\xe0\xf0\xf0\xf0\xf0\xe0\xf0\xf0\xe0\xf0\xf0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xf0\xf0\xdb\xf0\xdb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xdb\xe1\xdc\xdc\xe1\xe0\xe0\xdb\xdc\xe1\xe1\xdc\xe1\xe1\xe0\xdb\xe0\xdc\xd5\xd9\xe0\xdc\xe1\xe0\xe0\xe0\xdc\xe1\xe1\xdc\xdb\xdc\xdc\xe1\xe1\xdb\xe1\xdb\xe1\xdb\xdb\xdb\xdb\xdc\xdc\xe1\xdc\xe1\xe1\xe1\xe1\xe1\xdb\xdb\xdb\xdb\xe0\xe1\xe0\xe1\xdc\xdc\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xdc\xe1\xe1\xe1\xdc\xe0\xe0\xe0\xe0\xe0\xdc\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xdc\xdb\xe1\xe0\xdc\xdc\xdc\xdc\xe1\xe1\xdc\xdc\xe0\xe0\xdc\xdc\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xdc\xdc\xe1\xe1\xdc\xdc\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xdb\xe0\xe0\xe1\xdb\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xdb\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xdc' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe1\xe1\xe1\xe1\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe1\xe1\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xc4\xa3\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xf0\xe0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8b\x8b' -'\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x86\x86\x86\x86\x86\x86\x86\x86\x86\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' -'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x8e\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8c' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xed\xdb\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0' -'\xed\xdb\xf0\xf0\xf0\xf0\xed\xed\xed\xf0\xf0\xed\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xed\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xed\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xed\xed\xed\xf0\xed\xed\xed\xed\xf0\xed\xed\xf0\xdb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed' -'\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\x10\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\x10\xed\x10\x10\x10\x10\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed' -'\x10\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\x10\xf0\xf0\xf0\xf0\x10\x10\x10\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b' -'\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8d\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8d\xf0\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10' -'\xe1\xe0\xe0\xe1\xe1\xc1\xa0\xe0\xe1\xe1\xe0\x10\xe1\x10\x10\x10\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xc1\xa0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' +'nnknnnnnnnknnoikhnnnnnnnnnnnnnnnnnnnnnn\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10knk' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x10\x10......\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x16\x16........' +'\x16\x16\x16\x16\x16\x16\x10\x10......\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16\x10.\x10.\x10.\x10.\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10' +'\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x10\x16\x16....+\xcd\x16\xcd' +'\xcd\xcd\x16\x16\x16\x10\x16\x16....+\xcd\xcd\xcd\x16\x16\x16\x16\x10\x10\x16\x16....\x10\xcd\xcd\xcd\x16\x16\x16\x16\x16\x16\x16\x16.....\xcd\xcd\xcd\x10\x10\x16\x16\x16\x10\x16\x16....+\xcd\xcd\x10' +'\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\x07\x07\x07\x08\r\x97\x98\x98\x97\x97\x97\xb3\xb7\xa4\xa2\xbe\xa5\xa4\xa2\xbe\xa5\xb3\xb3\xb3\xb7\xb3\xb3\xb3\xb3\xf2\xf3\t\x0e\x0c\n\x0f\xf4\xad\xaf\xad\xad\xaf\xb3\xb7\xb7\xb7\xa6\xa3\xb3\xb7\xb7\xb3\x91' +'\x91\xb7\xb7\xb7\xd1\xbf\x9e\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xde\xb7\x91\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xf6\x07\x07\x07\x07\x07\x10\x10\x10\x10\x10\x07\x07\x07\x07\x07\x07\x85\x1d\x10\x10\x84\x85\x85\x85\x85\x85\xd3\xd3\xde\xbf\x9e\x19' +'\x85\x84\x84\x84\x84\x85\x85\x85\x85\x85\xd3\xd3\xde\xbf\x9e\x10\x1d\x1d\x1d\x1d\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc6\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10nnAAnnnnAAAnn4444n444AAnknAAkkkkn\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"\xee\xee.\xeb\xee\xeb\xee.\xee\xeb\x16...\x16\x16...\x14\xee.\xeb\xee\xef.....\xee\xee\xee\xeb\xeb\xee.\xee,\xee.\xee.,..\xe7\x16....\x16''''\x16\xee\xee\x16\x16.." +'\xdf\xde\xde\xde\xde.\x16\x16\x16\x16\xee\xde\xee\xee\x16\xe9\x8b\x8b\x8b\x89\x89\x8b\x8b\x8b\x8b\x8b\x8b\x89\x89\x89\x89\x8b||||||||||||~~~~||||||||||~~~~~~' +'~~~.\x16~~~~\x89\x10\x10\x10\x10\x10\x10\xd9\xd9\xd9\xd9\xd9\xeb\xeb\xeb\xeb\xeb\xde\xde\xee\xee\xee\xee\xde\xee\xee\xde\xee\xee\xde\xee\xee\xee\xee\xee\xee\xee\xde\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xee\xee\xd9\xee\xd9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xd9\xdf\xda\xda\xdf\xde\xde\xd9\xda\xdf\xdf\xda\xdf\xdf\xde\xd9\xde\xda\xd3\xd7\xde\xda\xdf\xde\xde\xde\xda\xdf\xdf\xda\xd9\xda\xda\xdf\xdf\xd9\xdf\xd9\xdf\xd9\xd9\xd9\xd9\xda\xda\xdf\xda\xdf\xdf\xdf\xdf\xdf\xd9\xd9\xd9\xd9\xde\xdf\xde\xdf\xda\xda\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xda\xdf\xdf\xdf\xda\xde\xde\xde\xde\xde\xda\xdf\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xda\xd9\xdf\xde\xda\xda\xda\xda\xdf\xdf\xda\xda\xde\xde\xda\xda\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xda\xda\xdf\xdf\xda\xda\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xde\xde\xd9\xde\xde\xdf\xd9\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xd9\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xda' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xee\xee\xee\xee\xee\xee\xee\xee\xdf\xdf\xdf\xdf\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xdf\xdf\xee\xee\xee\xee\xee\xee\xee\xc2\xa1\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xee\xde\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x89\x89' +'\x89\x89\x89\x89\x89\x89\x89\x89\x84\x84\x84\x84\x84\x84\x84\x84\x84\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8' +'\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\x8c\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x8a' '\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xc1\xa0\xc2\xa1\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe0\xe0\xc1\xa0\xc1\xa0\xe1\xe0\xe0\xe0\xe0\xe1\xe0\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xc1\xa0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe0\xe1\xe0\xe0\xe1\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe0\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe0\xe0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xeb\xd9\xee\xee\xee\xee\xeb\xeb\xee\xee' +'\xeb\xd9\xee\xee\xee\xee\xeb\xeb\xeb\xee\xee\xeb\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde' +'\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xeb\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee\xeb\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xeb\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xeb\xeb\xeb\xee\xeb\xeb\xeb\xeb\xee\xeb\xeb\xee\xd9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb' +'\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\x10\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' +'\x10\xee\xee\xee\xee\x10\xee\xee\xee\xee\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\x10\xee\xee\xee\xee\x10\x10\x10\xee\xeb\xee\xee\xee\xee\xee\xee\xee\x10\x10\xee\xee\xee\xee\xee\xee\xee\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89' +'\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\xee\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10' +'\xdf\xde\xde\xdf\xdf\xbf\x9e\xde\xdf\xdf\xde\x10\xdf\x10\x10\x10\xde\xde\xde\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xc0\x9f\xc0\x9f\xc0\x9f\xc0\x9f\xbf\x9e\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xbf\x9e\xc0\x9f\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xde\xde\xde\xde\xde\xde\xde' +'\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xde\xde\xbf\x9e\xbf\x9e\xdf\xde\xde\xde\xde\xdf\xde\xdf\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xbf\x9e\xde\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xdf\xdf\xde\xde\xdf\xde\xdf\xde\xde\xdf\xde\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xde\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xde\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde\xde\xde\xde\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xdf\xde\xde' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xde\xde\xee\xee\xde\xde\xde\xde\xde\xde\x10\x10\x10\xee\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'00000000000000000000000000000000000000000000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x100\x16000\x16\x160\x160\x160\x160000\x160\x16\x160\x16\x16\x16\x16\x16\x16\x16\x1d00' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\xf0\xf0\xf0\xf0\xf0\xf00\x160\x16ppp\x10\x10\x10\x10\x10\x10\x10\xb9\xb9\xb9\xb9\x8d\xb9\xb9' +'...............................................\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10.\x16...\x16\x16.\x16.\x16.\x16....\x16.\x16\x16.\x16\x16\x16\x16\x16\x16\x16\x1d..' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\xee\xee\xee\xee\xee\xee.\x16.\x16nnn\x10\x10\x10\x10\x10\x10\x10\xb7\xb7\xb7\xb7\x8b\xb7\xb7' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" "''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" "'''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''\x10'''''''\x10'''''''\x10'''''''\x10" -"'''''''\x10'''''''\x10'''''''\x10'''''''\x10pppppppppppppppppppppppppppppppp" -'\xb9\xb9\xa8\xa5\xa8\xa5\xb9\xb9\xb9\xa8\xa5\xb9\xa8\xa5\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x9a\xb9\xb9\x9a\xb9\xa8\xa5\xb9\xb9\xa8\xa5\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xb9\xb9\xb9\xb9\xb9 \xb9\xb9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''\x10'''''''\x10'''''''\x10'''''''\x10nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" +'\xb7\xb7\xa6\xa3\xa6\xa3\xb7\xb7\xb7\xa6\xa3\xb7\xa6\xa3\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\x98\xb7\xb7\x98\xb7\xa6\xa3\xb7\xb7\xa6\xa3\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xb7\xb7\xb7\xb7\xb7 \xb7\xb7\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10' -'\xf7\xbc\xbc\xbc\xf3\x1e*\x81\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\xf3\xf3\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\x9b\xc3\xa2\xa2\xf3\x81\x81\x81\x81\x81\x81\x81\x81\x81svwtuu\x9b\x1e\x1e\x1e\x1e\x1e\xf3\xf3\x81\x81\x81\x1e*\xbc\xf3\xf0' -'\x10***************************************************************' -'***********************\x10\x10rr\xd1\xd1\x1e\x1e*\x9b*******************************' -'***********************************************************\xbc\x1e\x1e\x1e*' -'\x10\x10\x10\x10\x10*****************************************\x10\x10\x10***************' -'****************************************************************' -'***************\x10\xec\xec\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec************************\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10****************' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\x10\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xea\xea\xea\xea\xea\xea\xea\xea\xf3\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xec' -'\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10' +'\xf5\xba\xba\xba\xf1\x1e(\x7f\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xf1\xf1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\x99\xc1\xa0\xa0\xf1\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7fqturss\x99\x1e\x1e\x1e\x1e\x1e\xf1\xf1\x7f\x7f\x7f\x1e(\xba\xf1\xee' +'\x10(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((((((((((((\x10\x10pp\xcf\xcf\x1e\x1e(\x99(((((((((((((((((((((((((((((((' +'(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((\xba\x1e\x1e\x1e(' +'\x10\x10\x10\x10\x10(((((((((((((((((((((((((((((((((((((((((\x10\x10\x10(((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((((\x10\xea\xea\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10((((((((((((((((' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xf1\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xea' +'\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xf1\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xf1\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1' '((((()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' @@ -135059,7 +135057,7 @@ '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' ')(()((()()((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((()((((((((((((((((((((((((((((((((((' '(((((((((((()((((((()()(((((((((((((((((((((((((((((((((((((((()' @@ -135140,46 +135138,42 @@ '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'*********************\x1e******************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'*************\x10\x10\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -"\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb4\xb4" -"''''''''''''\x1d\xb9\xb9\xb9''''''''''''''''||||||||||''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x100\x160\x160\x160\x160\x160\x16'p666\xb9\x10\x10\x10\x10\x10\x10\x10\x10pp\xb9!" -"0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''''''''''\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80pp\xb4\xb4\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10" -'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf!!!!!!!!!\xcf\xcf0\x160\x160\x160\x160\x160\x160\x16\x16\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x1d\x16\x16\x16\x16\x16\x16\x16\x160\x160\x1600\x16' -'0\x160\x160\x160\x16!\xcc\xcc0\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'(((((((((((((((((((((\x1e((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((\x10\x10\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +"\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb2\xb2" +"''''''''''''\x1d\xb7\xb7\xb7''''''''''''''''zzzzzzzzzz''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +".\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10.\x16.\x16.\x16.\x16.\x16.\x16'n444\xb7\x10\x10\x10\x10\x10\x10\x10\x10nn\xb7!" +".\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"''''''''''''''''''''''''''''''''''''''~~~~~~~~~~nn\xb2\xb2\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10" +'\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd!!!!!!!!!\xcd\xcd.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x1d\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16..\x16' +'.\x16.\x16.\x16.\x16!\xca\xca.\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''" -"''B'''E''''B'''''''''''''''''''''''22BB2\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\xeb\xeb\xc9\xe8\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''''''\xb9\xb9\xb9\xb9\x10\x10\x10\x10\x10\x10\x10\x10" -"22''''''''''''''''''''''''''''''''''''''''''''''''''222222222222" -"2222E\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4\xb4||||||||||\x10\x10\x10\x10\x10\x10pppppppppppppppppp''''''\xb4\xb4\xb4'\x10\x10\x10\x10" -"||||||||||''''''''''''''''''''''''''''BBBBBmmm\xb4\xb4''''''''''''''''" -"'''''''BBBBBBBBBBB23\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4*****************************\x10\x10\x10" -"BBB2'''''''''''''''''''''''''''''''''''''''''''''''D22BBBB22B222" -'3\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x10\x1d||||||||||\x10\x10\x10\x10\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''''''''BBBBBB22BB22BB\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''B''''''''B2\x10\x10||||||||||\x10\x10\xb4\xb4\xb4\xb4''''''''''''''''\x1d''''''\xeb\xeb\xeb'2\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''p'ppm''pp'''''pp" -"'p'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''\x1d\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''@'''C''''@'''''''''''''''''''''''00@@0\xee\xee\xee\xee\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\xe9\xe9\xc7\xe6\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''''''\xb7\xb7\xb7\xb7\x10\x10\x10\x10\x10\x10\x10\x10" +"00''''''''''''''''''''''''''''''''''''''''''''''''''000000000000" +"0000C\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2\xb2zzzzzzzzzz\x10\x10\x10\x10\x10\x10nnnnnnnnnnnnnnnnnn''''''\xb2\xb2\xb2'\x10\x10\x10\x10" +"zzzzzzzzzz''''''''''''''''''''''''''''@@@@@kkk\xb2\xb2''''''''''''''''" +"'''''''@@@@@@@@@@@01\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2(((((((((((((((((((((((((((((\x10\x10\x10" +"@@@0'''''''''''''''''''''''''''''''''''''''''''''''B00@@@@00 at 000" +'1\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x10\x1dzzzzzzzzzz\x10\x10\x10\x10\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''''''''''''''@@@@@@00@@00@@\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'''@''''''''@0\x10\x10zzzzzzzzzz\x10\x10\xb2\xb2\xb2\xb2''''''''''''''''\x1d''''''\xe9\xe9\xe9'0\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''n'nnk''nn'''''nn" +"'n'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''\x1d\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''22B22B22\xb42E\x10\x10||||||||||\x10\x10\x10\x10\x10\x10" +"'''''''''''''''''''''''''''''''''''00 at 00@00\xb20C\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10" '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' -'((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10****************' -'*******\x10\x10\x10\x10*************************************************\x10\x10\x10\x10' +'((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10((((((((((((((((' +'(((((((\x10\x10\x10\x10(((((((((((((((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' @@ -135188,140 +135182,140 @@ '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' -'****************************************************************' -'*******************************************+*******+****+*******' -'**************************************************+*************' -'*****************+*+*****************************************+**' -'**********************************************\x11\x11****************' -'**********************************************\x11\x11****************' -'****************************************************************' -'**************************\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10,V,,,,,,,,,,\xd5,,,,,,,,,,,,,\x10,,,,,\x10,\x10' -',,\x10,,\x10,,,,,,,,,,$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((()((((((()(((()(((((((' +'(((((((((((((((((((((((((((((((((((((((((((((((((()(((((((((((((' +'((((((((((((((((()()((((((((((((((((((((((((((((((((((((((((()((' +'((((((((((((((((((((((((((((((((((((((((((((((\x11\x11((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((\x11\x11((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' +'\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10*T**********\xd3*************\x10*****\x10*\x10' +'**\x10**\x10**********$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$######$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\xc0\x9f' +'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\xbe\x9d' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$##\xc5\xf0\x10\x10' -'8888888888888888\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xc3\xa2\xbc\x10\x10\x10\x10\x10\x10ppppppp\x10\x10\x10\x10\x10\x10\x10\x10\x10\xbc\x9b\x9b\x95\x95\xc3\xa2\xc3\xa2\xc3\xa2\xc3\xa2\xc3\xa2\xc3' -'\xa2\xc3\xa2\xc3\xa2\xbc\xbc\xc3\xa2\xbc\xbc\xbc\xbc\x95\x95\x95\xae\xbc\xae\x10\xbc\xae\xbc\xbc\x9b\xc4\xa3\xc4\xa3\xc4\xa3\xb3\xbc\xbc\xd7\x98\xe5\xe5\xe4\x10\xbc\xcb\xb3\xbc\x10\x10\x10\x10#$#$#\x10#$#$#$#$#$' +'$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$##\xc3\xee\x10\x10' +'6666666666666666\xba\xba\xba\xba\xba\xba\xba\xc1\xa0\xba\x10\x10\x10\x10\x10\x10nnnnnnn\x10\x10\x10\x10\x10\x10\x10\x10\x10\xba\x99\x99\x93\x93\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1' +'\xa0\xc1\xa0\xc1\xa0\xba\xba\xc1\xa0\xba\xba\xba\xba\x93\x93\x93\xac\xba\xac\x10\xba\xac\xba\xba\x99\xc2\xa1\xc2\xa1\xc2\xa1\xb1\xba\xba\xd5\x96\xe3\xe3\xe2\x10\xba\xc9\xb1\xba\x10\x10\x10\x10#$#$#\x10#$#$#$#$#$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x07' -'\x10\xb7\xb7\xb0\xc7\xb0\xb7\xb7\xbe\x9d\xb7\xd4\xab\x96\xab\xabyyyyyyyyyy\xab\xb7\xde\xdd\xde\xb7\xb7//////////////////////////\xbe\xb7\x9d\xce\x92' -'\xce\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbe\xdd\x9d\xdd\xbe\x9d\xb8\xbf\x9e\xb8\xb8%%%%%%%%%%\x1b%%%%%%%%%%%%%%%' +'\x10\xb5\xb5\xae\xc5\xae\xb5\xb5\xbc\x9b\xb5\xd2\xa9\x94\xa9\xa9wwwwwwwwww\xa9\xb5\xdc\xdb\xdc\xb5\xb5--------------------------\xbc\xb5\x9b\xcc\x90' +'\xcc\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbc\xdb\x9b\xdb\xbc\x9b\xb6\xbd\x9c\xb6\xb6%%%%%%%%%%\x1b%%%%%%%%%%%%%%%' '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x1a\x1a%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x10' -'\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%\x10\x10\x10\xc7\xc7\xdd\xce\xee\xc7\xc7\x10\xef\xdf\xdf\xdf\xdf\xef\xef\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x0b\x0b\x0b\xf0\xed\x10\x10' +'\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%\x10\x10\x10\xc5\xc5\xdb\xcc\xec\xc5\xc5\x10\xed\xdd\xdd\xdd\xdd\xed\xed\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x0b\x0b\x0b\xee\xeb\x10\x10' "''''''''''''\x10''''''''''''''''''''''''''\x10'''''''''''''''''''\x10''\x10'" "''''''''''''''\x10\x10''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10" -'\xb4\xb9\xeb\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x8d\x8d\x8d\x8d\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x8d\x10\x10\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebm\x10\x10' +'\xb2\xb7\xe9\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x8b\x8b\x8b\x8b\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x8b\x10\x10\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9k\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "'''''''''''''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''''''''''" "'''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''''\x10\x88\x88\x88\x88\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" -"'\x80''''''''\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''\x10\xb4''''''''''''''''''''''''''''''''" -"''''\x10\x10\x10\x10''''''''\xb4\x80\x80\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -'0000000000000000000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +"'''''''''''''''''''''''''''''''\x10\x86\x86\x86\x86\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" +"'~''''''''~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''\x10\xb2''''''''''''''''''''''''''''''''" +"''''\x10\x10\x10\x10''''''''\xb2~~~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +'........................................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16''''''''''''''''''''''''''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,\x10\x10,\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10,,\x10\x10\x10,\x10\x10,' -',,,,,,,,,,,,,,,,,,,,,,\x10\xbd\x90\x90\x90\x90\x90\x90\x90\x90\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'******\x10\x10*\x10********************************************\x10**\x10\x10\x10*\x10\x10*' +'**********************\x10\xbb\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,\x90\x90\x90\x90\x90\x90\x10\x10\x10\xb9,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10\xbd' +'**********************\x8e\x8e\x8e\x8e\x8e\x8e\x10\x10\x10\xb7**************************\x10\x10\x10\x10\x10\xbb' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',BBB\x10BB\x10\x10\x10\x10\x10BmBp,,,,\x10,,,\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10pCm\x10\x10\x10\x10E' -'\x91\x91\x91\x91\x90\x90\x90\x90\x10\x10\x10\x10\x10\x10\x10\x10\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x10\x10\x10\x10\x10\x10\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x90\x90\xbd' +'*@@@\x10@@\x10\x10\x10\x10\x10 at k@n****\x10***\x10***************************\x10\x10\x10\x10nAk\x10\x10\x10\x10C' +'\x8f\x8f\x8f\x8f\x8e\x8e\x8e\x8e\x10\x10\x10\x10\x10\x10\x10\x10\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\x10\x10\x10\x10\x10\x10\x10*****************************\x8e\x8e\xbb' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\xb9\xb9\xb9\xb9\xb9\xb9\xb9' -',,,,,,,,,,,,,,,,,,,,,,\x10\x10\x90\x90\x90\x90\x90\x90\x90\x90,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10\x90\x90\x90\x90\x90\x90\x90\x90' +'******************************************************\x10\x10\x10\xb7\xb7\xb7\xb7\xb7\xb7\xb7' +'**********************\x10\x10\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e*******************\x10\x10\x10\x10\x10\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'****************************************************************' +'*********\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x84\x84\x84\x84\x84\x84\x84\x84\x84\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x82\x82\x82\x82\x82\x82\x82\x82\x82\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BB2'''''''''''''''''''''''''''''''''''''''''''''222BBBB22ED\xb4\xb4\x08\xb4\xb4" -'\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"@@0'''''''''''''''''''''''''''''''''''''''''''''000@@@@00CB\xb2\xb2\x08\xb2\xb2" +'\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x7f\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80' -'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x7f\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~' +'~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "'''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb44CCC\xeb\xeb\xeb544444\x07\x07\x07\x07\x07\x07\x07\x07mmmmm' -'mmm\xeb\xebpppppmm\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebpppp\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0ppp\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe922AAA\xe9\xe9\xe9322222\x07\x07\x07\x07\x07\x07\x07\x07kkkkk' +'kkk\xe9\xe9nnnnnkk\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9nnnn\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xeennn\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'00000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16000000000000' -'00000000000000\x16\x16\x16\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16000000000000000000000000' -'00\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160\x1000\x10\x100\x10\x1000\x10\x100000\x1000000000\x16\x16\x16\x16\x10\x16\x10\x16\x16\x16' -'\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x1600\x100000\x10\x1000000000\x100000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600\x100000\x10' -'00000\x100\x10\x10\x100000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000' -'000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160000' -'0000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160000000000000000' -'0000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10000000000000000000000000' -'0\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160\x16\x10\x10zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16............' +'..............\x16\x16\x16\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16........................' +'..\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x10..\x10\x10.\x10\x10..\x10\x10....\x10........\x16\x16\x16\x16\x10\x16\x10\x16\x16\x16' +'\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16..\x10....\x10\x10........\x10.......\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..\x10....\x10' +'.....\x10.\x10\x10\x10.......\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16....................' +'......\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16....' +'......................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16................' +'..........\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10........................' +'.\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.\x16\x10\x10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\x10\x10\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xeb\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\xea' -'\x10\x10\xea\x10\x10\x10\xea\x10\x10\x10\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\xea\xea\x10\x10\xea' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\xea\xea\xea\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x84\x84\x84\x84\x84\x84\x84\x84\x84\x84\x84\x10\x10\x10\x10\x10\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe9\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\xe8' +'\x10\x10\xe8\x10\x10\x10\xe8\x10\x10\x10\xe8\xe8\xe8\xe8\xe8\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\xe8\xe8\x10\x10\xe8' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\xe8\xe8\xe8\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' @@ -135372,11 +135366,7 @@ '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'****************************************************************' -'****************************************************************' -'****************+***********************************************' -'****************************************************************' -'******************************\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' +'((((((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' @@ -135388,10 +135378,10 @@ '\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'8888888888888888888888888888888888888888888888888888888888888888' -'8888888888888888888888888888888888888888888888888888888888888888' -'8888888888888888888888888888888888888888888888888888888888888888' -'888888888888888888888888888888888888888888888888\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'6666666666666666666666666666666666666666666666666666666666666666' +'6666666666666666666666666666666666666666666666666666666666666666' +'6666666666666666666666666666666666666666666666666666666666666666' +'666666666666666666666666666666666666666666666666\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' From noreply at buildbot.pypy.org Fri Mar 8 22:48:25 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 8 Mar 2013 22:48:25 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308214825.89A401C39D3@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62250:e61c417b2ead Date: 2013-03-08 13:46 -0800 http://bitbucket.org/pypy/pypy/changeset/e61c417b2ead/ Log: merge default diff --git a/rpython/rlib/unicodedata/generate_unicodedb.py b/rpython/rlib/unicodedata/generate_unicodedb.py --- a/rpython/rlib/unicodedata/generate_unicodedb.py +++ b/rpython/rlib/unicodedata/generate_unicodedb.py @@ -169,6 +169,13 @@ else: table[int(code, 16)].east_asian_width = width + # Expand ranges + for (first, last), char in ranges.iteritems(): + for code in range(first, last + 1): + assert table[code] is None, 'Multiply defined character %04X' % code + + table[code] = char + # Read Derived Core Properties: for line in derived_core_properties_file: line = line.split('#', 1)[0].strip() @@ -190,13 +197,6 @@ continue table[char].properties += (p,) - # Expand ranges - for (first, last), char in ranges.iteritems(): - for code in range(first, last + 1): - assert table[code] is None, 'Multiply defined character %04X' % code - - table[code] = char - defaultChar = Unicodechar(['0000', None, 'Cn'] + [''] * 12) for code in range(len(table)): if table[code] is None: diff --git a/rpython/rlib/unicodedata/test/test_unicodedata.py b/rpython/rlib/unicodedata/test/test_unicodedata.py --- a/rpython/rlib/unicodedata/test/test_unicodedata.py +++ b/rpython/rlib/unicodedata/test/test_unicodedata.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import random import unicodedata @@ -51,6 +52,8 @@ assert unicodedb_5_2_0.isxidcontinue(ord('_')) assert unicodedb_5_2_0.isxidcontinue(ord('0')) assert not unicodedb_5_2_0.isxidcontinue(ord('(')) + oc = ord(u'日') + assert unicodedb_5_2_0.isxidstart(oc) def test_compare_functions(self): def getX(fun, code): diff --git a/rpython/rlib/unicodedata/unicodedb_3_2_0.py b/rpython/rlib/unicodedata/unicodedb_3_2_0.py --- a/rpython/rlib/unicodedata/unicodedb_3_2_0.py +++ b/rpython/rlib/unicodedata/unicodedb_3_2_0.py @@ -16052,9 +16052,8 @@ ('Lo', 'L', 'H', 7170, 0), ('Lo', 'L', 'N', 6146, 0), ('Lo', 'L', 'N', 7170, 0), -('Lo', 'L', 'W', 4098, 0), -('Lo', 'L', 'W', 4162, 0), ('Lo', 'L', 'W', 7170, 0), +('Lo', 'L', 'W', 7234, 0), ('Lo', 'R', 'N', 7170, 0), ('Lt', 'L', 'N', 7186, 0), ('Lu', 'L', 'A', 7178, 0), @@ -16251,144 +16250,144 @@ _db_pgtbl = ( '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x08\x08\x08\x08\x08\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%\x08\x08\x08&\'()*+,,,,,,,,,,,,' ',,,,,,,,,,,,,-./,0,1,,234,,,,,56,,78,,,9,,,,,,,,,,,:,,;,,,,,,,,,' -'<,,,=,,,,,,,>?,,,,,,,,@,,,,,,,,ABBBBC\x08\x08\x08\x08\x08\x08\x08,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,DEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFBGHIJKL' -'\x08\x08\x08MN\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08OP\x08\x08QRST\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'<,,,=,,,,,,,>?,,,,,,,,@,,,,,,,,A,,,,B\x08\x08\x08\x08\x08\x08\x08,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,CDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEE,FGHIJK' +'\x08\x08\x08LM\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08NO\x08\x08PQRS\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,U\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08BBV\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'W\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,T\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08,,U\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'V\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEW' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEW' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x02\x03\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xe2\xaa\xaa\xa2\xb9\xa2\xaa\xaa\xb1\x8f\xaa\xc3\x9b\x86\x9b\x9emmmmmmmmmm\x9b\xaa\xce\xcd\xce\xaa' -'\xaa((((((((((((((((((((((((((\xb1\xaa\x8f\xbe\x83\xbe\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\xb1\xcd\x8f\xcd\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xdf\xa5\xb9\xb9\xb5\xb9\xda\xd6\xbb\xd9\x10\x96\xcd\x88\xd6\xbe\xd1\xc0uu\xbb\x12\xd6\xa6\xbbu\x10\x93{{{\xa5' -"''''''%'''''''''%''''''\xc6%'''''%\x10\x10\x10\x12\x12\x12\x12\x10\x12\x10\x10\x10\x12\x10\x10\x12\x12\x10\x12\x10\x10\x12\x12\x12\xc6\x10\x10\x10\x12\x10\x12\x10\x12" -"'\x10'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x10'\x10'\x12'\x12'\x12'\x10'\x12'\x12'\x12'\x12'\x12%\x10'\x12'\x10'\x12'\x12'\x10%\x10'\x12'\x12\x10'\x12'\x12'\x12%" -"\x10%\x10'\x10'\x12'\x10\x10%\x10'\x10'\x12'\x12%\x10'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12%\x10'\x12'\x10'\x12'\x12'\x12'\x12'\x12'\x12''\x12'\x12'\x12\x12" -"\x12''\x12'\x12''\x12'''\x12\x12''''\x12''\x12'''\x12\x12\x12''\x12''\x12'\x12'\x12''\x12'\x12\x12'\x12''\x12'''\x12'\x12''\x12\x12\x1f'\x12\x12\x12" -"\x1f\x1f\x1f\x1f'$\x12'$\x12'$\x12'\x10'\x10'\x10'\x10'\x10'\x10'\x10'\x10\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12'$\x12'\x12'''\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r\r\r\r\r\r\r" +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x02\x03\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xe1\xa9\xa9\xa1\xb8\xa1\xa9\xa9\xb0\x8e\xa9\xc2\x9a\x85\x9a\x9dllllllllll\x9a\xa9\xcd\xcc\xcd\xa9' +"\xa9''''''''''''''''''''''''''\xb0\xa9\x8e\xbd\x82\xbd\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\xb0\xcc\x8e\xcc\x01" +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xde\xa4\xb8\xb8\xb4\xb8\xd9\xd5\xba\xd8\x10\x95\xcc\x87\xd5\xbd\xd0\xbftt\xba\x12\xd5\xa5\xbat\x10\x92zzz\xa4' +'&&&&&&$&&&&&&&&&$&&&&&&\xc5$&&&&&$\x10\x10\x10\x12\x12\x12\x12\x10\x12\x10\x10\x10\x12\x10\x10\x12\x12\x10\x12\x10\x10\x12\x12\x12\xc5\x10\x10\x10\x12\x10\x12\x10\x12' +'&\x10&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x10&\x10&\x12&\x12&\x12&\x10&\x12&\x12&\x12&\x12&\x12$\x10&\x12&\x10&\x12&\x12&\x10$\x10&\x12&\x12\x10&\x12&\x12&\x12$' +'\x10$\x10&\x10&\x12&\x10\x10$\x10&\x10&\x12&\x12$\x10&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12$\x10&\x12&\x10&\x12&\x12&\x12&\x12&\x12&\x12&&\x12&\x12&\x12\x12' +'\x12&&\x12&\x12&&\x12&&&\x12\x12&&&&\x12&&\x12&&&\x12\x12\x12&&\x12&&\x12&\x12&\x12&&\x12&\x12\x12&\x12&&\x12&&&\x12&\x12&&\x12\x12\x1f&\x12\x12\x12' +'\x1f\x1f\x1f\x1f&#\x12&#\x12&#\x12&\x10&\x10&\x10&\x10&\x10&\x10&\x10&\x10\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12&#\x12&\x12&&&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' -'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\x19\x19\x19\x19\x19\x19\x19\x19\x19\xbd\xbd\x19\x19\x19\x19\x19' -'\x19\x19\xbd\xbd\xbb\xbd\xbd\xbb\xbd\xbb\xbb\xbb\xbd\xbb\xbd\xbd\x15\x19\xbd\xbd\xbd\xbd\xbd\xbd\xbb\xbb\xbb\xbb\xbd\xbb\xbd\xbb\x19\x19\x19\x19\x19\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x19\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'222222222222222222222311113011111//1111//11111111111.....1111222' -'222226211122211-\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r5542222222222222\r\r\r\r\xbd\xbd\r\r\r\r\x18\r\r\r\xa9\r' -"\r\r\r\r\xbd\xbd'\xa9'''\r'\r''\x12%%%%%%%%%%%%%%%%%\r%%%%%%%''\x12\x12\x12\x12\x12\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10\x12\x10\x10\x10\x10\x10\x10\x10\x12\x12\x12\x12\x12\r\x12\x12'''\x12\x12\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12\x12\x12\x12'\x12\xcb\r\r\r\r\r\r\r\r\r" -"'%''''''''''''''%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12\xd4cccc\r,,'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"''\x12'\x12'\x12'\x12'\x12'\x12'\x12\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r'\x12\r\r\r\r\r\r" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r'''''''''''''''" -"'''''''''''''''''''''''\r\r\x19\xa4\xa4\xa4\xa4\xa4\xa4\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -'\x12\x12\x12\x12\x12\x12\x12\x12\r\xa4\x89\r\r\r\r\r\r`cccc`ccca`cccccc\r`````cc`ccabc;<=>?@ABCD\rEFG\xacH' -'\xacIJ\xacc\r\r\r\r\r\r\r\r\r\r\r###########################\r\r\r\r\r###\xac\xac\r\r\r\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\x9a\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x97\r\r\r\x97\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r' -'\x14\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1cLMNOPQRScc`\r\r\r\r\r\r\r\r\r\rjjjjjjjjjj\xa1\x98\x98\x97\x1c\x1cT\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\x19\x19\x19\x19\x19\x19\x19\x19\x19\xbc\xbc\x19\x19\x19\x19\x19' +'\x19\x19\xbc\xbc\xba\xbc\xbc\xba\xbc\xba\xba\xba\xbc\xba\xbc\xbc\x15\x19\xbc\xbc\xbc\xbc\xbc\xbc\xba\xba\xba\xba\xbc\xba\xbc\xba\x19\x19\x19\x19\x19\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\x19\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'111111111111111111111200002/00000..0000..00000000000-----0000111' +'111115100011100,\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r4431111111111111\r\r\r\r\xbc\xbc\r\r\r\r\x18\r\r\r\xa8\r' +'\r\r\r\r\xbc\xbc&\xa8&&&\r&\r&&\x12$$$$$$$$$$$$$$$$$\r$$$$$$$&&\x12\x12\x12\x12\x12\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x12\x10\x10\x10\x10\x10\x10\x10\x12\x12\x12\x12\x12\r\x12\x12&&&\x12\x12\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12\x12\x12\x12&\x12\xca\r\r\r\r\r\r\r\r\r' +'&$&&&&&&&&&&&&&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12\xd3bbbb\r++&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r&\x12\r\r\r\r\r\r' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r&&&&&&&&&&&&&&&' +'&&&&&&&&&&&&&&&&&&&&&&&\r\r\x19\xa3\xa3\xa3\xa3\xa3\xa3\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\r\xa3\x88\r\r\r\r\r\r_bbbb_bbb`_bbbbbb\r_____bb_bb`ab:;<=>?@ABC\rDEF\xabG' +'\xabHI\xabb\r\r\r\r\r\r\r\r\r\r\r"""""""""""""""""""""""""""\r\r\r\r\r"""\xab\xab\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\x99\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x96\r\r\r\x96\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r' +'\x14\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1cKLMNOPQRbb_\r\r\r\r\r\r\r\r\r\riiiiiiiiii\xa0\x97\x97\x96\x1c\x1cS\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x97\x1cccccccc\x04,cccc`c\x14\x14cc\xd9`cc`\r\rllllllllll\x1c\x1c\x1c\xd0\xd0\r' -'\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\r\x05\x1cU\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\rc`cc`cc```c``c`c' -'cc`c`c`c`cc\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c77777777777\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x96\x1cbbbbbbb\x04+bbbb_b\x14\x14bb\xd8_bb_\r\rkkkkkkkkkk\x1c\x1c\x1c\xcf\xcf\r' +'\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\r\x05\x1cT\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\rb_bb_bb___b__b_b' +'bb_b_b_b_bb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c66666666666\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r77)\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r9\x1f))' -')77777777)))):\r\r\x1fc`cc\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77\xa4\xa4nnnnnnnnnn\xa4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r7))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r\r\x1f\x1f\x1f\x1f\r\r9\r))' -')7777\r\r))\r\r)):\r\r\r\r\r\r\r\r\r)\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f77\r\rnnnnnnnnnn\x1f\x1f\xb8\xb8yyyyxy\xd4\r\r\r\r\r' -'\r\r7\r\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\r9\r))' -')77\r\r\r\r77\r\r77:\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\r\r\r\r\r\r\rnnnnnnnnnn77\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' -'\r77)\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r9\x1f))' -')77777\r77)\r)):\r\r\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\r\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r7))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\r\r9\x1f)7' -')777\r\r\r))\r\r)):\r\r\r\r\r\r\r\r7)\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f\r\r\r\rnnnnnnnnnn\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r7\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\r\x1f\r\x1f\x1f\r\r\r\x1f\x1f\r\r\r\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\r\r\r))' -'7))\r\r\r)))\r))):\r\r\r\r\r\r\r\r\r)\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rnnnnnnnnnyyy\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r)))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r77' -'7))))\r777\r777:\r\r\r\r\r\r\rVW\r\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r)7' -')))))\r7))\r))7:\r\r\r\r\r\r\r))\r\r\r\r\r\r\r\x1f\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r))' -')777\r\r)))\r))):\r\r\r\r\r\r\r\r\r)\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r:\r\r\r\r)))777\r7\r))))))))\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r))\xa4\r\r\r\r\r\r\r\r\r\r\r' -'\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f7\x1f\x1e7777XX:\r\r\r\r\xb8' -'\x1f\x1f\x1f\x1f\x1f\x1f\x197YYYY777\xa4nnnnnnnnnn\xa4\xa4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\x1f\x1f\r\x1f\r\r\x1f\x1f\r\x1f\r\r\x1f\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\r\x1f\r\r\x1f\x1f\r\x1f\x1f\x1f\x1f7\x1f\x1e7777ZZ\r77\x1f\r\r' -'\x1f\x1f\x1f\x1f\x1f\r\x19\r[[[[77\r\rnnnnnnnnnn\r\r\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\xd4\xd4\xd4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xd4\xd4\xd4\xd4\xd4``\xd4\xd4\xd4\xd4\xd4\xd4nnnnnnnnnnyyyyyyyyyy\xd4`\xd4`\xd4_\xaf\x8d\xaf\x8d))' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\\]7^77777]]]]7)' -']7cc:\xa4cc\x1f\x1f\x1f\x1f\r\r\r\r77777777\r777777777777777777777777777777777777\r\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4`\xd4\xd4\xd4\xd4\xd4\xd4\r\r\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r)7777)7\r\r\r79):\r\r\r\r\r\r' -'nnnnnnnnnn\xa4\xa4\xa4\xa4\xa4\xa4\x1f\x1f\x1f\x1f\x1f\x1f))77\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r''''''''''''''''''''''''''''''''" -"''''''\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\xa4\r\r\r\r" -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""\r\r\r\r\r"\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\r66(\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r8\x1f((' +'(66666666((((9\r\r\x1fb_bb\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f66\xa3\xa3mmmmmmmmmm\xa3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r6((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r\r\x1f\x1f\x1f\x1f\r\r8\r((' +'(6666\r\r((\r\r((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f66\r\rmmmmmmmmmm\x1f\x1f\xb7\xb7xxxxwx\xd3\r\r\r\r\r' +'\r\r6\r\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\r8\r((' +'(66\r\r\r\r66\r\r669\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\r\r\r\r\r\r\rmmmmmmmmmm66\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' +'\r66(\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r8\x1f((' +'(66666\r66(\r((9\r\r\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\r\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r6((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\r\r8\x1f(6' +'(666\r\r\r((\r\r((9\r\r\r\r\r\r\r\r6(\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f\r\r\r\rmmmmmmmmmm\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r6\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\r\x1f\r\x1f\x1f\r\r\r\x1f\x1f\r\r\r\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\r\r\r((' +'6((\r\r\r(((\r(((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rmmmmmmmmmxxx\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r(((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r66' +'6((((\r666\r6669\r\r\r\r\r\r\rUV\r\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r(6' +'(((((\r6((\r((69\r\r\r\r\r\r\r((\r\r\r\r\r\r\r\x1f\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r((' +'(666\r\r(((\r(((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r9\r\r\r\r(((666\r6\r((((((((\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r((\xa3\r\r\r\r\r\r\r\r\r\r\r' +'\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f6\x1f\x1e6666WW9\r\r\r\r\xb7' +'\x1f\x1f\x1f\x1f\x1f\x1f\x196XXXX666\xa3mmmmmmmmmm\xa3\xa3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\x1f\x1f\r\x1f\r\r\x1f\x1f\r\x1f\r\r\x1f\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\r\x1f\r\r\x1f\x1f\r\x1f\x1f\x1f\x1f6\x1f\x1e6666YY\r66\x1f\r\r' +'\x1f\x1f\x1f\x1f\x1f\r\x19\rZZZZ66\r\rmmmmmmmmmm\r\r\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\xd3\xd3\xd3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xd3\xd3\xd3\xd3\xd3__\xd3\xd3\xd3\xd3\xd3\xd3mmmmmmmmmmxxxxxxxxxx\xd3_\xd3_\xd3^\xae\x8c\xae\x8c((' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r[\\6]66666\\\\\\\\6(' +'\\6bb9\xa3bb\x1f\x1f\x1f\x1f\r\r\r\r66666666\r666666666666666666666666666666666666\r\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3_\xd3\xd3\xd3\xd3\xd3\xd3\r\r\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r(6666(6\r\r\r68(9\r\r\r\r\r\r' +'mmmmmmmmmm\xa3\xa3\xa3\xa3\xa3\xa3\x1f\x1f\x1f\x1f\x1f\x1f((66\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&' +'&&&&&&\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\xa3\r\r\r\r' +' ' +' \r\r\r\r\r \x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' @@ -16396,7 +16395,7 @@ '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r' '\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4nnnnnnnnnyyyyyyyyyyy\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3mmmmmmmmmxxxxxxxxxxx\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' '\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' @@ -16408,93 +16407,93 @@ '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa4\xa4\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r' -'\xe1\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xaf\x8d\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa4\xa4\xa4qqq\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f77:\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77:\xa4\xa4\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r77\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f)))7777777))' -'))))))7))777777777:7\xa4\xa4\xa4\x19\xa4\xa4\xa4\xb8\x1f\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xa9\xa9\xa9\xa9\xa9\xa9\x89\xa9\xa9\xa9\xa9777\x05\rnnnnnnnnnn\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa3\xa3\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r' +'\xe0\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xae\x8c\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa3\xa3\xa3ppp\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f669\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f669\xa3\xa3\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f66\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r66\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f(((6666666((' +'((((((6((66666666696\xa3\xa3\xa3\x19\xa3\xa3\xa3\xb7\x1f\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xa8\xa8\xa8\xa8\xa8\xa8\x88\xa8\xa8\xa8\xa8666\x05\rmmmmmmmmmm\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x19\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fa\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r" -"\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\r\r''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\x12\x12''''''''" -"\x12\x12\x12\x12\x12\x12\r\r''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12\r'\r'\r'\r'\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r" -"\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\r\x12\x12''''$\xbd\x12\xbd" -"\xbd\xbd\x12\x12\x12\r\x12\x12''''$\xbd\xbd\xbd\x12\x12\x12\x12\r\r\x12\x12''''\r\xbd\xbd\xbd\x12\x12\x12\x12\x12\x12\x12\x12'''''\xbd\xbd\xbd\r\r\x12\x12\x12\r\x12\x12''''$\xbd\xbd\r" -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xde\x05\x05\x06\n\x88\x89\x89\x88\x88\x88\xa5\xa9\x94\x92\xaf\x95\x94\x92\xaf\x95\xa5\xa5\xa5\xa9\xa5\xa5\xa5\xa5\xdc\xdd\x07\x0b\t\x08\x0c\xe1\x9f\xa1\x9f\x9f\xa1\xa5\xa9\xa9\xa9\x96\x93\xa5\xa9\xa9\xa5\x82' -'\x82\xa9\xa9\xa9\xcb\xb0\x8e\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xcb\r\r\r\r\xa9\r\r\r\r\r\r\r\xe1\x05\x05\x05\x05\r\r\r\r\r\r\x05\x05\x05\x05\x05\x05w\x12\r\ruwwwww\xc2\xc2\xcb\xb0\x8e\x10' -'wuuuuwwwww\xc2\xc2\xcb\xb0\x8e\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb8\xb8\xb5\xb8\xb8\xb8\xb8\xb8\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rcc88cccc888cc,,,,c,,,88c`c8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"\xd9\xd9'\xd6\xd9\xd6\xd9'\xd9\xd6\x12'''\x12\x12'''\x10\xd9'\xd6\xd9\xd9'''''\xd9\xd9\xd9\xd6\xd6\xd9'\xd9%\xd9'\xd9'%''\xd2\x12''\xd9'\x12\x1f\x1f\x1f\x1f\x12\xd9\r\r\x12''" -"\xcc\xcb\xcb\xcb\xcb'\x12\x12\x12\x12\xd9\xcb\r\r\r\r\r\r\r{{}}}}}}{{{{}ooooooooooooqqqqooooooooooqqqqqq" -'qqqp\r\r\r\r\r\r\r\r\r\r\r\r\xc6\xc6\xc6\xc6\xc6\xd6\xd6\xd6\xd6\xd6\xcb\xcb\xd9\xd9\xd9\xd9\xcb\xd9\xd9\xcb\xd9\xd9\xcb\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xd9\xd9\xc6\xd9\xc6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xc6\xcc\xc7\xc7\xcc\xcb\xcb\xc6\xc7\xcc\xcc\xc7\xcc\xcc\xcb\xc6\xcb\xc7\xc2\xc2\xcb\xc7\xcc\xcb\xcb\xcb\xc7\xcc\xcc\xc7\xc6\xc7\xc7\xcc\xcc\xc6\xcc\xc6\xcc\xc6\xc6\xc6\xc6\xc7\xc7\xcc\xc7\xcc\xcc\xcc\xcc\xcc\xc6\xc6\xc6\xc6\xcb\xcc\xcb\xcc\xc7\xc7\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xc7\xcc\xcc\xcc\xc7\xcb\xcb\xcb\xcb\xcb\xc7\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xc7\xc6\xcc\xcb\xc7\xc7\xc7\xc7\xcc\xcc\xc7\xc7\xcb\xcb\xc7\xc7\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xc7\xc7\xcc\xcc\xc7\xc7\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xc6\xcb\xcb\xcc\xc6\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xc6\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xc7' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcc\xcc\xcc\xcc\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcc\xcc\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xb3\x91\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd9\xcb\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd4\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xaf\x8d\xa9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rtttttttttssssssssssstttttttttsss' -'sssssssstttttttttsssssssssss\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' -'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3v{{{{{{{{{{|||||||||{\r' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd6\xc6\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9' -'\xd6\xc6\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd9\xd9\xd6\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd9\xd9\r\r\xd9\xd9\r\xd9\xd9\xd9\xd6\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd6\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd6\xd6\xd6\xd9\xd6\xd6\xd6\xd6\xd9\xd6\xd6\xd9\xc6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12\x12\x12\x12\x12\x12\r\r\r\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r' +'\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\r\r&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&' +'\x12\x12\x12\x12\x12\x12\r\r&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12\r&\r&\r&\r&\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r' +'\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\r\x12\x12&&&&#\xbc\x12\xbc' +'\xbc\xbc\x12\x12\x12\r\x12\x12&&&&#\xbc\xbc\xbc\x12\x12\x12\x12\r\r\x12\x12&&&&\r\xbc\xbc\xbc\x12\x12\x12\x12\x12\x12\x12\x12&&&&&\xbc\xbc\xbc\r\r\x12\x12\x12\r\x12\x12&&&&#\xbc\xbc\r' +'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xdd\x05\x05\x06\n\x87\x88\x88\x87\x87\x87\xa4\xa8\x93\x91\xae\x94\x93\x91\xae\x94\xa4\xa4\xa4\xa8\xa4\xa4\xa4\xa4\xdb\xdc\x07\x0b\t\x08\x0c\xe0\x9e\xa0\x9e\x9e\xa0\xa4\xa8\xa8\xa8\x95\x92\xa4\xa8\xa8\xa4\x81' +'\x81\xa8\xa8\xa8\xca\xaf\x8d\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xca\r\r\r\r\xa8\r\r\r\r\r\r\r\xe0\x05\x05\x05\x05\r\r\r\r\r\r\x05\x05\x05\x05\x05\x05v\x12\r\rtvvvvv\xc1\xc1\xca\xaf\x8d\x10' +'vttttvvvvv\xc1\xc1\xca\xaf\x8d\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb4\xb7\xb7\xb7\xb7\xb7\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rbb77bbbb777bb++++b+++77b_b7\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8&\xd5\xd8\xd5\xd8&\xd8\xd5\x12&&&\x12\x12&&&\x10\xd8&\xd5\xd8\xd8&&&&&\xd8\xd8\xd8\xd5\xd5\xd8&\xd8$\xd8&\xd8&$&&\xd1\x12&&\xd8&\x12\x1f\x1f\x1f\x1f\x12\xd8\r\r\x12&&' +'\xcb\xca\xca\xca\xca&\x12\x12\x12\x12\xd8\xca\r\r\r\r\r\r\rzz||||||zzzz|nnnnnnnnnnnnppppnnnnnnnnnnpppppp' +'pppo\r\r\r\r\r\r\r\r\r\r\r\r\xc5\xc5\xc5\xc5\xc5\xd5\xd5\xd5\xd5\xd5\xca\xca\xd8\xd8\xd8\xd8\xca\xd8\xd8\xca\xd8\xd8\xca\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xd8\xd8\xc5\xd8\xc5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xc5\xcb\xc6\xc6\xcb\xca\xca\xc5\xc6\xcb\xcb\xc6\xcb\xcb\xca\xc5\xca\xc6\xc1\xc1\xca\xc6\xcb\xca\xca\xca\xc6\xcb\xcb\xc6\xc5\xc6\xc6\xcb\xcb\xc5\xcb\xc5\xcb\xc5\xc5\xc5\xc5\xc6\xc6\xcb\xc6\xcb\xcb\xcb\xcb\xcb\xc5\xc5\xc5\xc5\xca\xcb\xca\xcb\xc6\xc6\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xc6\xcb\xcb\xcb\xc6\xca\xca\xca\xca\xca\xc6\xcb\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xc6\xc5\xcb\xca\xc6\xc6\xc6\xc6\xcb\xcb\xc6\xc6\xca\xca\xc6\xc6\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xc6\xc6\xcb\xcb\xc6\xc6\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xca\xca\xc5\xca\xca\xcb\xc5\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xc5\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xc6' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xcb\xcb\xcb\xcb\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xcb\xcb\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xb2\x90\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd8\xca\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd3\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xae\x8c\xa8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rsssssssssrrrrrrrrrrrsssssssssrrr' +'rrrrrrrrsssssssssrrrrrrrrrrr\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2uzzzzzzzzzz{{{{{{{{{z\r' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd5\xc5\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8' +'\xd5\xc5\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd8\xd8\xd5\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca' +'\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd8\xd8\r\r\xd8\xd8\r\xd8\xd8\xd8\xd5\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd5\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd5\xd5\xd5\xd8\xd5\xd5\xd5\xd5\xd8\xd5\xd5\xd8\xc5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\r\xd9\xd9\xd9\xd9\r\r\r\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e|||||||||{' -'~~~~~~~~~}~~~~~~~~~}\xd9\r\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xb1\x8f\xb1\x8f\xb1\x8f\r\r\r\r\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcb\xcb\xcb\xb0\x8e\xb1\x8f\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcb\xcb\xb0\x8e\xb0\x8e\xcc\xcb\xcb\xcb\xcb\xcc\xcb\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xb0\x8e\xcb\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcb\xcc\xcb\xcb\xcc\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcb\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcb\xcb' +'\r\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\r\xd8\xd8\xd8\xd8\r\r\r\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d{{{{{{{{{z' +'}}}}}}}}}|}}}}}}}}}|\xd8\r\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xca\xca\xca\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xb0\x8e\xb0\x8e\xb0\x8e\r\r\r\r\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xaf\x8d\xb0\x8e\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xca\xca\xca\xca\xca\xca\xca' +'\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xca\xca\xaf\x8d\xaf\x8d\xcb\xca\xca\xca\xca\xcb\xca\xcb\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xaf\x8d\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xcb\xcb\xca\xca\xcb\xca\xcb\xca\xca\xcb\xca\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xca\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xca\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca\xca\xca\xca\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xcb\xca\xca' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r' -'\xe0\xab\xab\xab\xdb\x1a"r\xb3\x91\xb3\x91\xb3\x91\xb3\x91\xb3\x91\xdb\xdb\xb3\x91\xb3\x91\xb3\x91\xb3\x91\x8a\xb2\x90\x90\xdbrrrrrrrrrehifgg\x8a\x1a\x1a\x1a\x1a\x1a\xdb\xdbrrr\x1a"\xab\xdb\xd9' -'\r"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""""""""""""\r\rdd\xbf\xbf\x1a\x1a"\x8a"""""""""""""""""""""""""""""""' -'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""\x84\x1a\x1a\x1a"' -'\r\r\r\r\r""""""""""""""""""""""""""""""""""""""""\r\r\r\r"""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""""\r\xd5\xd5zzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5""""""""""""""""""""""""\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r""""""""""""""""' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\rzzzzzzzzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\r\r\r\r\r\r\r\r\r\r\r\r\r\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\xd5' -'zzzzzzzzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\r\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\r\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r' +'\xdf\xaa\xaa\xaa\xda\x1a q\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xda\xda\xb2\x90\xb2\x90\xb2\x90\xb2\x90\x89\xb1\x8f\x8f\xdaqqqqqqqqqdgheff\x89\x1a\x1a\x1a\x1a\x1a\xda\xdaqqq\x1a \xaa\xda\xd8' +'\r ' +' \r\rcc\xbe\xbe\x1a\x1a \x89 ' +' \x83\x1a\x1a\x1a ' +'\r\r\r\r\r \r\r\r\r ' +' ' +' \r\xd4\xd4yyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4 \r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r ' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\ryyyyyyyyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r~~~~~~~~~~~~~~~\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\xd4' +'yyyyyyyyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4~~~~~~~~~~~~~~~' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r' ' ' ' ' ' ' @@ -16583,14 +16582,10 @@ ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""\r\r\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' ' +' ' +' \r\r\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' ' ' ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' @@ -16603,67 +16598,67 @@ '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' -'""""""""""""""""""""""""""""""""""""""""""""""\r\r""""""""""""""""' -'"""""""""""""""""""""""""""""""""""""""""""\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' \r\r ' +' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\x12\x12\x12\x12\x12\r\r\r\r\r#K##########\xc2#############\r#####\r#\r' -'##\r##\r##########\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' +'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\x12\x12\x12\x12\x12\r\r\r\r\r"J""""""""""\xc1"""""""""""""\r"""""\r"\r' +'""\r""\r""""""""""\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\xaf\x8d' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\xae\x8c' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\xb4\r\r\r' -'----------------\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rcccc\r\r\r\r\r\r\r\r\r\r\r\r\xab\x8a\x8a\x84\x84\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2' -'\x90\xb2\x90\xb2\x90\xab\xab\r\r\xab\xab\xab\xab\x84\x84\x84\x9c\xab\x9c\r\xab\x9c\xab\xab\x8a\xb2\x90\xb2\x90\xb2\x90\xa3\xab\xab\xc4\x87\xcf\xcf\xcf\r\xab\xba\xa3\xab\r\r\r\r\x1b\x1c\x1b\x1c\x1b\r\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\xb3\r\r\r' +',,,,,,,,,,,,,,,,\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rbbbb\r\r\r\r\r\r\r\r\r\r\r\r\xaa\x89\x89\x83\x83\xb1\x8f\xb1\x8f\xb1\x8f\xb1\x8f\xb1\x8f\xb1' +'\x8f\xb1\x8f\xb1\x8f\xaa\xaa\r\r\xaa\xaa\xaa\xaa\x83\x83\x83\x9b\xaa\x9b\r\xaa\x9b\xaa\xaa\x89\xb1\x8f\xb1\x8f\xb1\x8f\xa2\xaa\xaa\xc3\x86\xce\xce\xce\r\xaa\xb9\xa2\xaa\r\r\r\r\x1b\x1c\x1b\x1c\x1b\r\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\x05' -'\r\xa7\xa7\xa0\xb6\xa0\xa7\xa7\xad\x8b\xa7\xc1\x99\x85\x99\x9dkkkkkkkkkk\x99\xa7\xc9\xc8\xc9\xa7\xa7&&&&&&&&&&&&&&&&&&&&&&&&&&\xad\xa7\x8b\xbc\x80' -'\xbc\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xad\xc8\x8b\xc8\xad\x8b\xa8\xae\x8c\xa8\x81\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x17\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' +'\r\xa6\xa6\x9f\xb5\x9f\xa6\xa6\xac\x8a\xa6\xc0\x98\x84\x98\x9cjjjjjjjjjj\x98\xa6\xc8\xc7\xc8\xa6\xa6%%%%%%%%%%%%%%%%%%%%%%%%%%\xac\xa6\x8a\xbb\x7f' +'\xbb\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xac\xc7\x8a\xc7\xac\x8a\xa7\xad\x8b\xa7\x80\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x17\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' '\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\r' -'\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\r\r\r\xb6\xb6\xc8\xbc\xd7\xb6\xb6\r\xd8\xca\xca\xca\xca\xd8\xd8\r\r\r\r\r\r\r\r\r\r\x05\x05\x05\xd9\xd6\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\ryyyy\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fp\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\r\r\r\xb5\xb5\xc7\xbb\xd6\xb5\xb5\r\xd7\xc9\xc9\xc9\xc9\xd7\xd7\r\r\r\r\r\r\r\r\r\r\x05\x05\x05\xd8\xd5\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\rxxxx\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fo\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"''''''''''''''''''''''''''''''''''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" +'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4**888\xd4\xd4\xd4+*****\x05\x05\x05\x05\x05\x05\x05\x05`````' -'```\xd4\xd4ccccc``\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4cccc\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''" -"''''''''''''''\x12\x12\x12\x12\x12\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''" -"''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12'\r''\r\r'\r\r''\r\r''''\r''''''''\x12\x12\x12\x12\r\x12\r\x12\x12\x12" -"\x12\r\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12''\r''''\r\r''''''''\r'''''''\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''\r''''\r" -"'''''\r'\r\r\r'''''''\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''" -"''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''" -"''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''" -"''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r''''''''''''''''''''''''" -"'\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -'\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12\r\r\r\rllllllllllllllllllllllllllllllllllllllllllllllllll' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\r\r\r\r\r\r\r' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3))777\xd3\xd3\xd3*)))))\x05\x05\x05\x05\x05\x05\x05\x05_____' +'___\xd3\xd3bbbbb__\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3bbbb\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&' +'&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&' +'&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&\r&&\r\r&\r\r&&\r\r&&&&\r&&&&&&&&\x12\x12\x12\x12\r\x12\r\x12\x12\x12' +'\x12\r\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12&&\r&&&&\r\r&&&&&&&&\r&&&&&&&\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&\r&&&&\r' +'&&&&&\r&\r\r\r&&&&&&&\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&' +'&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&' +'&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&' +'&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r&&&&&&&&&&&&&&&&&&&&&&&&' +'&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12\r\r\r\rkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' ' ' ' ' ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'""""""""""""""""""""""""""""""\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' diff --git a/rpython/rlib/unicodedata/unicodedb_5_2_0.py b/rpython/rlib/unicodedata/unicodedb_5_2_0.py --- a/rpython/rlib/unicodedata/unicodedb_5_2_0.py +++ b/rpython/rlib/unicodedata/unicodedb_5_2_0.py @@ -134550,8 +134550,6 @@ ('Lo', 'L', 'H', 7170, 0), ('Lo', 'L', 'N', 6146, 0), ('Lo', 'L', 'N', 7170, 0), -('Lo', 'L', 'W', 4098, 0), -('Lo', 'L', 'W', 4162, 0), ('Lo', 'L', 'W', 7170, 0), ('Lo', 'L', 'W', 7234, 0), ('Lo', 'R', 'N', 7170, 0), @@ -134764,155 +134762,155 @@ _db_pgtbl = ( '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123455565575555' '555555555555589:5;5<55=5>55555?@55AB555C5555555D555E55F555555555' -'G555H5555555IJ55555555K55555555LMNNNO\x15PQRSTU55555555555555555555' -'55555555555555555555555VWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXYZ[\\]^_' -'`abcdeeefghijekeleeeeeeeeeeeeeee\x15\x15\x15mneeeeeeeeeee\x15\x15\x15\x15oeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeepqrstuvweeeeeeeeeeeeeeeeeeeeeeeexyzeeeeeeeeeeeee' -'{|5555555}~\x7f55555555555555555555555\x8055555\x8155555555555555555\x825555' -'5555555555555555555555555555555555\x8355555555555555555555555555555' -'55555555555555555555555555555555555555\x845555555555555555\x85\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x87N\x88\x86\x86\x86\x86\x89' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x89' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'\x8a\x8beeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x8c' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x8c' +'G555H5555555IJ55555555K55555555LM555N\x15OPQRST55555555555555555555' +'55555555555555555555555UVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWXYZ[\\]^' +'_`abcdddefghidjdkddddddddddddddd\x15\x15\x15lmddddddddddd\x15\x15\x15\x15nddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'ddddddddddddddddopqrstuvddddddddddddddddddddddddwxyddddddddddddd' +'z{5555555|}~55555555555555555555555\x7f55555\x8055555555555555555\x815555' +'5555555555555555555555555555555555\x8255555555555555555555555555555' +'55555555555555555555555555555555555555\x835555555555555555\x84\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x7f5\x86\x85\x85\x85\x85\x87' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x87' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'\x88\x89dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\x8a' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\x8a' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xf9\xbb\xbb\xb2\xca\xb2\xbb\xbb\xc2\xa1\xbb\xd6\xad\x97\xad\xad{{{{{{{{{{\xad\xbb\xe3\xe2\xe3\xbb' -'\xbb11111111111111111111111111\xc2\xbb\xa1\xd0\x94\xd0\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc2\xe2\xa1\xe2\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf6\xb5\xca\xca\xc6\xca\xf2\xed\xcd\xf0\x14\xa8\xe2\x06\xed\xd0\xe7\xd8\x86\x86\xcd\x16\xed\xb6\xcd\x86\x14\xa5\x8b\x8b\x8b\xb5' -'000000.000000000.000000\xdb.00000.\x14\x14\x14\x16\x16\x16\x16\x14\x16\x14\x14\x14\x16\x14\x14\x16\x16\x14\x16\x14\x14\x16\x16\x16\xdb\x14\x14\x14\x16\x14\x16\x14\x16' -'0\x140\x160\x160\x160\x160\x160\x160\x160\x140\x140\x160\x160\x160\x140\x160\x160\x160\x160\x16.\x140\x160\x140\x160\x160\x14.\x140\x160\x16\x140\x160\x160\x16.' -'\x14.\x140\x140\x160\x14\x14.\x140\x140\x160\x16.\x140\x160\x160\x160\x160\x160\x160\x160\x160\x16.\x140\x160\x140\x160\x160\x160\x160\x160\x1600\x160\x160\x16\x16' -"\x1600\x160\x1600\x16000\x16\x160000\x1600\x16000\x16\x16\x1600\x1600\x160\x160\x1600\x160\x16\x160\x1600\x16000\x160\x1600\x16\x16'0\x16\x16\x16" -"''''0-\x160-\x160-\x160\x140\x140\x140\x140\x140\x140\x140\x14\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x160-\x160\x16000\x160\x160\x160\x16" -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x16\x16\x1600\x1600\x16' -'\x160\x160000\x160\x160\x160\x160\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xf7\xb9\xb9\xb0\xc8\xb0\xb9\xb9\xc0\x9f\xb9\xd4\xab\x95\xab\xabyyyyyyyyyy\xab\xb9\xe1\xe0\xe1\xb9' +'\xb9//////////////////////////\xc0\xb9\x9f\xce\x92\xce\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc0\xe0\x9f\xe0\x01' +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf4\xb3\xc8\xc8\xc4\xc8\xf0\xeb\xcb\xee\x14\xa6\xe0\x06\xeb\xce\xe5\xd6\x84\x84\xcb\x16\xeb\xb4\xcb\x84\x14\xa3\x89\x89\x89\xb3' +'......,.........,......\xd9,.....,\x14\x14\x14\x16\x16\x16\x16\x14\x16\x14\x14\x14\x16\x14\x14\x16\x16\x14\x16\x14\x14\x16\x16\x16\xd9\x14\x14\x14\x16\x14\x16\x14\x16' +'.\x14.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x14.\x14.\x16.\x16.\x16.\x14.\x16.\x16.\x16.\x16.\x16,\x14.\x16.\x14.\x16.\x16.\x14,\x14.\x16.\x16\x14.\x16.\x16.\x16,' +'\x14,\x14.\x14.\x16.\x14\x14,\x14.\x14.\x16.\x16,\x14.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16,\x14.\x16.\x14.\x16.\x16.\x16.\x16.\x16.\x16..\x16.\x16.\x16\x16' +"\x16..\x16.\x16..\x16...\x16\x16....\x16..\x16...\x16\x16\x16..\x16..\x16.\x16.\x16..\x16.\x16\x16.\x16..\x16...\x16.\x16..\x16\x16'.\x16\x16\x16" +"''''.+\x16.+\x16.+\x16.\x14.\x14.\x14.\x14.\x14.\x14.\x14.\x14\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16.+\x16.\x16...\x16.\x16.\x16.\x16" +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16\x16\x16..\x16..\x16' +'\x16.\x16....\x16.\x16.\x16.\x16.\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d!!\x1d\x1d\x1d\x1d\x1d" -'\x1d\x1d\xcf\xcf\xcd\xcf!\x1f!\x1f\x1f\x1f!\x1f!!\x19\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcd\xcd\xcd\xcd\xcf\xcd\xcf\xcd\x1d\x1d\x1d\x1d\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcf!\xcf\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' -'=====================><<<<>;<<<<<::<<<<::<<<<<<<<<<<99999<<<<===' -'=====A=<<<===<<8===<<<<=><<=?@@?@@?=============0\x160\x16!\xcf0\x16\x10\x10\x1c\x16\x16\x16\xb9\x10' -'\x10\x10\x10\x10\xcf\xcf0\xba000\x100\x1000\x16.................\x10.......00\x16\x16\x16\x16\x16\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' -'\x14\x14\x16\x14\x14\x14\x14\x14\x14\x14\x16\x16\x16\x16\x160\x16\x16000\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x160\x16\xe00\x1600\x16\x16000' -'0.00000000000000................................\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' -'\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x16\xebppppp660\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'00\x160\x160\x160\x160\x160\x160\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10000000000000000' -'00000000000000000000000\x10\x10\x1d\xb4\xb4\xb4\xb4\xb4\xb4\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x10\xb4\x9a\x10\x10\x10\x10\x10\x10mppppmpppnmppppppmmmmmmppmppnopFGHIJKLMNOOPQR\x9cS' -'\xbdTU\xbdpm\xbdN\x10\x10\x10\x10\x10\x10\x10\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10,,,\xbd\xbd\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x05\x05\x05\x05\x10\x10\xe0\xe0\xd2\xb1\xb1\xc5\xac\xa9\xf0\xf0ppppppppZ[\\\xa9\x10\x10\xa9\xa9\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'\x18$$$$$$$$$$WXYZ[\\]^ppmmpppppmpp\x10xxxxxxxxxx\xb1\xaa\xaa\xa9$$_$$$$$$$$$$$$$$$' +'\x1d\x1d\xcd\xcd\xcb\xcd!\x1f!\x1f\x1f\x1f!\x1f!!\x19\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcb\xcb\xcb\xcb\xcd\xcb\xcd\xcb\x1d\x1d\x1d\x1d\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcd!\xcd\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd' +';;;;;;;;;;;;;;;;;;;;;<::::<9:::::88::::88:::::::::::77777::::;;;' +';;;;;?;:::;;;::6;;;::::;<::;=>>=>>=;;;;;;;;;;;;;.\x16.\x16!\xcd.\x16\x10\x10\x1c\x16\x16\x16\xb7\x10' +'\x10\x10\x10\x10\xcd\xcd.\xb8...\x10.\x10..\x16,,,,,,,,,,,,,,,,,\x10,,,,,,,..\x16\x16\x16\x16\x16\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' +'\x14\x14\x16\x14\x14\x14\x14\x14\x14\x14\x16\x16\x16\x16\x16.\x16\x16...\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16.\x16\xde.\x16..\x16\x16...' +'.,..............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' +'\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16\xe9nnnnn44.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'..\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10...............' +'.......................\x10\x10\x1d\xb2\xb2\xb2\xb2\xb2\xb2\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x10\xb2\x98\x10\x10\x10\x10\x10\x10knnnnknnnlknnnnnnkkkkkknnknnlmnDEFGHIJKLMMNOP\x9aQ' +'\xbbRS\xbbnk\xbbL\x10\x10\x10\x10\x10\x10\x10\x10***************************\x10\x10\x10\x10\x10***\xbb\xbb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x05\x05\x05\x05\x10\x10\xde\xde\xd0\xaf\xaf\xc3\xaa\xa7\xee\xeennnnnnnnXYZ\xa7\x10\x10\xa7\xa7\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'\x18$$$$$$$$$$UVWXYZ[\\nnkknnnnnknn\x10vvvvvvvvvv\xaf\xa8\xa8\xa7$$]$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$\xa9$ppppppp\x056ppppmp\x18\x18pp\xf0mppm$$zzzzzzzzzz$$$\xe6\xe6$' -'\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\x10\x07$`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$pmppmppmmmpmmpmp' -'ppmpmpmpmpp\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$BBBBBBBBBBB$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'}}}}}}}}}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,pppppppmp""\xf0\xb9\xb9\xb9"\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,pppp"ppppppppp"ppp"ppppp\x10\x10\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x10' +'$$$$$$$$$$$$$$$$$$$$\xa7$nnnnnnn\x054nnnnkn\x18\x18nn\xeeknnk$$xxxxxxxxxx$$$\xe4\xe4$' +'\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\x10\x07$^$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$nknnknnkkknkknkn' +'nnknknknknn\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@@@@@@@@@@$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'{{{{{{{{{{*********************************nnnnnnnkn""\xee\xb7\xb7\xb7"\x10\x10\x10\x10\x10' +'**********************nnnn"nnnnnnnnn"nnn"nnnnn\x10\x10\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BBB2''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10D'22" -"2BBBBBBBB2222E2\x10'pmppB\x10\x10''''''''''BB\xb4\xb4||||||||||\xb4\x1d'\x10\x10\x10\x10\x10\x10'''''''" -"\x10B22\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10'\x10\x10\x10''''\x10\x10D'22" -"2BBBB\x10\x1022\x10\x1022E'\x10\x10\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10''\x10'''BB\x10\x10||||||||||''\xc9\xc9\x88\x88\x88\x88\x88\x88\xeb\xc9\x10\x10\x10\x10" -"\x10BB2\x10''''''\x10\x10\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10''\x10''\x10\x10D\x1022" -"2BB\x10\x10\x10\x10BB\x10\x10BBE\x10\x10\x10B\x10\x10\x10\x10\x10\x10\x10''''\x10'\x10\x10\x10\x10\x10\x10\x10||||||||||BB'''B\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10BB2\x10'''''''''\x10'''\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10D'22" -"2BBBBB\x10BB2\x1022E\x10\x10'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x10\xc9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10B22\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10D'2B" -"2BBBB\x10\x1022\x10\x1022E\x10\x10\x10\x10\x10\x10\x10\x10B2\x10\x10\x10\x10''\x10'''BB\x10\x10||||||||||\xeb'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10B'\x10''''''\x10\x10\x10'''\x10''''\x10\x10\x10''\x10'\x10''\x10\x10\x10''\x10\x10\x10'''\x10\x10\x10''''''''''''\x10\x10\x10\x1022" -"B22\x10\x10\x10222\x10222E\x10\x10'\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10||||||||||\x88\x88\x88\xf0\xf0\xf0\xf0\xf0\xf0\xc9\xf0\x10\x10\x10\x10\x10" -"\x10222\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10\x10'BB" -"B2222\x10BBB\x10BBBE\x10\x10\x10\x10\x10\x10\x10ab\x10''\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x10\x10\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xeb" -"\x10\x1022\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10D'27" -"22222\x10722\x1022BE\x10\x10\x10\x10\x10\x10\x1022\x10\x10\x10\x10\x10\x10\x10'\x10''BB\x10\x10||||||||||\x10\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x1022\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''''''''\x10\x10\x10'22" -"2BBBB\x10222\x10222E\x10\x10\x10\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x88\x88\x88\x88\x88\x88\x10\x10\x10\xeb''''''" -"\x10\x1022\x10''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''\x10'''''''''\x10'\x10\x10" -"'''''''\x10\x10\x10E\x10\x10\x10\x10222BBB\x10B\x1022222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1022\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10''''''''''''''''''''''''''''''''''''''''''''''''B'&BBBBccE\x10\x10\x10\x10\xc9" -"''''''\x1dBddddBBB\xb4||||||||||\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10''\x10'\x10\x10''\x10'\x10\x10'\x10\x10\x10\x10\x10\x10''''\x10'''''''\x10'''\x10'\x10'\x10\x10''\x10''''B'&BBBBee\x10BB'\x10\x10" -"'''''\x10\x1d\x10ffffBB\x10\x10||||||||||\x10\x10''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'\xeb\xeb\xeb\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\xebmm\xeb\xeb\xeb\xeb\xeb\xeb||||||||||\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xebm\xebm\xebl\xc1\xa0\xc1\xa022" -"''''''''\x10''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10ghBiBBBBBhhhhB2" -"hBppE\xb4pp''''\x10\x10\x10\x10BBBBBBBB\x10BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x10\xeb\xeb" -'\xeb\xeb\xeb\xeb\xeb\xebm\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\xeb\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''''''''''22BBBB2BBBBBD2EE22BB'" -"||||||||||\xb4\xb4\xb4\xb4\xb4\xb4''''''22BB''''BBB'222''2222222'''BBBB'''''''''''" -"''B22BB222222m'2||||||||||222B\xeb\xeb00000000000000000000000000000000" -"000000\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''''''''''''''''''''''''''''''''\xb4\x1d\x10\x10\x10" -'****************************************************************' -"********************************''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''*****''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''******" +"@@@0''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10B'00" +"0@@@@@@@@0000C0\x10'nknn@\x10\x10''''''''''@@\xb2\xb2zzzzzzzzzz\xb2\x1d'\x10\x10\x10\x10\x10\x10'''''''" +"\x10 at 00\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10'\x10\x10\x10''''\x10\x10B'00" +"0@@@@\x10\x1000\x10\x1000C'\x10\x10\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10''\x10'''@@\x10\x10zzzzzzzzzz''\xc7\xc7\x86\x86\x86\x86\x86\x86\xe9\xc7\x10\x10\x10\x10" +"\x10@@0\x10''''''\x10\x10\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10''\x10''\x10\x10B\x1000" +"0@@\x10\x10\x10\x10@@\x10\x10@@C\x10\x10\x10@\x10\x10\x10\x10\x10\x10\x10''''\x10'\x10\x10\x10\x10\x10\x10\x10zzzzzzzzzz@@'''@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10@@0\x10'''''''''\x10'''\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10B'00" +"0@@@@@\x10@@0\x1000C\x10\x10'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x10\xc7\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10 at 00\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10B'0@" +"0@@@@\x10\x1000\x10\x1000C\x10\x10\x10\x10\x10\x10\x10\x10 at 0\x10\x10\x10\x10''\x10'''@@\x10\x10zzzzzzzzzz\xe9'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x10@'\x10''''''\x10\x10\x10'''\x10''''\x10\x10\x10''\x10'\x10''\x10\x10\x10''\x10\x10\x10'''\x10\x10\x10''''''''''''\x10\x10\x10\x1000" +"@00\x10\x10\x10000\x10000C\x10\x10'\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10zzzzzzzzzz\x86\x86\x86\xee\xee\xee\xee\xee\xee\xc7\xee\x10\x10\x10\x10\x10" +"\x10000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10\x10'@@" +"@0000\x10@@@\x10@@@C\x10\x10\x10\x10\x10\x10\x10_`\x10''\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x10\x10\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xe9" +"\x10\x1000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10B'05" +"00000\x10500\x1000 at C\x10\x10\x10\x10\x10\x10\x1000\x10\x10\x10\x10\x10\x10\x10'\x10''@@\x10\x10zzzzzzzzzz\x10\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x1000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''''''''\x10\x10\x10'00" +"0@@@@\x10000\x10000C\x10\x10\x10\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x86\x86\x86\x86\x86\x86\x10\x10\x10\xe9''''''" +"\x10\x1000\x10''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''\x10'''''''''\x10'\x10\x10" +"'''''''\x10\x10\x10C\x10\x10\x10\x10000@@@\x10@\x1000000000\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1000\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10''''''''''''''''''''''''''''''''''''''''''''''''@'&@@@@aaC\x10\x10\x10\x10\xc7" +"''''''\x1d at bbbb@@@\xb2zzzzzzzzzz\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10''\x10'\x10\x10''\x10'\x10\x10'\x10\x10\x10\x10\x10\x10''''\x10'''''''\x10'''\x10'\x10'\x10\x10''\x10''''@'&@@@@cc\x10@@'\x10\x10" +"'''''\x10\x1d\x10dddd@@\x10\x10zzzzzzzzzz\x10\x10''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'\xe9\xe9\xe9\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\xe9kk\xe9\xe9\xe9\xe9\xe9\xe9zzzzzzzzzz\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\xe9k\xe9k\xe9j\xbf\x9e\xbf\x9e00" +"''''''''\x10''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10ef at g@@@@@ffff at 0" +"f at nnC\xb2nn''''\x10\x10\x10\x10@@@@@@@@\x10@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\x10\xe9\xe9" +'\xe9\xe9\xe9\xe9\xe9\xe9k\xe9\xe9\xe9\xe9\xe9\xe9\x10\xe9\xe9\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''''''''''''''''00@@@@0@@@@@B0CC00@@'" +"zzzzzzzzzz\xb2\xb2\xb2\xb2\xb2\xb2''''''00@@''''@@@'000''0000000'''@@@@'''''''''''" +"''@00@@000000k'0zzzzzzzzzz000@\xe9\xe9................................" +"......\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''''''''''''''''''''''''''''''''\xb2\x1d\x10\x10\x10" +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +"((((((((((((((((((((((((((((((((''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''(((((''''''''''''''''''''''''" +"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''((((((" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''\x10''''\x10\x10'''''''\x10'\x10''''\x10\x10''''''''''''''''''''''''''''''''" "'''''''''\x10''''\x10\x10'''''''''''''''''''''''''''''''''\x10''''\x10\x10'''''''\x10" "'\x10''''\x10\x10'''''''''''''''\x10''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''\x10''''\x10\x10''''''''''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''\x10\x10\x10\x10p\xeb\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x89\x89\x89\x89\x89\x89\x89\x89\x89\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10" -"''''''''''''''''\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''\x10\x10\x10\x10n\xe9\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x87\x87\x87\x87\x87\x87\x87\x87\x87\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10" +"''''''''''''''''\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x9a'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" +"\x98'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" @@ -134921,125 +134919,125 @@ "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''''''''''''\xb4\xb4'''''''''''''''''" -"\xf8''''''''''''''''''''''''''\xc1\xa0\x10\x10\x10''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''''''''''\xb4\xb4\xb4\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''\x10''''BBE\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''BBE\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''BB\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''\x10'''\x10BB\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''''''\x08\x082BBBBBBB22" -"222222B22BBBBBBBBBEB\xb4\xb4\xb4\x1d\xb4\xb4\xb4\xc9'p\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x10\x10\x10\x10\x10\x10" -"\xb9\xb9\xb9\xb9\xb9\xb9\x9a\xb9\xb9\xb9\xb9BBB\xf8\x10||||||||||\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''''''\xb2\xb2'''''''''''''''''" +"\xf6''''''''''''''''''''''''''\xbf\x9e\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''''\xb2\xb2\xb2~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'''''''''''''\x10''''@@C\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''@@C\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''@@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''\x10'''\x10@@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''''''\x08\x080@@@@@@@00" +"000000 at 00@@@@@@@@@C@\xb2\xb2\xb2\x1d\xb2\xb2\xb2\xc7'n\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x10\x10\x10\x10\x10\x10" +"\xb7\xb7\xb7\xb7\xb7\xb7\x98\xb7\xb7\xb7\xb7@@@\xf6\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" "'''\x1d''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''''''''''''''o'\x10\x10\x10\x10\x10''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''m'\x10\x10\x10\x10\x10''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''\x10\x10\x10BBB2222BB222\x10\x10\x10\x1022B222222npm\x10\x10\x10\x10" -"\xf0\x10\x10\x10\xb9\xb9||||||||||''''''''''''''''''''''''''''''\x10\x10'''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x102222222222222222" -"2'''''''22\x10\x10\x10\x10\x10\x10|||||||||||\x10\x10\x10\xb9\xb9\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" -"'''''''''''''''''''''''pm222\x10\x10\xb4\xb4''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''2B2BBBBBBB\x10E2B22BBBBBBBB222222BBpppppppp\x10\x10m" -'||||||||||\x10\x10\x10\x10\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x1d\xb4\xb4\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''\x10\x10\x10@@@0000@@000\x10\x10\x10\x1000 at 000000lnk\x10\x10\x10\x10" +"\xee\x10\x10\x10\xb7\xb7zzzzzzzzzz''''''''''''''''''''''''''''''\x10\x10'''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x100000000000000000" +"0'''''''00\x10\x10\x10\x10\x10\x10zzzzzzzzzzz\x10\x10\x10\xb7\xb7\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee" +"'''''''''''''''''''''''nk000\x10\x10\xb2\xb2''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''0 at 0@@@@@@@\x10C0 at 00@@@@@@@@000000@@nnnnnnnn\x10\x10k" +'zzzzzzzzzz\x10\x10\x10\x10\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x1d\xb2\xb2\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BBBB2'''''''''''''''''''''''''''''''''''''''''''''''D2BBBBB2B222" -"22B23'''''''\x10\x10\x10\x10||||||||||\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebpmppppppp\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10" -"BB2''''''''''''''''''''''''''''''2BBBB22BB3\x10\x10\x10''||||||||||\x10\x10\x10\x10\x10\x10" +"@@@@0'''''''''''''''''''''''''''''''''''''''''''''''B0@@@@@0 at 000" +"00 at 01'''''''\x10\x10\x10\x10zzzzzzzzzz\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9nknnnnnnn\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10" +"@@0''''''''''''''''''''''''''''''0@@@@00@@1\x10\x10\x10''zzzzzzzzzz\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"''''''''''''''''''''''''''''''''''''22222222BBBBBBBB22BD\x10\x10\x10\xb4\xb4\xb4\xb4\xb4" -"||||||||||\x10\x10\x10'''||||||||||''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb4\xb4" +"''''''''''''''''''''''''''''''''''''00000000@@@@@@@@00 at B\x10\x10\x10\xb2\xb2\xb2\xb2\xb2" +"zzzzzzzzzz\x10\x10\x10'''zzzzzzzzzz''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb2\xb2" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10ppp\xb4Cmmmmmppmmmmp2CCCCCCC''''m''''2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10nnn\xb2Akkkkknnkkkkn0AAAAAAA''''k''''0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' '\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' -'ppmpppppppmppqkmjpppppppppppppppppppppp\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10mpm' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x16\x16\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x10\x10000000\x10\x10\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x16\x1600000000' -'\x16\x16\x16\x16\x16\x16\x10\x10000000\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16\x100\x100\x100\x100\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10' -'\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x10\x16\x160000-\xcf\x16\xcf' -'\xcf\xcf\x16\x16\x16\x10\x16\x160000-\xcf\xcf\xcf\x16\x16\x16\x16\x10\x10\x16\x160000\x10\xcf\xcf\xcf\x16\x16\x16\x16\x16\x16\x16\x1600000\xcf\xcf\xcf\x10\x10\x16\x16\x16\x10\x16\x160000-\xcf\xcf\x10' -'\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\x07\x07\x07\x08\r\x99\x9a\x9a\x99\x99\x99\xb5\xb9\xa6\xa4\xc0\xa7\xa6\xa4\xc0\xa7\xb5\xb5\xb5\xb9\xb5\xb5\xb5\xb5\xf4\xf5\t\x0e\x0c\n\x0f\xf6\xaf\xb1\xaf\xaf\xb1\xb5\xb9\xb9\xb9\xa8\xa5\xb5\xb9\xb9\xb5\x93' -'\x93\xb9\xb9\xb9\xd3\xc1\xa0\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xe0\xb9\x93\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xf8\x07\x07\x07\x07\x07\x10\x10\x10\x10\x10\x07\x07\x07\x07\x07\x07\x87\x1d\x10\x10\x86\x87\x87\x87\x87\x87\xd5\xd5\xe0\xc1\xa0\x19' -'\x87\x86\x86\x86\x86\x87\x87\x87\x87\x87\xd5\xd5\xe0\xc1\xa0\x10\x1d\x1d\x1d\x1d\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc8\xc9\xc9\xc6\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10ppCCppppCCCpp6666p666CCpmpCCmmmmp\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"\xf0\xf00\xed\xf0\xed\xf00\xf0\xed\x16000\x16\x16000\x14\xf00\xed\xf0\xf100000\xf0\xf0\xf0\xed\xed\xf00\xf0.\xf00\xf00.00\xe9\x160000\x16''''\x16\xf0\xf0\x16\x1600" -'\xe1\xe0\xe0\xe0\xe00\x16\x16\x16\x16\xf0\xe0\xf0\xf0\x16\xeb\x8d\x8d\x8d\x8b\x8b\x8d\x8d\x8d\x8d\x8d\x8d\x8b\x8b\x8b\x8b\x8d~~~~~~~~~~~~\x80\x80\x80\x80~~~~~~~~~~\x80\x80\x80\x80\x80\x80' -'\x80\x80\x800\x16\x80\x80\x80\x80\x8b\x10\x10\x10\x10\x10\x10\xdb\xdb\xdb\xdb\xdb\xed\xed\xed\xed\xed\xe0\xe0\xf0\xf0\xf0\xf0\xe0\xf0\xf0\xe0\xf0\xf0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xf0\xf0\xdb\xf0\xdb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xdb\xe1\xdc\xdc\xe1\xe0\xe0\xdb\xdc\xe1\xe1\xdc\xe1\xe1\xe0\xdb\xe0\xdc\xd5\xd9\xe0\xdc\xe1\xe0\xe0\xe0\xdc\xe1\xe1\xdc\xdb\xdc\xdc\xe1\xe1\xdb\xe1\xdb\xe1\xdb\xdb\xdb\xdb\xdc\xdc\xe1\xdc\xe1\xe1\xe1\xe1\xe1\xdb\xdb\xdb\xdb\xe0\xe1\xe0\xe1\xdc\xdc\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xdc\xe1\xe1\xe1\xdc\xe0\xe0\xe0\xe0\xe0\xdc\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xdc\xdb\xe1\xe0\xdc\xdc\xdc\xdc\xe1\xe1\xdc\xdc\xe0\xe0\xdc\xdc\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xdc\xdc\xe1\xe1\xdc\xdc\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xdb\xe0\xe0\xe1\xdb\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xdb\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xdc' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe1\xe1\xe1\xe1\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe1\xe1\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xc4\xa3\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xf0\xe0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8b\x8b' -'\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x86\x86\x86\x86\x86\x86\x86\x86\x86\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' -'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x8e\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8c' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xed\xdb\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0' -'\xed\xdb\xf0\xf0\xf0\xf0\xed\xed\xed\xf0\xf0\xed\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xed\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xed\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xed\xed\xed\xf0\xed\xed\xed\xed\xf0\xed\xed\xf0\xdb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed' -'\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\x10\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\x10\xed\x10\x10\x10\x10\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed' -'\x10\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\x10\xf0\xf0\xf0\xf0\x10\x10\x10\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b' -'\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8d\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8d\xf0\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10' -'\xe1\xe0\xe0\xe1\xe1\xc1\xa0\xe0\xe1\xe1\xe0\x10\xe1\x10\x10\x10\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xc1\xa0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' +'nnknnnnnnnknnoikhnnnnnnnnnnnnnnnnnnnnnn\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10knk' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x10\x10......\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x16\x16........' +'\x16\x16\x16\x16\x16\x16\x10\x10......\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16\x10.\x10.\x10.\x10.\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10' +'\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x10\x16\x16....+\xcd\x16\xcd' +'\xcd\xcd\x16\x16\x16\x10\x16\x16....+\xcd\xcd\xcd\x16\x16\x16\x16\x10\x10\x16\x16....\x10\xcd\xcd\xcd\x16\x16\x16\x16\x16\x16\x16\x16.....\xcd\xcd\xcd\x10\x10\x16\x16\x16\x10\x16\x16....+\xcd\xcd\x10' +'\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\x07\x07\x07\x08\r\x97\x98\x98\x97\x97\x97\xb3\xb7\xa4\xa2\xbe\xa5\xa4\xa2\xbe\xa5\xb3\xb3\xb3\xb7\xb3\xb3\xb3\xb3\xf2\xf3\t\x0e\x0c\n\x0f\xf4\xad\xaf\xad\xad\xaf\xb3\xb7\xb7\xb7\xa6\xa3\xb3\xb7\xb7\xb3\x91' +'\x91\xb7\xb7\xb7\xd1\xbf\x9e\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xde\xb7\x91\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xf6\x07\x07\x07\x07\x07\x10\x10\x10\x10\x10\x07\x07\x07\x07\x07\x07\x85\x1d\x10\x10\x84\x85\x85\x85\x85\x85\xd3\xd3\xde\xbf\x9e\x19' +'\x85\x84\x84\x84\x84\x85\x85\x85\x85\x85\xd3\xd3\xde\xbf\x9e\x10\x1d\x1d\x1d\x1d\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc6\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10nnAAnnnnAAAnn4444n444AAnknAAkkkkn\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"\xee\xee.\xeb\xee\xeb\xee.\xee\xeb\x16...\x16\x16...\x14\xee.\xeb\xee\xef.....\xee\xee\xee\xeb\xeb\xee.\xee,\xee.\xee.,..\xe7\x16....\x16''''\x16\xee\xee\x16\x16.." +'\xdf\xde\xde\xde\xde.\x16\x16\x16\x16\xee\xde\xee\xee\x16\xe9\x8b\x8b\x8b\x89\x89\x8b\x8b\x8b\x8b\x8b\x8b\x89\x89\x89\x89\x8b||||||||||||~~~~||||||||||~~~~~~' +'~~~.\x16~~~~\x89\x10\x10\x10\x10\x10\x10\xd9\xd9\xd9\xd9\xd9\xeb\xeb\xeb\xeb\xeb\xde\xde\xee\xee\xee\xee\xde\xee\xee\xde\xee\xee\xde\xee\xee\xee\xee\xee\xee\xee\xde\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xee\xee\xd9\xee\xd9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xd9\xdf\xda\xda\xdf\xde\xde\xd9\xda\xdf\xdf\xda\xdf\xdf\xde\xd9\xde\xda\xd3\xd7\xde\xda\xdf\xde\xde\xde\xda\xdf\xdf\xda\xd9\xda\xda\xdf\xdf\xd9\xdf\xd9\xdf\xd9\xd9\xd9\xd9\xda\xda\xdf\xda\xdf\xdf\xdf\xdf\xdf\xd9\xd9\xd9\xd9\xde\xdf\xde\xdf\xda\xda\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xda\xdf\xdf\xdf\xda\xde\xde\xde\xde\xde\xda\xdf\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xda\xd9\xdf\xde\xda\xda\xda\xda\xdf\xdf\xda\xda\xde\xde\xda\xda\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xda\xda\xdf\xdf\xda\xda\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xde\xde\xd9\xde\xde\xdf\xd9\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xd9\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xda' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xee\xee\xee\xee\xee\xee\xee\xee\xdf\xdf\xdf\xdf\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xdf\xdf\xee\xee\xee\xee\xee\xee\xee\xc2\xa1\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xee\xde\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x89\x89' +'\x89\x89\x89\x89\x89\x89\x89\x89\x84\x84\x84\x84\x84\x84\x84\x84\x84\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8' +'\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\x8c\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x8a' '\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xc1\xa0\xc2\xa1\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe0\xe0\xc1\xa0\xc1\xa0\xe1\xe0\xe0\xe0\xe0\xe1\xe0\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xc1\xa0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe0\xe1\xe0\xe0\xe1\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe0\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe0\xe0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xeb\xd9\xee\xee\xee\xee\xeb\xeb\xee\xee' +'\xeb\xd9\xee\xee\xee\xee\xeb\xeb\xeb\xee\xee\xeb\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde' +'\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xeb\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee\xeb\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xeb\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xeb\xeb\xeb\xee\xeb\xeb\xeb\xeb\xee\xeb\xeb\xee\xd9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb' +'\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\x10\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' +'\x10\xee\xee\xee\xee\x10\xee\xee\xee\xee\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\x10\xee\xee\xee\xee\x10\x10\x10\xee\xeb\xee\xee\xee\xee\xee\xee\xee\x10\x10\xee\xee\xee\xee\xee\xee\xee\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89' +'\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\xee\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10' +'\xdf\xde\xde\xdf\xdf\xbf\x9e\xde\xdf\xdf\xde\x10\xdf\x10\x10\x10\xde\xde\xde\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xc0\x9f\xc0\x9f\xc0\x9f\xc0\x9f\xbf\x9e\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xbf\x9e\xc0\x9f\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xde\xde\xde\xde\xde\xde\xde' +'\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xde\xde\xbf\x9e\xbf\x9e\xdf\xde\xde\xde\xde\xdf\xde\xdf\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xbf\x9e\xde\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xdf\xdf\xde\xde\xdf\xde\xdf\xde\xde\xdf\xde\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xde\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xde\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde\xde\xde\xde\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xdf\xde\xde' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xde\xde\xee\xee\xde\xde\xde\xde\xde\xde\x10\x10\x10\xee\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'00000000000000000000000000000000000000000000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x100\x16000\x16\x160\x160\x160\x160000\x160\x16\x160\x16\x16\x16\x16\x16\x16\x16\x1d00' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\xf0\xf0\xf0\xf0\xf0\xf00\x160\x16ppp\x10\x10\x10\x10\x10\x10\x10\xb9\xb9\xb9\xb9\x8d\xb9\xb9' +'...............................................\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10.\x16...\x16\x16.\x16.\x16.\x16....\x16.\x16\x16.\x16\x16\x16\x16\x16\x16\x16\x1d..' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\xee\xee\xee\xee\xee\xee.\x16.\x16nnn\x10\x10\x10\x10\x10\x10\x10\xb7\xb7\xb7\xb7\x8b\xb7\xb7' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" "''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" "'''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''\x10'''''''\x10'''''''\x10'''''''\x10" -"'''''''\x10'''''''\x10'''''''\x10'''''''\x10pppppppppppppppppppppppppppppppp" -'\xb9\xb9\xa8\xa5\xa8\xa5\xb9\xb9\xb9\xa8\xa5\xb9\xa8\xa5\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x9a\xb9\xb9\x9a\xb9\xa8\xa5\xb9\xb9\xa8\xa5\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xb9\xb9\xb9\xb9\xb9 \xb9\xb9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''\x10'''''''\x10'''''''\x10'''''''\x10nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" +'\xb7\xb7\xa6\xa3\xa6\xa3\xb7\xb7\xb7\xa6\xa3\xb7\xa6\xa3\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\x98\xb7\xb7\x98\xb7\xa6\xa3\xb7\xb7\xa6\xa3\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xb7\xb7\xb7\xb7\xb7 \xb7\xb7\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10' -'\xf7\xbc\xbc\xbc\xf3\x1e*\x81\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\xf3\xf3\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\x9b\xc3\xa2\xa2\xf3\x81\x81\x81\x81\x81\x81\x81\x81\x81svwtuu\x9b\x1e\x1e\x1e\x1e\x1e\xf3\xf3\x81\x81\x81\x1e*\xbc\xf3\xf0' -'\x10***************************************************************' -'***********************\x10\x10rr\xd1\xd1\x1e\x1e*\x9b*******************************' -'***********************************************************\xbc\x1e\x1e\x1e*' -'\x10\x10\x10\x10\x10*****************************************\x10\x10\x10***************' -'****************************************************************' -'***************\x10\xec\xec\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec************************\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10****************' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\x10\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xea\xea\xea\xea\xea\xea\xea\xea\xf3\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xec' -'\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10' +'\xf5\xba\xba\xba\xf1\x1e(\x7f\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xf1\xf1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\x99\xc1\xa0\xa0\xf1\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7fqturss\x99\x1e\x1e\x1e\x1e\x1e\xf1\xf1\x7f\x7f\x7f\x1e(\xba\xf1\xee' +'\x10(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((((((((((((\x10\x10pp\xcf\xcf\x1e\x1e(\x99(((((((((((((((((((((((((((((((' +'(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((\xba\x1e\x1e\x1e(' +'\x10\x10\x10\x10\x10(((((((((((((((((((((((((((((((((((((((((\x10\x10\x10(((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((((\x10\xea\xea\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10((((((((((((((((' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xf1\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xea' +'\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xf1\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xf1\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1' '((((()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' @@ -135059,7 +135057,7 @@ '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' ')(()((()()((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((()((((((((((((((((((((((((((((((((((' '(((((((((((()((((((()()(((((((((((((((((((((((((((((((((((((((()' @@ -135140,46 +135138,42 @@ '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'*********************\x1e******************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'*************\x10\x10\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -"\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb4\xb4" -"''''''''''''\x1d\xb9\xb9\xb9''''''''''''''''||||||||||''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x100\x160\x160\x160\x160\x160\x16'p666\xb9\x10\x10\x10\x10\x10\x10\x10\x10pp\xb9!" -"0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''''''''''\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80pp\xb4\xb4\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10" -'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf!!!!!!!!!\xcf\xcf0\x160\x160\x160\x160\x160\x160\x16\x16\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x1d\x16\x16\x16\x16\x16\x16\x16\x160\x160\x1600\x16' -'0\x160\x160\x160\x16!\xcc\xcc0\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'(((((((((((((((((((((\x1e((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((\x10\x10\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +"\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb2\xb2" +"''''''''''''\x1d\xb7\xb7\xb7''''''''''''''''zzzzzzzzzz''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +".\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10.\x16.\x16.\x16.\x16.\x16.\x16'n444\xb7\x10\x10\x10\x10\x10\x10\x10\x10nn\xb7!" +".\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"''''''''''''''''''''''''''''''''''''''~~~~~~~~~~nn\xb2\xb2\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10" +'\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd!!!!!!!!!\xcd\xcd.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x1d\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16..\x16' +'.\x16.\x16.\x16.\x16!\xca\xca.\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''" -"''B'''E''''B'''''''''''''''''''''''22BB2\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\xeb\xeb\xc9\xe8\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''''''\xb9\xb9\xb9\xb9\x10\x10\x10\x10\x10\x10\x10\x10" -"22''''''''''''''''''''''''''''''''''''''''''''''''''222222222222" -"2222E\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4\xb4||||||||||\x10\x10\x10\x10\x10\x10pppppppppppppppppp''''''\xb4\xb4\xb4'\x10\x10\x10\x10" -"||||||||||''''''''''''''''''''''''''''BBBBBmmm\xb4\xb4''''''''''''''''" -"'''''''BBBBBBBBBBB23\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4*****************************\x10\x10\x10" -"BBB2'''''''''''''''''''''''''''''''''''''''''''''''D22BBBB22B222" -'3\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x10\x1d||||||||||\x10\x10\x10\x10\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''''''''BBBBBB22BB22BB\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''B''''''''B2\x10\x10||||||||||\x10\x10\xb4\xb4\xb4\xb4''''''''''''''''\x1d''''''\xeb\xeb\xeb'2\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''p'ppm''pp'''''pp" -"'p'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''\x1d\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''@'''C''''@'''''''''''''''''''''''00@@0\xee\xee\xee\xee\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\xe9\xe9\xc7\xe6\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''''''\xb7\xb7\xb7\xb7\x10\x10\x10\x10\x10\x10\x10\x10" +"00''''''''''''''''''''''''''''''''''''''''''''''''''000000000000" +"0000C\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2\xb2zzzzzzzzzz\x10\x10\x10\x10\x10\x10nnnnnnnnnnnnnnnnnn''''''\xb2\xb2\xb2'\x10\x10\x10\x10" +"zzzzzzzzzz''''''''''''''''''''''''''''@@@@@kkk\xb2\xb2''''''''''''''''" +"'''''''@@@@@@@@@@@01\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2(((((((((((((((((((((((((((((\x10\x10\x10" +"@@@0'''''''''''''''''''''''''''''''''''''''''''''''B00@@@@00 at 000" +'1\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x10\x1dzzzzzzzzzz\x10\x10\x10\x10\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''''''''''''''@@@@@@00@@00@@\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'''@''''''''@0\x10\x10zzzzzzzzzz\x10\x10\xb2\xb2\xb2\xb2''''''''''''''''\x1d''''''\xe9\xe9\xe9'0\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''n'nnk''nn'''''nn" +"'n'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''\x1d\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''22B22B22\xb42E\x10\x10||||||||||\x10\x10\x10\x10\x10\x10" +"'''''''''''''''''''''''''''''''''''00 at 00@00\xb20C\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10" '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' -'((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10****************' -'*******\x10\x10\x10\x10*************************************************\x10\x10\x10\x10' +'((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10((((((((((((((((' +'(((((((\x10\x10\x10\x10(((((((((((((((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' @@ -135188,140 +135182,140 @@ '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' -'****************************************************************' -'*******************************************+*******+****+*******' -'**************************************************+*************' -'*****************+*+*****************************************+**' -'**********************************************\x11\x11****************' -'**********************************************\x11\x11****************' -'****************************************************************' -'**************************\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10,V,,,,,,,,,,\xd5,,,,,,,,,,,,,\x10,,,,,\x10,\x10' -',,\x10,,\x10,,,,,,,,,,$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((()((((((()(((()(((((((' +'(((((((((((((((((((((((((((((((((((((((((((((((((()(((((((((((((' +'((((((((((((((((()()((((((((((((((((((((((((((((((((((((((((()((' +'((((((((((((((((((((((((((((((((((((((((((((((\x11\x11((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((\x11\x11((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' +'\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10*T**********\xd3*************\x10*****\x10*\x10' +'**\x10**\x10**********$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$######$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\xc0\x9f' +'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\xbe\x9d' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$##\xc5\xf0\x10\x10' -'8888888888888888\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xc3\xa2\xbc\x10\x10\x10\x10\x10\x10ppppppp\x10\x10\x10\x10\x10\x10\x10\x10\x10\xbc\x9b\x9b\x95\x95\xc3\xa2\xc3\xa2\xc3\xa2\xc3\xa2\xc3\xa2\xc3' -'\xa2\xc3\xa2\xc3\xa2\xbc\xbc\xc3\xa2\xbc\xbc\xbc\xbc\x95\x95\x95\xae\xbc\xae\x10\xbc\xae\xbc\xbc\x9b\xc4\xa3\xc4\xa3\xc4\xa3\xb3\xbc\xbc\xd7\x98\xe5\xe5\xe4\x10\xbc\xcb\xb3\xbc\x10\x10\x10\x10#$#$#\x10#$#$#$#$#$' +'$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$##\xc3\xee\x10\x10' +'6666666666666666\xba\xba\xba\xba\xba\xba\xba\xc1\xa0\xba\x10\x10\x10\x10\x10\x10nnnnnnn\x10\x10\x10\x10\x10\x10\x10\x10\x10\xba\x99\x99\x93\x93\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1' +'\xa0\xc1\xa0\xc1\xa0\xba\xba\xc1\xa0\xba\xba\xba\xba\x93\x93\x93\xac\xba\xac\x10\xba\xac\xba\xba\x99\xc2\xa1\xc2\xa1\xc2\xa1\xb1\xba\xba\xd5\x96\xe3\xe3\xe2\x10\xba\xc9\xb1\xba\x10\x10\x10\x10#$#$#\x10#$#$#$#$#$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x07' -'\x10\xb7\xb7\xb0\xc7\xb0\xb7\xb7\xbe\x9d\xb7\xd4\xab\x96\xab\xabyyyyyyyyyy\xab\xb7\xde\xdd\xde\xb7\xb7//////////////////////////\xbe\xb7\x9d\xce\x92' -'\xce\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbe\xdd\x9d\xdd\xbe\x9d\xb8\xbf\x9e\xb8\xb8%%%%%%%%%%\x1b%%%%%%%%%%%%%%%' +'\x10\xb5\xb5\xae\xc5\xae\xb5\xb5\xbc\x9b\xb5\xd2\xa9\x94\xa9\xa9wwwwwwwwww\xa9\xb5\xdc\xdb\xdc\xb5\xb5--------------------------\xbc\xb5\x9b\xcc\x90' +'\xcc\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbc\xdb\x9b\xdb\xbc\x9b\xb6\xbd\x9c\xb6\xb6%%%%%%%%%%\x1b%%%%%%%%%%%%%%%' '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x1a\x1a%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x10' -'\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%\x10\x10\x10\xc7\xc7\xdd\xce\xee\xc7\xc7\x10\xef\xdf\xdf\xdf\xdf\xef\xef\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x0b\x0b\x0b\xf0\xed\x10\x10' +'\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%\x10\x10\x10\xc5\xc5\xdb\xcc\xec\xc5\xc5\x10\xed\xdd\xdd\xdd\xdd\xed\xed\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x0b\x0b\x0b\xee\xeb\x10\x10' "''''''''''''\x10''''''''''''''''''''''''''\x10'''''''''''''''''''\x10''\x10'" "''''''''''''''\x10\x10''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10" -'\xb4\xb9\xeb\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x8d\x8d\x8d\x8d\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x8d\x10\x10\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebm\x10\x10' +'\xb2\xb7\xe9\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x8b\x8b\x8b\x8b\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x8b\x10\x10\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9k\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "'''''''''''''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''''''''''" "'''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''''\x10\x88\x88\x88\x88\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" -"'\x80''''''''\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''\x10\xb4''''''''''''''''''''''''''''''''" -"''''\x10\x10\x10\x10''''''''\xb4\x80\x80\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -'0000000000000000000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +"'''''''''''''''''''''''''''''''\x10\x86\x86\x86\x86\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" +"'~''''''''~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''\x10\xb2''''''''''''''''''''''''''''''''" +"''''\x10\x10\x10\x10''''''''\xb2~~~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +'........................................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16''''''''''''''''''''''''''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,\x10\x10,\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10,,\x10\x10\x10,\x10\x10,' -',,,,,,,,,,,,,,,,,,,,,,\x10\xbd\x90\x90\x90\x90\x90\x90\x90\x90\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'******\x10\x10*\x10********************************************\x10**\x10\x10\x10*\x10\x10*' +'**********************\x10\xbb\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,\x90\x90\x90\x90\x90\x90\x10\x10\x10\xb9,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10\xbd' +'**********************\x8e\x8e\x8e\x8e\x8e\x8e\x10\x10\x10\xb7**************************\x10\x10\x10\x10\x10\xbb' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',BBB\x10BB\x10\x10\x10\x10\x10BmBp,,,,\x10,,,\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10pCm\x10\x10\x10\x10E' -'\x91\x91\x91\x91\x90\x90\x90\x90\x10\x10\x10\x10\x10\x10\x10\x10\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x10\x10\x10\x10\x10\x10\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x90\x90\xbd' +'*@@@\x10@@\x10\x10\x10\x10\x10 at k@n****\x10***\x10***************************\x10\x10\x10\x10nAk\x10\x10\x10\x10C' +'\x8f\x8f\x8f\x8f\x8e\x8e\x8e\x8e\x10\x10\x10\x10\x10\x10\x10\x10\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\x10\x10\x10\x10\x10\x10\x10*****************************\x8e\x8e\xbb' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\xb9\xb9\xb9\xb9\xb9\xb9\xb9' -',,,,,,,,,,,,,,,,,,,,,,\x10\x10\x90\x90\x90\x90\x90\x90\x90\x90,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10\x90\x90\x90\x90\x90\x90\x90\x90' +'******************************************************\x10\x10\x10\xb7\xb7\xb7\xb7\xb7\xb7\xb7' +'**********************\x10\x10\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e*******************\x10\x10\x10\x10\x10\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'****************************************************************' +'*********\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x84\x84\x84\x84\x84\x84\x84\x84\x84\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x82\x82\x82\x82\x82\x82\x82\x82\x82\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BB2'''''''''''''''''''''''''''''''''''''''''''''222BBBB22ED\xb4\xb4\x08\xb4\xb4" -'\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"@@0'''''''''''''''''''''''''''''''''''''''''''''000@@@@00CB\xb2\xb2\x08\xb2\xb2" +'\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x7f\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80' -'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x7f\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~' +'~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "'''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb44CCC\xeb\xeb\xeb544444\x07\x07\x07\x07\x07\x07\x07\x07mmmmm' -'mmm\xeb\xebpppppmm\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebpppp\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0ppp\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe922AAA\xe9\xe9\xe9322222\x07\x07\x07\x07\x07\x07\x07\x07kkkkk' +'kkk\xe9\xe9nnnnnkk\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9nnnn\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xeennn\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'00000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16000000000000' -'00000000000000\x16\x16\x16\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16000000000000000000000000' -'00\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160\x1000\x10\x100\x10\x1000\x10\x100000\x1000000000\x16\x16\x16\x16\x10\x16\x10\x16\x16\x16' -'\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x1600\x100000\x10\x1000000000\x100000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600\x100000\x10' -'00000\x100\x10\x10\x100000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000' -'000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160000' -'0000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160000000000000000' -'0000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10000000000000000000000000' -'0\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160\x16\x10\x10zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16............' +'..............\x16\x16\x16\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16........................' +'..\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x10..\x10\x10.\x10\x10..\x10\x10....\x10........\x16\x16\x16\x16\x10\x16\x10\x16\x16\x16' +'\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16..\x10....\x10\x10........\x10.......\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..\x10....\x10' +'.....\x10.\x10\x10\x10.......\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16....................' +'......\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16....' +'......................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16................' +'..........\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10........................' +'.\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.\x16\x10\x10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\x10\x10\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xeb\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\xea' -'\x10\x10\xea\x10\x10\x10\xea\x10\x10\x10\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\xea\xea\x10\x10\xea' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\xea\xea\xea\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x84\x84\x84\x84\x84\x84\x84\x84\x84\x84\x84\x10\x10\x10\x10\x10\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe9\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\xe8' +'\x10\x10\xe8\x10\x10\x10\xe8\x10\x10\x10\xe8\xe8\xe8\xe8\xe8\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\xe8\xe8\x10\x10\xe8' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\xe8\xe8\xe8\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' @@ -135372,11 +135366,7 @@ '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'****************************************************************' -'****************************************************************' -'****************+***********************************************' -'****************************************************************' -'******************************\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' +'((((((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' @@ -135388,10 +135378,10 @@ '\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'8888888888888888888888888888888888888888888888888888888888888888' -'8888888888888888888888888888888888888888888888888888888888888888' -'8888888888888888888888888888888888888888888888888888888888888888' -'888888888888888888888888888888888888888888888888\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'6666666666666666666666666666666666666666666666666666666666666666' +'6666666666666666666666666666666666666666666666666666666666666666' +'6666666666666666666666666666666666666666666666666666666666666666' +'666666666666666666666666666666666666666666666666\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' From noreply at buildbot.pypy.org Fri Mar 8 23:51:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:51:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: kill datetime._call_tzinfo_method Message-ID: <20130308225153.9749A1C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62251:fa88318c96af Date: 2013-03-08 16:46 -0500 http://bitbucket.org/pypy/pypy/changeset/fa88318c96af/ Log: kill datetime._call_tzinfo_method diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -238,11 +238,6 @@ newformat = "".join(newformat) return _time.strftime(newformat, timetuple) -def _call_tzinfo_method(tzinfo, methname, tzinfoarg): - if tzinfo is None: - return None - return getattr(tzinfo, methname)(tzinfoarg) - # Just raise TypeError if the arg isn't None or a string. def _check_tzname(name): if name is not None and not isinstance(name, str): @@ -1612,7 +1607,9 @@ it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", self) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(self) _check_tzname(name) return name @@ -2123,7 +2120,7 @@ # Clean up unused names del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y, _DI4Y, _MAXORDINAL, _MONTHNAMES, - _build_struct_time, _call_tzinfo_method, _check_date_fields, + _build_struct_time, _check_date_fields, _check_time_fields, _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror, _date_class, _days_before_month, _days_before_year, _days_in_month, _format_time, _is_leap, From noreply at buildbot.pypy.org Fri Mar 8 23:51:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:51:54 +0100 (CET) Subject: [pypy-commit] pypy py3k: update datetime name cleanup for changes, add test Message-ID: <20130308225154.E80371C39E4@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62252:a0935a3ab7b9 Date: 2013-03-08 17:08 -0500 http://bitbucket.org/pypy/pypy/changeset/a0935a3ab7b9/ Log: update datetime name cleanup for changes, add test diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -2118,14 +2118,13 @@ pass else: # Clean up unused names - del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, - _DI100Y, _DI400Y, _DI4Y, _MAXORDINAL, _MONTHNAMES, - _build_struct_time, _check_date_fields, - _check_time_fields, _check_tzinfo_arg, _check_tzname, - _check_utc_offset, _cmp, _cmperror, _date_class, _days_before_month, - _days_before_year, _days_in_month, _format_time, _is_leap, - _isoweek1monday, _math, _ord2ymd, _time, _time_class, _tzinfo_class, - _wrap_strftime, _ymd2ord) + del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y, + _DI4Y, _MAXORDINAL, _MINYEARFMT, _MONTHNAMES, _build_struct_time, + _check_date_fields, _check_int_field, _check_time_fields, + _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror, + _date_class, _days_before_month, _days_before_year, _days_in_month, + _format_time, _is_leap, _isoweek1monday, _math, _ord2ymd, _round, + _struct, _time, _time_class, _tzinfo_class, _wrap_strftime, _ymd2ord) # XXX Since import * above excludes names that start with _, # docstring does not get overwritten. In the future, it may be # appropriate to maintain a single module level docstring and diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -49,6 +49,17 @@ self.assertEqual(datetime.MINYEAR, 1) self.assertEqual(datetime.MAXYEAR, 9999) + def test_name_cleanup(self): + if not '_Fast' in str(type(self)): + return + datetime = datetime_module + names = set(name for name in dir(datetime) + if not name.startswith('__') and not name.endswith('__')) + allowed = set(['MAXYEAR', 'MINYEAR', 'date', 'datetime', + 'datetime_CAPI', 'time', 'timedelta', 'timezone', + 'tzinfo']) + self.assertEqual(names - allowed, set([])) + ############################################################################# # tzinfo tests From noreply at buildbot.pypy.org Fri Mar 8 23:51:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:51:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix this exception to match c datetime Message-ID: <20130308225156.323571C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62253:7022298605ca Date: 2013-03-08 17:22 -0500 http://bitbucket.org/pypy/pypy/changeset/7022298605ca/ Log: fix this exception to match c datetime diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -1307,7 +1307,7 @@ if tzinfo is None or isinstance(tzinfo, _tzinfo_class): self._tzinfo = tzinfo else: - raise TypeError("bad tzinfo state arg %r" % tzinfo) + raise TypeError("bad tzinfo state arg") def __reduce__(self): return (time, self._getstate()) @@ -1783,7 +1783,7 @@ if tzinfo is None or isinstance(tzinfo, _tzinfo_class): self._tzinfo = tzinfo else: - raise TypeError("bad tzinfo state arg %r" % tzinfo) + raise TypeError("bad tzinfo state arg") def __reduce__(self): return (self.__class__, self._getstate()) From noreply at buildbot.pypy.org Fri Mar 8 23:51:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:51:57 +0100 (CET) Subject: [pypy-commit] pypy default: kill datetime._call_tzinfo_method Message-ID: <20130308225157.726651C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62254:a01317e45a4f Date: 2013-03-08 16:46 -0500 http://bitbucket.org/pypy/pypy/changeset/a01317e45a4f/ Log: kill datetime._call_tzinfo_method diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -236,11 +236,6 @@ newformat = "".join(newformat) return _time.strftime(newformat, timetuple) -def _call_tzinfo_method(tzinfo, methname, tzinfoarg): - if tzinfo is None: - return None - return getattr(tzinfo, methname)(tzinfoarg) - # Just raise TypeError if the arg isn't None or a string. def _check_tzname(name): if name is not None and not isinstance(name, str): @@ -1336,7 +1331,9 @@ def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of UTC).""" - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(None) offset = _check_utc_offset("utcoffset", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1344,7 +1341,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _utcoffset(self): - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(None) offset = _check_utc_offset("utcoffset", offset) return offset @@ -1355,7 +1354,9 @@ it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", None) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(None) _check_tzname(name) return name @@ -1368,7 +1369,9 @@ need to consult dst() unless you're interested in displaying the DST info. """ - offset = _call_tzinfo_method(self._tzinfo, "dst", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(None) offset = _check_utc_offset("dst", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1376,7 +1379,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _dst(self): - offset = _call_tzinfo_method(self._tzinfo, "dst", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(None) offset = _check_utc_offset("dst", offset) return offset @@ -1710,7 +1715,9 @@ def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of UTC).""" - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(self) offset = _check_utc_offset("utcoffset", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1718,7 +1725,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _utcoffset(self): - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(self) offset = _check_utc_offset("utcoffset", offset) return offset @@ -1729,7 +1738,9 @@ it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", self) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(self) _check_tzname(name) return name @@ -1742,7 +1753,9 @@ need to consult dst() unless you're interested in displaying the DST info. """ - offset = _call_tzinfo_method(self._tzinfo, "dst", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(self) offset = _check_utc_offset("dst", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1750,7 +1763,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _dst(self): - offset = _call_tzinfo_method(self._tzinfo, "dst", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(self) offset = _check_utc_offset("dst", offset) return offset From noreply at buildbot.pypy.org Fri Mar 8 23:51:58 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:51:58 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix datetime unpickle checking of tzinfo arg Message-ID: <20130308225158.AA0E41C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62255:7be6c0646eb4 Date: 2013-03-08 17:19 -0500 http://bitbucket.org/pypy/pypy/changeset/7be6c0646eb4/ Log: test and fix datetime unpickle checking of tzinfo arg diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -1425,7 +1425,10 @@ ord(string[0]), ord(string[1]), ord(string[2]), ord(string[3]), ord(string[4]), ord(string[5])) self._microsecond = (((us1 << 8) | us2) << 8) | us3 - self._tzinfo = tzinfo + if tzinfo is None or isinstance(tzinfo, _tzinfo_class): + self._tzinfo = tzinfo + else: + raise TypeError("bad tzinfo state arg") def __reduce__(self): return (time, self._getstate()) @@ -1922,7 +1925,10 @@ ord(string[7]), ord(string[8]), ord(string[9])) self._year = yhi * 256 + ylo self._microsecond = (((us1 << 8) | us2) << 8) | us3 - self._tzinfo = tzinfo + if tzinfo is None or isinstance(tzinfo, _tzinfo_class): + self._tzinfo = tzinfo + else: + raise TypeError("bad tzinfo state arg") def __reduce__(self): return (self.__class__, self._getstate()) diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -25,6 +25,16 @@ e = raises(TypeError, datetime.datetime, '123') assert e.value.args[0] == 'an integer is required' + datetime.time('\x01' * 6, None) + with raises(TypeError) as e: + datetime.time('\x01' * 6, 123) + assert str(e.value) == "bad tzinfo state arg" + + datetime.datetime('\x01' * 10, None) + with raises(TypeError) as e: + datetime.datetime('\x01' * 10, 123) + assert str(e.value) == "bad tzinfo state arg" + def test_strptime(): import time, sys if sys.version_info < (2, 6): From noreply at buildbot.pypy.org Fri Mar 8 23:51:59 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:51:59 +0100 (CET) Subject: [pypy-commit] pypy py3k: improve datetime test_backdoor_resistance Message-ID: <20130308225159.ECDBD1C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62256:32627dc63db2 Date: 2013-03-08 17:49 -0500 http://bitbucket.org/pypy/pypy/changeset/32627dc63db2/ Log: improve datetime test_backdoor_resistance diff --git a/lib-python/3/test/datetimetester.py b/lib-python/3/test/datetimetester.py --- a/lib-python/3/test/datetimetester.py +++ b/lib-python/3/test/datetimetester.py @@ -1380,9 +1380,10 @@ for month_byte in b'9', b'\0', b'\r', b'\xff': self.assertRaises(TypeError, self.theclass, base[:2] + month_byte + base[3:]) - # Good bytes, but bad tzinfo: - self.assertRaises(TypeError, self.theclass, - bytes([1] * len(base)), 'EST') + if issubclass(self.theclass, datetime): + # Good bytes, but bad tzinfo: + with self.assertRaisesRegex(TypeError, '^bad tzinfo state arg$'): + self.theclass(bytes([1] * len(base)), 'EST') for ord_byte in range(1, 13): # This shouldn't blow up because of the month byte alone. If @@ -2275,6 +2276,9 @@ for hour_byte in ' ', '9', chr(24), '\xff': self.assertRaises(TypeError, self.theclass, hour_byte + base[1:]) + # Good bytes, but bad tzinfo: + with self.assertRaisesRegex(TypeError, '^bad tzinfo state arg$'): + self.theclass(bytes([1] * len(base)), 'EST') # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) From noreply at buildbot.pypy.org Fri Mar 8 23:52:01 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:52:01 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130308225201.298681C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62257:b004dedd9b20 Date: 2013-03-08 17:50 -0500 http://bitbucket.org/pypy/pypy/changeset/b004dedd9b20/ Log: merge default From noreply at buildbot.pypy.org Fri Mar 8 23:52:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:52:02 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20130308225202.F25791C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62258:06591dc39015 Date: 2013-03-08 17:51 -0500 http://bitbucket.org/pypy/pypy/changeset/06591dc39015/ Log: merge heads diff --git a/rpython/rlib/unicodedata/generate_unicodedb.py b/rpython/rlib/unicodedata/generate_unicodedb.py --- a/rpython/rlib/unicodedata/generate_unicodedb.py +++ b/rpython/rlib/unicodedata/generate_unicodedb.py @@ -169,6 +169,13 @@ else: table[int(code, 16)].east_asian_width = width + # Expand ranges + for (first, last), char in ranges.iteritems(): + for code in range(first, last + 1): + assert table[code] is None, 'Multiply defined character %04X' % code + + table[code] = char + # Read Derived Core Properties: for line in derived_core_properties_file: line = line.split('#', 1)[0].strip() @@ -190,13 +197,6 @@ continue table[char].properties += (p,) - # Expand ranges - for (first, last), char in ranges.iteritems(): - for code in range(first, last + 1): - assert table[code] is None, 'Multiply defined character %04X' % code - - table[code] = char - defaultChar = Unicodechar(['0000', None, 'Cn'] + [''] * 12) for code in range(len(table)): if table[code] is None: diff --git a/rpython/rlib/unicodedata/test/test_unicodedata.py b/rpython/rlib/unicodedata/test/test_unicodedata.py --- a/rpython/rlib/unicodedata/test/test_unicodedata.py +++ b/rpython/rlib/unicodedata/test/test_unicodedata.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import random import unicodedata @@ -51,6 +52,8 @@ assert unicodedb_5_2_0.isxidcontinue(ord('_')) assert unicodedb_5_2_0.isxidcontinue(ord('0')) assert not unicodedb_5_2_0.isxidcontinue(ord('(')) + oc = ord(u'日') + assert unicodedb_5_2_0.isxidstart(oc) def test_compare_functions(self): def getX(fun, code): diff --git a/rpython/rlib/unicodedata/unicodedb_3_2_0.py b/rpython/rlib/unicodedata/unicodedb_3_2_0.py --- a/rpython/rlib/unicodedata/unicodedb_3_2_0.py +++ b/rpython/rlib/unicodedata/unicodedb_3_2_0.py @@ -16052,9 +16052,8 @@ ('Lo', 'L', 'H', 7170, 0), ('Lo', 'L', 'N', 6146, 0), ('Lo', 'L', 'N', 7170, 0), -('Lo', 'L', 'W', 4098, 0), -('Lo', 'L', 'W', 4162, 0), ('Lo', 'L', 'W', 7170, 0), +('Lo', 'L', 'W', 7234, 0), ('Lo', 'R', 'N', 7170, 0), ('Lt', 'L', 'N', 7186, 0), ('Lu', 'L', 'A', 7178, 0), @@ -16251,144 +16250,144 @@ _db_pgtbl = ( '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x08\x08\x08\x08\x08\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%\x08\x08\x08&\'()*+,,,,,,,,,,,,' ',,,,,,,,,,,,,-./,0,1,,234,,,,,56,,78,,,9,,,,,,,,,,,:,,;,,,,,,,,,' -'<,,,=,,,,,,,>?,,,,,,,,@,,,,,,,,ABBBBC\x08\x08\x08\x08\x08\x08\x08,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,DEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFBGHIJKL' -'\x08\x08\x08MN\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08OP\x08\x08QRST\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'<,,,=,,,,,,,>?,,,,,,,,@,,,,,,,,A,,,,B\x08\x08\x08\x08\x08\x08\x08,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,CDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEE,FGHIJK' +'\x08\x08\x08LM\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08NO\x08\x08PQRS\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,U\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08BBV\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'W\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,T\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08,,U\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'V\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEW' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEW' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x02\x03\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xe2\xaa\xaa\xa2\xb9\xa2\xaa\xaa\xb1\x8f\xaa\xc3\x9b\x86\x9b\x9emmmmmmmmmm\x9b\xaa\xce\xcd\xce\xaa' -'\xaa((((((((((((((((((((((((((\xb1\xaa\x8f\xbe\x83\xbe\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\xb1\xcd\x8f\xcd\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xdf\xa5\xb9\xb9\xb5\xb9\xda\xd6\xbb\xd9\x10\x96\xcd\x88\xd6\xbe\xd1\xc0uu\xbb\x12\xd6\xa6\xbbu\x10\x93{{{\xa5' -"''''''%'''''''''%''''''\xc6%'''''%\x10\x10\x10\x12\x12\x12\x12\x10\x12\x10\x10\x10\x12\x10\x10\x12\x12\x10\x12\x10\x10\x12\x12\x12\xc6\x10\x10\x10\x12\x10\x12\x10\x12" -"'\x10'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x10'\x10'\x12'\x12'\x12'\x10'\x12'\x12'\x12'\x12'\x12%\x10'\x12'\x10'\x12'\x12'\x10%\x10'\x12'\x12\x10'\x12'\x12'\x12%" -"\x10%\x10'\x10'\x12'\x10\x10%\x10'\x10'\x12'\x12%\x10'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12%\x10'\x12'\x10'\x12'\x12'\x12'\x12'\x12'\x12''\x12'\x12'\x12\x12" -"\x12''\x12'\x12''\x12'''\x12\x12''''\x12''\x12'''\x12\x12\x12''\x12''\x12'\x12'\x12''\x12'\x12\x12'\x12''\x12'''\x12'\x12''\x12\x12\x1f'\x12\x12\x12" -"\x1f\x1f\x1f\x1f'$\x12'$\x12'$\x12'\x10'\x10'\x10'\x10'\x10'\x10'\x10'\x10\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12'$\x12'\x12'''\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r\r\r\r\r\r\r" +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x02\x03\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xe1\xa9\xa9\xa1\xb8\xa1\xa9\xa9\xb0\x8e\xa9\xc2\x9a\x85\x9a\x9dllllllllll\x9a\xa9\xcd\xcc\xcd\xa9' +"\xa9''''''''''''''''''''''''''\xb0\xa9\x8e\xbd\x82\xbd\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\xb0\xcc\x8e\xcc\x01" +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xde\xa4\xb8\xb8\xb4\xb8\xd9\xd5\xba\xd8\x10\x95\xcc\x87\xd5\xbd\xd0\xbftt\xba\x12\xd5\xa5\xbat\x10\x92zzz\xa4' +'&&&&&&$&&&&&&&&&$&&&&&&\xc5$&&&&&$\x10\x10\x10\x12\x12\x12\x12\x10\x12\x10\x10\x10\x12\x10\x10\x12\x12\x10\x12\x10\x10\x12\x12\x12\xc5\x10\x10\x10\x12\x10\x12\x10\x12' +'&\x10&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x10&\x10&\x12&\x12&\x12&\x10&\x12&\x12&\x12&\x12&\x12$\x10&\x12&\x10&\x12&\x12&\x10$\x10&\x12&\x12\x10&\x12&\x12&\x12$' +'\x10$\x10&\x10&\x12&\x10\x10$\x10&\x10&\x12&\x12$\x10&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12$\x10&\x12&\x10&\x12&\x12&\x12&\x12&\x12&\x12&&\x12&\x12&\x12\x12' +'\x12&&\x12&\x12&&\x12&&&\x12\x12&&&&\x12&&\x12&&&\x12\x12\x12&&\x12&&\x12&\x12&\x12&&\x12&\x12\x12&\x12&&\x12&&&\x12&\x12&&\x12\x12\x1f&\x12\x12\x12' +'\x1f\x1f\x1f\x1f&#\x12&#\x12&#\x12&\x10&\x10&\x10&\x10&\x10&\x10&\x10&\x10\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12&#\x12&\x12&&&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' -'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\x19\x19\x19\x19\x19\x19\x19\x19\x19\xbd\xbd\x19\x19\x19\x19\x19' -'\x19\x19\xbd\xbd\xbb\xbd\xbd\xbb\xbd\xbb\xbb\xbb\xbd\xbb\xbd\xbd\x15\x19\xbd\xbd\xbd\xbd\xbd\xbd\xbb\xbb\xbb\xbb\xbd\xbb\xbd\xbb\x19\x19\x19\x19\x19\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x19\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'222222222222222222222311113011111//1111//11111111111.....1111222' -'222226211122211-\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r5542222222222222\r\r\r\r\xbd\xbd\r\r\r\r\x18\r\r\r\xa9\r' -"\r\r\r\r\xbd\xbd'\xa9'''\r'\r''\x12%%%%%%%%%%%%%%%%%\r%%%%%%%''\x12\x12\x12\x12\x12\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10\x12\x10\x10\x10\x10\x10\x10\x10\x12\x12\x12\x12\x12\r\x12\x12'''\x12\x12\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12\x12\x12\x12'\x12\xcb\r\r\r\r\r\r\r\r\r" -"'%''''''''''''''%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12\xd4cccc\r,,'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"''\x12'\x12'\x12'\x12'\x12'\x12'\x12\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r'\x12\r\r\r\r\r\r" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r'''''''''''''''" -"'''''''''''''''''''''''\r\r\x19\xa4\xa4\xa4\xa4\xa4\xa4\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -'\x12\x12\x12\x12\x12\x12\x12\x12\r\xa4\x89\r\r\r\r\r\r`cccc`ccca`cccccc\r`````cc`ccabc;<=>?@ABCD\rEFG\xacH' -'\xacIJ\xacc\r\r\r\r\r\r\r\r\r\r\r###########################\r\r\r\r\r###\xac\xac\r\r\r\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\x9a\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x97\r\r\r\x97\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r' -'\x14\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1cLMNOPQRScc`\r\r\r\r\r\r\r\r\r\rjjjjjjjjjj\xa1\x98\x98\x97\x1c\x1cT\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\x19\x19\x19\x19\x19\x19\x19\x19\x19\xbc\xbc\x19\x19\x19\x19\x19' +'\x19\x19\xbc\xbc\xba\xbc\xbc\xba\xbc\xba\xba\xba\xbc\xba\xbc\xbc\x15\x19\xbc\xbc\xbc\xbc\xbc\xbc\xba\xba\xba\xba\xbc\xba\xbc\xba\x19\x19\x19\x19\x19\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\x19\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'111111111111111111111200002/00000..0000..00000000000-----0000111' +'111115100011100,\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r4431111111111111\r\r\r\r\xbc\xbc\r\r\r\r\x18\r\r\r\xa8\r' +'\r\r\r\r\xbc\xbc&\xa8&&&\r&\r&&\x12$$$$$$$$$$$$$$$$$\r$$$$$$$&&\x12\x12\x12\x12\x12\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x12\x10\x10\x10\x10\x10\x10\x10\x12\x12\x12\x12\x12\r\x12\x12&&&\x12\x12\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12\x12\x12\x12&\x12\xca\r\r\r\r\r\r\r\r\r' +'&$&&&&&&&&&&&&&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x12\x10\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12\xd3bbbb\r++&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r&\x12\r\r\r\r\r\r' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r&&&&&&&&&&&&&&&' +'&&&&&&&&&&&&&&&&&&&&&&&\r\r\x19\xa3\xa3\xa3\xa3\xa3\xa3\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\r\xa3\x88\r\r\r\r\r\r_bbbb_bbb`_bbbbbb\r_____bb_bb`ab:;<=>?@ABC\rDEF\xabG' +'\xabHI\xabb\r\r\r\r\r\r\r\r\r\r\r"""""""""""""""""""""""""""\r\r\r\r\r"""\xab\xab\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\x99\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x96\r\r\r\x96\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r' +'\x14\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1cKLMNOPQRbb_\r\r\r\r\r\r\r\r\r\riiiiiiiiii\xa0\x97\x97\x96\x1c\x1cS\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x97\x1cccccccc\x04,cccc`c\x14\x14cc\xd9`cc`\r\rllllllllll\x1c\x1c\x1c\xd0\xd0\r' -'\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\r\x05\x1cU\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\rc`cc`cc```c``c`c' -'cc`c`c`c`cc\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c77777777777\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x96\x1cbbbbbbb\x04+bbbb_b\x14\x14bb\xd8_bb_\r\rkkkkkkkkkk\x1c\x1c\x1c\xcf\xcf\r' +'\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\r\x05\x1cT\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\rb_bb_bb___b__b_b' +'bb_b_b_b_bb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c66666666666\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r77)\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r9\x1f))' -')77777777)))):\r\r\x1fc`cc\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77\xa4\xa4nnnnnnnnnn\xa4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r7))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r\r\x1f\x1f\x1f\x1f\r\r9\r))' -')7777\r\r))\r\r)):\r\r\r\r\r\r\r\r\r)\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f77\r\rnnnnnnnnnn\x1f\x1f\xb8\xb8yyyyxy\xd4\r\r\r\r\r' -'\r\r7\r\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\r9\r))' -')77\r\r\r\r77\r\r77:\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\r\r\r\r\r\r\rnnnnnnnnnn77\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' -'\r77)\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r9\x1f))' -')77777\r77)\r)):\r\r\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\r\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r7))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\r\r9\x1f)7' -')777\r\r\r))\r\r)):\r\r\r\r\r\r\r\r7)\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f\r\r\r\rnnnnnnnnnn\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r7\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\r\x1f\r\x1f\x1f\r\r\r\x1f\x1f\r\r\r\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\r\r\r))' -'7))\r\r\r)))\r))):\r\r\r\r\r\r\r\r\r)\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rnnnnnnnnnyyy\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r)))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r77' -'7))))\r777\r777:\r\r\r\r\r\r\rVW\r\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r)7' -')))))\r7))\r))7:\r\r\r\r\r\r\r))\r\r\r\r\r\r\r\x1f\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r))' -')777\r\r)))\r))):\r\r\r\r\r\r\r\r\r)\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r))\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r:\r\r\r\r)))777\r7\r))))))))\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r))\xa4\r\r\r\r\r\r\r\r\r\r\r' -'\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f7\x1f\x1e7777XX:\r\r\r\r\xb8' -'\x1f\x1f\x1f\x1f\x1f\x1f\x197YYYY777\xa4nnnnnnnnnn\xa4\xa4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\x1f\x1f\r\x1f\r\r\x1f\x1f\r\x1f\r\r\x1f\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\r\x1f\r\r\x1f\x1f\r\x1f\x1f\x1f\x1f7\x1f\x1e7777ZZ\r77\x1f\r\r' -'\x1f\x1f\x1f\x1f\x1f\r\x19\r[[[[77\r\rnnnnnnnnnn\r\r\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\xd4\xd4\xd4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xd4\xd4\xd4\xd4\xd4``\xd4\xd4\xd4\xd4\xd4\xd4nnnnnnnnnnyyyyyyyyyy\xd4`\xd4`\xd4_\xaf\x8d\xaf\x8d))' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\\]7^77777]]]]7)' -']7cc:\xa4cc\x1f\x1f\x1f\x1f\r\r\r\r77777777\r777777777777777777777777777777777777\r\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4`\xd4\xd4\xd4\xd4\xd4\xd4\r\r\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r)7777)7\r\r\r79):\r\r\r\r\r\r' -'nnnnnnnnnn\xa4\xa4\xa4\xa4\xa4\xa4\x1f\x1f\x1f\x1f\x1f\x1f))77\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r''''''''''''''''''''''''''''''''" -"''''''\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\xa4\r\r\r\r" -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""\r\r\r\r\r"\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\r66(\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r8\x1f((' +'(66666666((((9\r\r\x1fb_bb\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f66\xa3\xa3mmmmmmmmmm\xa3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r6((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r\r\x1f\x1f\x1f\x1f\r\r8\r((' +'(6666\r\r((\r\r((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f66\r\rmmmmmmmmmm\x1f\x1f\xb7\xb7xxxxwx\xd3\r\r\r\r\r' +'\r\r6\r\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\x1f\x1f\r\r8\r((' +'(66\r\r\r\r66\r\r669\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\r\r\r\r\r\r\rmmmmmmmmmm66\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' +'\r66(\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r8\x1f((' +'(66666\r66(\r((9\r\r\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\r\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r6((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r\r\x1f\x1f\x1f\x1f\r\r8\x1f(6' +'(666\r\r\r((\r\r((9\r\r\r\r\r\r\r\r6(\r\r\r\r\x1f\x1f\r\x1f\x1f\x1f\r\r\r\rmmmmmmmmmm\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r6\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\r\x1f\r\x1f\x1f\r\r\r\x1f\x1f\r\r\r\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\r\r\r((' +'6((\r\r\r(((\r(((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rmmmmmmmmmxxx\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r(((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r66' +'6((((\r666\r6669\r\r\r\r\r\r\rUV\r\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\r\r\r(6' +'(((((\r6((\r((69\r\r\r\r\r\r\r((\r\r\r\r\r\r\r\x1f\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r((' +'(666\r\r(((\r(((9\r\r\r\r\r\r\r\r\r(\r\r\r\r\r\r\r\r\x1f\x1f\r\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r((\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r9\r\r\r\r(((666\r6\r((((((((\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r((\xa3\r\r\r\r\r\r\r\r\r\r\r' +'\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f6\x1f\x1e6666WW9\r\r\r\r\xb7' +'\x1f\x1f\x1f\x1f\x1f\x1f\x196XXXX666\xa3mmmmmmmmmm\xa3\xa3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\x1f\x1f\r\x1f\r\r\x1f\x1f\r\x1f\r\r\x1f\r\r\r\r\r\r\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r\x1f\r\x1f\r\r\x1f\x1f\r\x1f\x1f\x1f\x1f6\x1f\x1e6666YY\r66\x1f\r\r' +'\x1f\x1f\x1f\x1f\x1f\r\x19\rZZZZ66\r\rmmmmmmmmmm\r\r\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\xd3\xd3\xd3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xd3\xd3\xd3\xd3\xd3__\xd3\xd3\xd3\xd3\xd3\xd3mmmmmmmmmmxxxxxxxxxx\xd3_\xd3_\xd3^\xae\x8c\xae\x8c((' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r[\\6]66666\\\\\\\\6(' +'\\6bb9\xa3bb\x1f\x1f\x1f\x1f\r\r\r\r66666666\r666666666666666666666666666666666666\r\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3_\xd3\xd3\xd3\xd3\xd3\xd3\r\r\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\r(6666(6\r\r\r68(9\r\r\r\r\r\r' +'mmmmmmmmmm\xa3\xa3\xa3\xa3\xa3\xa3\x1f\x1f\x1f\x1f\x1f\x1f((66\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&' +'&&&&&&\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\xa3\r\r\r\r' +' ' +' \r\r\r\r\r \x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' @@ -16396,7 +16395,7 @@ '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r' '\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\r\x1f\x1f\x1f\x1f\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4nnnnnnnnnyyyyyyyyyyy\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3mmmmmmmmmxxxxxxxxxxx\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r\r\r' '\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' @@ -16408,93 +16407,93 @@ '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa4\xa4\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r' -'\xe1\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xaf\x8d\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa4\xa4\xa4qqq\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f77:\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77:\xa4\xa4\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f77\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r77\r\r\r\r\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f)))7777777))' -'))))))7))777777777:7\xa4\xa4\xa4\x19\xa4\xa4\xa4\xb8\x1f\r\r\rnnnnnnnnnn\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xa9\xa9\xa9\xa9\xa9\xa9\x89\xa9\xa9\xa9\xa9777\x05\rnnnnnnnnnn\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa3\xa3\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r\r' +'\xe0\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xae\x8c\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\xa3\xa3\xa3ppp\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\x1f669\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f669\xa3\xa3\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f66\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\x1f\x1f\x1f\r66\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f(((6666666((' +'((((((6((66666666696\xa3\xa3\xa3\x19\xa3\xa3\xa3\xb7\x1f\r\r\rmmmmmmmmmm\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xa8\xa8\xa8\xa8\xa8\xa8\x88\xa8\xa8\xa8\xa8666\x05\rmmmmmmmmmm\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' '\x1f\x1f\x1f\x19\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\r\r\r\r\r\r\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fa\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12" -"'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12'\x12\r\r\r\r\r\r" -"\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\r\r''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\x12\x12''''''''" -"\x12\x12\x12\x12\x12\x12\r\r''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12\r'\r'\r'\r'\x12\x12\x12\x12\x12\x12\x12\x12''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r" -"\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\x12\x12\x12$$$$$$$$\x12\x12\x12\x12\x12\r\x12\x12''''$\xbd\x12\xbd" -"\xbd\xbd\x12\x12\x12\r\x12\x12''''$\xbd\xbd\xbd\x12\x12\x12\x12\r\r\x12\x12''''\r\xbd\xbd\xbd\x12\x12\x12\x12\x12\x12\x12\x12'''''\xbd\xbd\xbd\r\r\x12\x12\x12\r\x12\x12''''$\xbd\xbd\r" -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xde\x05\x05\x06\n\x88\x89\x89\x88\x88\x88\xa5\xa9\x94\x92\xaf\x95\x94\x92\xaf\x95\xa5\xa5\xa5\xa9\xa5\xa5\xa5\xa5\xdc\xdd\x07\x0b\t\x08\x0c\xe1\x9f\xa1\x9f\x9f\xa1\xa5\xa9\xa9\xa9\x96\x93\xa5\xa9\xa9\xa5\x82' -'\x82\xa9\xa9\xa9\xcb\xb0\x8e\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xcb\r\r\r\r\xa9\r\r\r\r\r\r\r\xe1\x05\x05\x05\x05\r\r\r\r\r\r\x05\x05\x05\x05\x05\x05w\x12\r\ruwwwww\xc2\xc2\xcb\xb0\x8e\x10' -'wuuuuwwwww\xc2\xc2\xcb\xb0\x8e\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb8\xb8\xb5\xb8\xb8\xb8\xb8\xb8\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rcc88cccc888cc,,,,c,,,88c`c8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"\xd9\xd9'\xd6\xd9\xd6\xd9'\xd9\xd6\x12'''\x12\x12'''\x10\xd9'\xd6\xd9\xd9'''''\xd9\xd9\xd9\xd6\xd6\xd9'\xd9%\xd9'\xd9'%''\xd2\x12''\xd9'\x12\x1f\x1f\x1f\x1f\x12\xd9\r\r\x12''" -"\xcc\xcb\xcb\xcb\xcb'\x12\x12\x12\x12\xd9\xcb\r\r\r\r\r\r\r{{}}}}}}{{{{}ooooooooooooqqqqooooooooooqqqqqq" -'qqqp\r\r\r\r\r\r\r\r\r\r\r\r\xc6\xc6\xc6\xc6\xc6\xd6\xd6\xd6\xd6\xd6\xcb\xcb\xd9\xd9\xd9\xd9\xcb\xd9\xd9\xcb\xd9\xd9\xcb\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xd9\xd9\xc6\xd9\xc6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xc6\xcc\xc7\xc7\xcc\xcb\xcb\xc6\xc7\xcc\xcc\xc7\xcc\xcc\xcb\xc6\xcb\xc7\xc2\xc2\xcb\xc7\xcc\xcb\xcb\xcb\xc7\xcc\xcc\xc7\xc6\xc7\xc7\xcc\xcc\xc6\xcc\xc6\xcc\xc6\xc6\xc6\xc6\xc7\xc7\xcc\xc7\xcc\xcc\xcc\xcc\xcc\xc6\xc6\xc6\xc6\xcb\xcc\xcb\xcc\xc7\xc7\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xc7\xcc\xcc\xcc\xc7\xcb\xcb\xcb\xcb\xcb\xc7\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xc7\xc6\xcc\xcb\xc7\xc7\xc7\xc7\xcc\xcc\xc7\xc7\xcb\xcb\xc7\xc7\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xc7\xc7\xcc\xcc\xc7\xc7\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xc6\xcb\xcb\xcc\xc6\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xc6\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xc7' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcc\xcc\xcc\xcc\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcc\xcc\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xb3\x91\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd9\xcb\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd4\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xaf\x8d\xa9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rtttttttttssssssssssstttttttttsss' -'sssssssstttttttttsssssssssss\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' -'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3v{{{{{{{{{{|||||||||{\r' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd6\xd6\xd6\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd6\xc6\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9' -'\xd6\xc6\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd9\xd9\xd6\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd6\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd6\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd9\xd9\xd9\r\r\xd9\xd9\r\xd9\xd9\xd9\xd6\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd6\xd9\xd6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd6\xd9\xd6\xd6\xd6\xd9\xd6\xd6\xd6\xd6\xd9\xd6\xd6\xd9\xc6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\x12\x12\x12\x12\x12\x12\r\r\r\r&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12' +'&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12&\x12\r\r\r\r\r\r' +'\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\r\r&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&' +'\x12\x12\x12\x12\x12\x12\r\r&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12\r&\r&\r&\r&\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r' +'\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\x12\x12\x12########\x12\x12\x12\x12\x12\r\x12\x12&&&&#\xbc\x12\xbc' +'\xbc\xbc\x12\x12\x12\r\x12\x12&&&&#\xbc\xbc\xbc\x12\x12\x12\x12\r\r\x12\x12&&&&\r\xbc\xbc\xbc\x12\x12\x12\x12\x12\x12\x12\x12&&&&&\xbc\xbc\xbc\r\r\x12\x12\x12\r\x12\x12&&&&#\xbc\xbc\r' +'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xdd\x05\x05\x06\n\x87\x88\x88\x87\x87\x87\xa4\xa8\x93\x91\xae\x94\x93\x91\xae\x94\xa4\xa4\xa4\xa8\xa4\xa4\xa4\xa4\xdb\xdc\x07\x0b\t\x08\x0c\xe0\x9e\xa0\x9e\x9e\xa0\xa4\xa8\xa8\xa8\x95\x92\xa4\xa8\xa8\xa4\x81' +'\x81\xa8\xa8\xa8\xca\xaf\x8d\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xa8\xca\r\r\r\r\xa8\r\r\r\r\r\r\r\xe0\x05\x05\x05\x05\r\r\r\r\r\r\x05\x05\x05\x05\x05\x05v\x12\r\rtvvvvv\xc1\xc1\xca\xaf\x8d\x10' +'vttttvvvvv\xc1\xc1\xca\xaf\x8d\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb4\xb7\xb7\xb7\xb7\xb7\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rbb77bbbb777bb++++b+++77b_b7\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8&\xd5\xd8\xd5\xd8&\xd8\xd5\x12&&&\x12\x12&&&\x10\xd8&\xd5\xd8\xd8&&&&&\xd8\xd8\xd8\xd5\xd5\xd8&\xd8$\xd8&\xd8&$&&\xd1\x12&&\xd8&\x12\x1f\x1f\x1f\x1f\x12\xd8\r\r\x12&&' +'\xcb\xca\xca\xca\xca&\x12\x12\x12\x12\xd8\xca\r\r\r\r\r\r\rzz||||||zzzz|nnnnnnnnnnnnppppnnnnnnnnnnpppppp' +'pppo\r\r\r\r\r\r\r\r\r\r\r\r\xc5\xc5\xc5\xc5\xc5\xd5\xd5\xd5\xd5\xd5\xca\xca\xd8\xd8\xd8\xd8\xca\xd8\xd8\xca\xd8\xd8\xca\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xd8\xd8\xc5\xd8\xc5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xc5\xcb\xc6\xc6\xcb\xca\xca\xc5\xc6\xcb\xcb\xc6\xcb\xcb\xca\xc5\xca\xc6\xc1\xc1\xca\xc6\xcb\xca\xca\xca\xc6\xcb\xcb\xc6\xc5\xc6\xc6\xcb\xcb\xc5\xcb\xc5\xcb\xc5\xc5\xc5\xc5\xc6\xc6\xcb\xc6\xcb\xcb\xcb\xcb\xcb\xc5\xc5\xc5\xc5\xca\xcb\xca\xcb\xc6\xc6\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xc6\xcb\xcb\xcb\xc6\xca\xca\xca\xca\xca\xc6\xcb\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xc6\xc5\xcb\xca\xc6\xc6\xc6\xc6\xcb\xcb\xc6\xc6\xca\xca\xc6\xc6\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xc6\xc6\xcb\xcb\xc6\xc6\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xca\xca\xc5\xca\xca\xcb\xc5\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xc5\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xc6' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xcb\xcb\xcb\xcb\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xcb\xcb\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xb2\x90\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd8\xca\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd3\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xae\x8c\xa8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rsssssssssrrrrrrrrrrrsssssssssrrr' +'rrrrrrrrsssssssssrrrrrrrrrrr\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2uzzzzzzzzzz{{{{{{{{{z\r' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd5\xc5\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8' +'\xd5\xc5\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd8\xd8\xd5\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd5\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xca\xca\xca\xca\xca\xca\xca\xca' +'\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd5\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd8\xd8\xd8\r\r\xd8\xd8\r\xd8\xd8\xd8\xd5\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd5\xd8\xd5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd5\xd8\xd5\xd5\xd5\xd8\xd5\xd5\xd5\xd5\xd8\xd5\xd5\xd8\xc5\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\r\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd6\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\r\xd9\xd9\xd9\xd9\r\r\r\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e|||||||||{' -'~~~~~~~~~}~~~~~~~~~}\xd9\r\r\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xb1\x8f\xb1\x8f\xb1\x8f\r\r\r\r\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xd9' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcb\xcb\xcb\xb0\x8e\xb1\x8f\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xb0\x8e\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcb\xcb\xb0\x8e\xb0\x8e\xcc\xcb\xcb\xcb\xcb\xcc\xcb\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xb0\x8e\xcb\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcb\xcc\xcb\xcb\xcc\xcb\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb' -'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcb\xcb\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' -'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcb\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcb\xcc\xcc\xcc\xcb\xcb\xcb\xcb\xcc\xcb\xcb\xcb\xcc\xcc\xcc\xcc\xcc\xcb\xcc\xcb\xcb' +'\r\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd5\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\r\xd8\xd8\xd8\xd8\r\r\r\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d{{{{{{{{{z' +'}}}}}}}}}|}}}}}}}}}|\xd8\r\r\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xca\xca\xca\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xb0\x8e\xb0\x8e\xb0\x8e\r\r\r\r\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xaf\x8d\xb0\x8e\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xaf\x8d\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xca\xca\xca\xca\xca\xca\xca' +'\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xca\xca\xaf\x8d\xaf\x8d\xcb\xca\xca\xca\xca\xcb\xca\xcb\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xaf\x8d\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xcb\xcb\xca\xca\xcb\xca\xcb\xca\xca\xcb\xca\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xca\xcb\xcb\xca\xca\xcb\xcb\xca\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xca\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xca\xca\xca\xca\xcb\xcb\xcb\xca\xca\xca\xca\xcb\xca\xca\xca\xcb\xcb\xcb\xcb\xcb\xca\xcb\xca\xca' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r' -'\xe0\xab\xab\xab\xdb\x1a"r\xb3\x91\xb3\x91\xb3\x91\xb3\x91\xb3\x91\xdb\xdb\xb3\x91\xb3\x91\xb3\x91\xb3\x91\x8a\xb2\x90\x90\xdbrrrrrrrrrehifgg\x8a\x1a\x1a\x1a\x1a\x1a\xdb\xdbrrr\x1a"\xab\xdb\xd9' -'\r"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""""""""""""\r\rdd\xbf\xbf\x1a\x1a"\x8a"""""""""""""""""""""""""""""""' -'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""\x84\x1a\x1a\x1a"' -'\r\r\r\r\r""""""""""""""""""""""""""""""""""""""""\r\r\r\r"""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""""\r\xd5\xd5zzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5""""""""""""""""""""""""\r\r\r\r\r\r\r\r' -'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r""""""""""""""""' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\rzzzzzzzzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\r\r\r\r\r\r\r\r\r\r\r\r\r\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\xd5' -'zzzzzzzzzz\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\r\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\r\r\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5' -'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r\r\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\r' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\r\r\r\r' +'\xdf\xaa\xaa\xaa\xda\x1a q\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xda\xda\xb2\x90\xb2\x90\xb2\x90\xb2\x90\x89\xb1\x8f\x8f\xdaqqqqqqqqqdgheff\x89\x1a\x1a\x1a\x1a\x1a\xda\xdaqqq\x1a \xaa\xda\xd8' +'\r ' +' \r\rcc\xbe\xbe\x1a\x1a \x89 ' +' \x83\x1a\x1a\x1a ' +'\r\r\r\r\r \r\r\r\r ' +' ' +' \r\xd4\xd4yyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4 \r\r\r\r\r\r\r\r' +'\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r ' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\ryyyyyyyyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r~~~~~~~~~~~~~~~\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\xd4' +'yyyyyyyyyy\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4~~~~~~~~~~~~~~~' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' +'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r' ' ' ' ' ' ' @@ -16583,14 +16582,10 @@ ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' -'"""""""""""""\r\r\r\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb' -'\xdb\xdb\xdb\xdb\xdb\xdb\xdb\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' ' +' ' +' \r\r\r\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda' +'\xda\xda\xda\xda\xda\xda\xda\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' ' ' ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' @@ -16603,67 +16598,67 @@ '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' '\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' -'""""""""""""""""""""""""""""""""""""""""""""""\r\r""""""""""""""""' -'"""""""""""""""""""""""""""""""""""""""""""\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' \r\r ' +' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\x12\x12\x12\x12\x12\r\r\r\r\r#K##########\xc2#############\r#####\r#\r' -'##\r##\r##########\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' +'\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\x12\x12\x12\x12\x12\r\r\r\r\r"J""""""""""\xc1"""""""""""""\r"""""\r"\r' +'""\r""\r""""""""""\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\xaf\x8d' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\xae\x8c' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' -'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\xb4\r\r\r' -'----------------\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rcccc\r\r\r\r\r\r\r\r\r\r\r\r\xab\x8a\x8a\x84\x84\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2\x90\xb2' -'\x90\xb2\x90\xb2\x90\xab\xab\r\r\xab\xab\xab\xab\x84\x84\x84\x9c\xab\x9c\r\xab\x9c\xab\xab\x8a\xb2\x90\xb2\x90\xb2\x90\xa3\xab\xab\xc4\x87\xcf\xcf\xcf\r\xab\xba\xa3\xab\r\r\r\r\x1b\x1c\x1b\x1c\x1b\r\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c' +'\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1b\x1b\xb3\r\r\r' +',,,,,,,,,,,,,,,,\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\rbbbb\r\r\r\r\r\r\r\r\r\r\r\r\xaa\x89\x89\x83\x83\xb1\x8f\xb1\x8f\xb1\x8f\xb1\x8f\xb1\x8f\xb1' +'\x8f\xb1\x8f\xb1\x8f\xaa\xaa\r\r\xaa\xaa\xaa\xaa\x83\x83\x83\x9b\xaa\x9b\r\xaa\x9b\xaa\xaa\x89\xb1\x8f\xb1\x8f\xb1\x8f\xa2\xaa\xaa\xc3\x86\xce\xce\xce\r\xaa\xb9\xa2\xaa\r\r\r\r\x1b\x1c\x1b\x1c\x1b\r\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c\x1b\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c' '\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\r\r\x05' -'\r\xa7\xa7\xa0\xb6\xa0\xa7\xa7\xad\x8b\xa7\xc1\x99\x85\x99\x9dkkkkkkkkkk\x99\xa7\xc9\xc8\xc9\xa7\xa7&&&&&&&&&&&&&&&&&&&&&&&&&&\xad\xa7\x8b\xbc\x80' -'\xbc\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xad\xc8\x8b\xc8\xad\x8b\xa8\xae\x8c\xa8\x81\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x17\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' +'\r\xa6\xa6\x9f\xb5\x9f\xa6\xa6\xac\x8a\xa6\xc0\x98\x84\x98\x9cjjjjjjjjjj\x98\xa6\xc8\xc7\xc8\xa6\xa6%%%%%%%%%%%%%%%%%%%%%%%%%%\xac\xa6\x8a\xbb\x7f' +'\xbb\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xac\xc7\x8a\xc7\xac\x8a\xa7\xad\x8b\xa7\x80\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x17\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' '\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\r' -'\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\r\r\r\xb6\xb6\xc8\xbc\xd7\xb6\xb6\r\xd8\xca\xca\xca\xca\xd8\xd8\r\r\r\r\r\r\r\r\r\r\x05\x05\x05\xd9\xd6\r\r' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\ryyyy\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' -'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fp\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\x1d\x1d\x1d\r\r\x1d\x1d\x1d\r\r\r\xb5\xb5\xc7\xbb\xd6\xb5\xb5\r\xd7\xc9\xc9\xc9\xc9\xd7\xd7\r\r\r\r\r\r\r\r\r\r\x05\x05\x05\xd8\xd5\r\r' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\rxxxx\r\r\r\r\r\r\r\r\r\r\r\r\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f' +'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1fo\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"''''''''''''''''''''''''''''''''''''''\r\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" +'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\r\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4**888\xd4\xd4\xd4+*****\x05\x05\x05\x05\x05\x05\x05\x05`````' -'```\xd4\xd4ccccc``\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4cccc\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4' -'\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -"''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''" -"''''''''''''''\x12\x12\x12\x12\x12\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''" -"''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12'\r''\r\r'\r\r''\r\r''''\r''''''''\x12\x12\x12\x12\r\x12\r\x12\x12\x12" -"\x12\r\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12''\r''''\r\r''''''''\r'''''''\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''\r''''\r" -"'''''\r'\r\r\r'''''''\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''" -"''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''" -"''''''''''''''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12''''''''''''''''" -"''''''''''\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r''''''''''''''''''''''''" -"'\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -"\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12'''''''''''''''''''''''''\xc5\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12" -'\x12\x12\x12\xc5\x12\x12\x12\x12\x12\x12\r\r\r\rllllllllllllllllllllllllllllllllllllllllllllllllll' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\r\r\r\r\r\r\r' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3))777\xd3\xd3\xd3*)))))\x05\x05\x05\x05\x05\x05\x05\x05_____' +'___\xd3\xd3bbbbb__\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3bbbb\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3' +'\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\xd3\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +'&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&' +'&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&' +'&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&\r&&\r\r&\r\r&&\r\r&&&&\r&&&&&&&&\x12\x12\x12\x12\r\x12\r\x12\x12\x12' +'\x12\r\x12\x12\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12&&\r&&&&\r\r&&&&&&&&\r&&&&&&&\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&\r&&&&\r' +'&&&&&\r&\r\r\r&&&&&&&\r\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&' +'&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&' +'&&&&&&&&&&&&&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&' +'&&&&&&&&&&\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\r\r\r\r&&&&&&&&&&&&&&&&&&&&&&&&' +'&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\x12\x12\x12\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12&&&&&&&&&&&&&&&&&&&&&&&&&\xc4\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' +'\x12\x12\x12\xc4\x12\x12\x12\x12\x12\x12\r\r\r\rkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' ' ' ' ' ' ' ' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' -'""""""""""""""""""""""""""""""\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' +' \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' diff --git a/rpython/rlib/unicodedata/unicodedb_5_2_0.py b/rpython/rlib/unicodedata/unicodedb_5_2_0.py --- a/rpython/rlib/unicodedata/unicodedb_5_2_0.py +++ b/rpython/rlib/unicodedata/unicodedb_5_2_0.py @@ -134550,8 +134550,6 @@ ('Lo', 'L', 'H', 7170, 0), ('Lo', 'L', 'N', 6146, 0), ('Lo', 'L', 'N', 7170, 0), -('Lo', 'L', 'W', 4098, 0), -('Lo', 'L', 'W', 4162, 0), ('Lo', 'L', 'W', 7170, 0), ('Lo', 'L', 'W', 7234, 0), ('Lo', 'R', 'N', 7170, 0), @@ -134764,155 +134762,155 @@ _db_pgtbl = ( '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123455565575555' '555555555555589:5;5<55=5>55555?@55AB555C5555555D555E55F555555555' -'G555H5555555IJ55555555K55555555LMNNNO\x15PQRSTU55555555555555555555' -'55555555555555555555555VWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXYZ[\\]^_' -'`abcdeeefghijekeleeeeeeeeeeeeeee\x15\x15\x15mneeeeeeeeeee\x15\x15\x15\x15oeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeepqrstuvweeeeeeeeeeeeeeeeeeeeeeeexyzeeeeeeeeeeeee' -'{|5555555}~\x7f55555555555555555555555\x8055555\x8155555555555555555\x825555' -'5555555555555555555555555555555555\x8355555555555555555555555555555' -'55555555555555555555555555555555555555\x845555555555555555\x85\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x87N\x88\x86\x86\x86\x86\x89' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x89' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'\x8a\x8beeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x8c' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x8c' +'G555H5555555IJ55555555K55555555LM555N\x15OPQRST55555555555555555555' +'55555555555555555555555UVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWXYZ[\\]^' +'_`abcdddefghidjdkddddddddddddddd\x15\x15\x15lmddddddddddd\x15\x15\x15\x15nddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'ddddddddddddddddopqrstuvddddddddddddddddddddddddwxyddddddddddddd' +'z{5555555|}~55555555555555555555555\x7f55555\x8055555555555555555\x815555' +'5555555555555555555555555555555555\x8255555555555555555555555555555' +'55555555555555555555555555555555555555\x835555555555555555\x84\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x7f5\x86\x85\x85\x85\x85\x87' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85' +'\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x87' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'\x88\x89dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\x8a' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' +'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\x8a' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xf9\xbb\xbb\xb2\xca\xb2\xbb\xbb\xc2\xa1\xbb\xd6\xad\x97\xad\xad{{{{{{{{{{\xad\xbb\xe3\xe2\xe3\xbb' -'\xbb11111111111111111111111111\xc2\xbb\xa1\xd0\x94\xd0\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc2\xe2\xa1\xe2\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf6\xb5\xca\xca\xc6\xca\xf2\xed\xcd\xf0\x14\xa8\xe2\x06\xed\xd0\xe7\xd8\x86\x86\xcd\x16\xed\xb6\xcd\x86\x14\xa5\x8b\x8b\x8b\xb5' -'000000.000000000.000000\xdb.00000.\x14\x14\x14\x16\x16\x16\x16\x14\x16\x14\x14\x14\x16\x14\x14\x16\x16\x14\x16\x14\x14\x16\x16\x16\xdb\x14\x14\x14\x16\x14\x16\x14\x16' -'0\x140\x160\x160\x160\x160\x160\x160\x160\x140\x140\x160\x160\x160\x140\x160\x160\x160\x160\x16.\x140\x160\x140\x160\x160\x14.\x140\x160\x16\x140\x160\x160\x16.' -'\x14.\x140\x140\x160\x14\x14.\x140\x140\x160\x16.\x140\x160\x160\x160\x160\x160\x160\x160\x160\x16.\x140\x160\x140\x160\x160\x160\x160\x160\x1600\x160\x160\x16\x16' -"\x1600\x160\x1600\x16000\x16\x160000\x1600\x16000\x16\x16\x1600\x1600\x160\x160\x1600\x160\x16\x160\x1600\x16000\x160\x1600\x16\x16'0\x16\x16\x16" -"''''0-\x160-\x160-\x160\x140\x140\x140\x140\x140\x140\x140\x14\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x160-\x160\x16000\x160\x160\x160\x16" -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x16\x16\x1600\x1600\x16' -'\x160\x160000\x160\x160\x160\x160\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xf7\xb9\xb9\xb0\xc8\xb0\xb9\xb9\xc0\x9f\xb9\xd4\xab\x95\xab\xabyyyyyyyyyy\xab\xb9\xe1\xe0\xe1\xb9' +'\xb9//////////////////////////\xc0\xb9\x9f\xce\x92\xce\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc0\xe0\x9f\xe0\x01' +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf4\xb3\xc8\xc8\xc4\xc8\xf0\xeb\xcb\xee\x14\xa6\xe0\x06\xeb\xce\xe5\xd6\x84\x84\xcb\x16\xeb\xb4\xcb\x84\x14\xa3\x89\x89\x89\xb3' +'......,.........,......\xd9,.....,\x14\x14\x14\x16\x16\x16\x16\x14\x16\x14\x14\x14\x16\x14\x14\x16\x16\x14\x16\x14\x14\x16\x16\x16\xd9\x14\x14\x14\x16\x14\x16\x14\x16' +'.\x14.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x14.\x14.\x16.\x16.\x16.\x14.\x16.\x16.\x16.\x16.\x16,\x14.\x16.\x14.\x16.\x16.\x14,\x14.\x16.\x16\x14.\x16.\x16.\x16,' +'\x14,\x14.\x14.\x16.\x14\x14,\x14.\x14.\x16.\x16,\x14.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16,\x14.\x16.\x14.\x16.\x16.\x16.\x16.\x16.\x16..\x16.\x16.\x16\x16' +"\x16..\x16.\x16..\x16...\x16\x16....\x16..\x16...\x16\x16\x16..\x16..\x16.\x16.\x16..\x16.\x16\x16.\x16..\x16...\x16.\x16..\x16\x16'.\x16\x16\x16" +"''''.+\x16.+\x16.+\x16.\x14.\x14.\x14.\x14.\x14.\x14.\x14.\x14\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16.+\x16.\x16...\x16.\x16.\x16.\x16" +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16\x16\x16..\x16..\x16' +'\x16.\x16....\x16.\x16.\x16.\x16.\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d!!\x1d\x1d\x1d\x1d\x1d" -'\x1d\x1d\xcf\xcf\xcd\xcf!\x1f!\x1f\x1f\x1f!\x1f!!\x19\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcd\xcd\xcd\xcd\xcf\xcd\xcf\xcd\x1d\x1d\x1d\x1d\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcf!\xcf\x1d\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' -'=====================><<<<>;<<<<<::<<<<::<<<<<<<<<<<99999<<<<===' -'=====A=<<<===<<8===<<<<=><<=?@@?@@?=============0\x160\x16!\xcf0\x16\x10\x10\x1c\x16\x16\x16\xb9\x10' -'\x10\x10\x10\x10\xcf\xcf0\xba000\x100\x1000\x16.................\x10.......00\x16\x16\x16\x16\x16\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' -'\x14\x14\x16\x14\x14\x14\x14\x14\x14\x14\x16\x16\x16\x16\x160\x16\x16000\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x160\x16\xe00\x1600\x16\x16000' -'0.00000000000000................................\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' -'\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x16\xebppppp660\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'00\x160\x160\x160\x160\x160\x160\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10000000000000000' -'00000000000000000000000\x10\x10\x1d\xb4\xb4\xb4\xb4\xb4\xb4\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x10\xb4\x9a\x10\x10\x10\x10\x10\x10mppppmpppnmppppppmmmmmmppmppnopFGHIJKLMNOOPQR\x9cS' -'\xbdTU\xbdpm\xbdN\x10\x10\x10\x10\x10\x10\x10\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10,,,\xbd\xbd\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x05\x05\x05\x05\x10\x10\xe0\xe0\xd2\xb1\xb1\xc5\xac\xa9\xf0\xf0ppppppppZ[\\\xa9\x10\x10\xa9\xa9\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'\x18$$$$$$$$$$WXYZ[\\]^ppmmpppppmpp\x10xxxxxxxxxx\xb1\xaa\xaa\xa9$$_$$$$$$$$$$$$$$$' +'\x1d\x1d\xcd\xcd\xcb\xcd!\x1f!\x1f\x1f\x1f!\x1f!!\x19\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcb\xcb\xcb\xcb\xcd\xcb\xcd\xcb\x1d\x1d\x1d\x1d\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcd!\xcd\x1d\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd' +';;;;;;;;;;;;;;;;;;;;;<::::<9:::::88::::88:::::::::::77777::::;;;' +';;;;;?;:::;;;::6;;;::::;<::;=>>=>>=;;;;;;;;;;;;;.\x16.\x16!\xcd.\x16\x10\x10\x1c\x16\x16\x16\xb7\x10' +'\x10\x10\x10\x10\xcd\xcd.\xb8...\x10.\x10..\x16,,,,,,,,,,,,,,,,,\x10,,,,,,,..\x16\x16\x16\x16\x16\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' +'\x14\x14\x16\x14\x14\x14\x14\x14\x14\x14\x16\x16\x16\x16\x16.\x16\x16...\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16.\x16\xde.\x16..\x16\x16...' +'.,..............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14' +'\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x16\x14\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16\xe9nnnnn44.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'..\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10...............' +'.......................\x10\x10\x1d\xb2\xb2\xb2\xb2\xb2\xb2\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x10\xb2\x98\x10\x10\x10\x10\x10\x10knnnnknnnlknnnnnnkkkkkknnknnlmnDEFGHIJKLMMNOP\x9aQ' +'\xbbRS\xbbnk\xbbL\x10\x10\x10\x10\x10\x10\x10\x10***************************\x10\x10\x10\x10\x10***\xbb\xbb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x05\x05\x05\x05\x10\x10\xde\xde\xd0\xaf\xaf\xc3\xaa\xa7\xee\xeennnnnnnnXYZ\xa7\x10\x10\xa7\xa7\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'\x18$$$$$$$$$$UVWXYZ[\\nnkknnnnnknn\x10vvvvvvvvvv\xaf\xa8\xa8\xa7$$]$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$\xa9$ppppppp\x056ppppmp\x18\x18pp\xf0mppm$$zzzzzzzzzz$$$\xe6\xe6$' -'\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\x10\x07$`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$pmppmppmmmpmmpmp' -'ppmpmpmpmpp\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$BBBBBBBBBBB$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'}}}}}}}}}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,pppppppmp""\xf0\xb9\xb9\xb9"\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,pppp"ppppppppp"ppp"ppppp\x10\x10\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x10' +'$$$$$$$$$$$$$$$$$$$$\xa7$nnnnnnn\x054nnnnkn\x18\x18nn\xeeknnk$$xxxxxxxxxx$$$\xe4\xe4$' +'\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\x10\x07$^$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$nknnknnkkknkknkn' +'nnknknknknn\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@@@@@@@@@@$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'{{{{{{{{{{*********************************nnnnnnnkn""\xee\xb7\xb7\xb7"\x10\x10\x10\x10\x10' +'**********************nnnn"nnnnnnnnn"nnn"nnnnn\x10\x10\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BBB2''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10D'22" -"2BBBBBBBB2222E2\x10'pmppB\x10\x10''''''''''BB\xb4\xb4||||||||||\xb4\x1d'\x10\x10\x10\x10\x10\x10'''''''" -"\x10B22\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10'\x10\x10\x10''''\x10\x10D'22" -"2BBBB\x10\x1022\x10\x1022E'\x10\x10\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10''\x10'''BB\x10\x10||||||||||''\xc9\xc9\x88\x88\x88\x88\x88\x88\xeb\xc9\x10\x10\x10\x10" -"\x10BB2\x10''''''\x10\x10\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10''\x10''\x10\x10D\x1022" -"2BB\x10\x10\x10\x10BB\x10\x10BBE\x10\x10\x10B\x10\x10\x10\x10\x10\x10\x10''''\x10'\x10\x10\x10\x10\x10\x10\x10||||||||||BB'''B\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10BB2\x10'''''''''\x10'''\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10D'22" -"2BBBBB\x10BB2\x1022E\x10\x10'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x10\xc9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10B22\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10D'2B" -"2BBBB\x10\x1022\x10\x1022E\x10\x10\x10\x10\x10\x10\x10\x10B2\x10\x10\x10\x10''\x10'''BB\x10\x10||||||||||\xeb'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x10B'\x10''''''\x10\x10\x10'''\x10''''\x10\x10\x10''\x10'\x10''\x10\x10\x10''\x10\x10\x10'''\x10\x10\x10''''''''''''\x10\x10\x10\x1022" -"B22\x10\x10\x10222\x10222E\x10\x10'\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10||||||||||\x88\x88\x88\xf0\xf0\xf0\xf0\xf0\xf0\xc9\xf0\x10\x10\x10\x10\x10" -"\x10222\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10\x10'BB" -"B2222\x10BBB\x10BBBE\x10\x10\x10\x10\x10\x10\x10ab\x10''\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x10\x10\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xeb" -"\x10\x1022\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10D'27" -"22222\x10722\x1022BE\x10\x10\x10\x10\x10\x10\x1022\x10\x10\x10\x10\x10\x10\x10'\x10''BB\x10\x10||||||||||\x10\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10\x1022\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''''''''\x10\x10\x10'22" -"2BBBB\x10222\x10222E\x10\x10\x10\x10\x10\x10\x10\x10\x102\x10\x10\x10\x10\x10\x10\x10\x10''BB\x10\x10||||||||||\x88\x88\x88\x88\x88\x88\x10\x10\x10\xeb''''''" -"\x10\x1022\x10''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''\x10'''''''''\x10'\x10\x10" -"'''''''\x10\x10\x10E\x10\x10\x10\x10222BBB\x10B\x1022222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1022\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10''''''''''''''''''''''''''''''''''''''''''''''''B'&BBBBccE\x10\x10\x10\x10\xc9" -"''''''\x1dBddddBBB\xb4||||||||||\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x10''\x10'\x10\x10''\x10'\x10\x10'\x10\x10\x10\x10\x10\x10''''\x10'''''''\x10'''\x10'\x10'\x10\x10''\x10''''B'&BBBBee\x10BB'\x10\x10" -"'''''\x10\x1d\x10ffffBB\x10\x10||||||||||\x10\x10''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'\xeb\xeb\xeb\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\xebmm\xeb\xeb\xeb\xeb\xeb\xeb||||||||||\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xebm\xebm\xebl\xc1\xa0\xc1\xa022" -"''''''''\x10''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10ghBiBBBBBhhhhB2" -"hBppE\xb4pp''''\x10\x10\x10\x10BBBBBBBB\x10BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x10\xeb\xeb" -'\xeb\xeb\xeb\xeb\xeb\xebm\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\xeb\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''''''''''22BBBB2BBBBBD2EE22BB'" -"||||||||||\xb4\xb4\xb4\xb4\xb4\xb4''''''22BB''''BBB'222''2222222'''BBBB'''''''''''" -"''B22BB222222m'2||||||||||222B\xeb\xeb00000000000000000000000000000000" -"000000\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''''''''''''''''''''''''''''''''\xb4\x1d\x10\x10\x10" -'****************************************************************' -"********************************''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''*****''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''******" +"@@@0''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10B'00" +"0@@@@@@@@0000C0\x10'nknn@\x10\x10''''''''''@@\xb2\xb2zzzzzzzzzz\xb2\x1d'\x10\x10\x10\x10\x10\x10'''''''" +"\x10 at 00\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10'\x10\x10\x10''''\x10\x10B'00" +"0@@@@\x10\x1000\x10\x1000C'\x10\x10\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10''\x10'''@@\x10\x10zzzzzzzzzz''\xc7\xc7\x86\x86\x86\x86\x86\x86\xe9\xc7\x10\x10\x10\x10" +"\x10@@0\x10''''''\x10\x10\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10''\x10''\x10\x10B\x1000" +"0@@\x10\x10\x10\x10@@\x10\x10@@C\x10\x10\x10@\x10\x10\x10\x10\x10\x10\x10''''\x10'\x10\x10\x10\x10\x10\x10\x10zzzzzzzzzz@@'''@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10@@0\x10'''''''''\x10'''\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10B'00" +"0@@@@@\x10@@0\x1000C\x10\x10'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x10\xc7\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10 at 00\x10''''''''\x10\x10''\x10\x10''''''''''''''''''''''\x10'''''''\x10''\x10'''''\x10\x10B'0@" +"0@@@@\x10\x1000\x10\x1000C\x10\x10\x10\x10\x10\x10\x10\x10 at 0\x10\x10\x10\x10''\x10'''@@\x10\x10zzzzzzzzzz\xe9'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x10@'\x10''''''\x10\x10\x10'''\x10''''\x10\x10\x10''\x10'\x10''\x10\x10\x10''\x10\x10\x10'''\x10\x10\x10''''''''''''\x10\x10\x10\x1000" +"@00\x10\x10\x10000\x10000C\x10\x10'\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10zzzzzzzzzz\x86\x86\x86\xee\xee\xee\xee\xee\xee\xc7\xee\x10\x10\x10\x10\x10" +"\x10000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10\x10'@@" +"@0000\x10@@@\x10@@@C\x10\x10\x10\x10\x10\x10\x10_`\x10''\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x10\x10\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xe9" +"\x10\x1000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''\x10'''''\x10\x10B'05" +"00000\x10500\x1000 at C\x10\x10\x10\x10\x10\x10\x1000\x10\x10\x10\x10\x10\x10\x10'\x10''@@\x10\x10zzzzzzzzzz\x10\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x1000\x10''''''''\x10'''\x10'''''''''''''''''''''''\x10''''''''''''''''\x10\x10\x10'00" +"0@@@@\x10000\x10000C\x10\x10\x10\x10\x10\x10\x10\x10\x100\x10\x10\x10\x10\x10\x10\x10\x10''@@\x10\x10zzzzzzzzzz\x86\x86\x86\x86\x86\x86\x10\x10\x10\xe9''''''" +"\x10\x1000\x10''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''\x10'''''''''\x10'\x10\x10" +"'''''''\x10\x10\x10C\x10\x10\x10\x10000@@@\x10@\x1000000000\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1000\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10''''''''''''''''''''''''''''''''''''''''''''''''@'&@@@@aaC\x10\x10\x10\x10\xc7" +"''''''\x1d at bbbb@@@\xb2zzzzzzzzzz\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10''\x10'\x10\x10''\x10'\x10\x10'\x10\x10\x10\x10\x10\x10''''\x10'''''''\x10'''\x10'\x10'\x10\x10''\x10''''@'&@@@@cc\x10@@'\x10\x10" +"'''''\x10\x1d\x10dddd@@\x10\x10zzzzzzzzzz\x10\x10''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'\xe9\xe9\xe9\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\xe9kk\xe9\xe9\xe9\xe9\xe9\xe9zzzzzzzzzz\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\xe9k\xe9k\xe9j\xbf\x9e\xbf\x9e00" +"''''''''\x10''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10ef at g@@@@@ffff at 0" +"f at nnC\xb2nn''''\x10\x10\x10\x10@@@@@@@@\x10@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\x10\xe9\xe9" +'\xe9\xe9\xe9\xe9\xe9\xe9k\xe9\xe9\xe9\xe9\xe9\xe9\x10\xe9\xe9\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''''''''''''''''00@@@@0@@@@@B0CC00@@'" +"zzzzzzzzzz\xb2\xb2\xb2\xb2\xb2\xb2''''''00@@''''@@@'000''0000000'''@@@@'''''''''''" +"''@00@@000000k'0zzzzzzzzzz000@\xe9\xe9................................" +"......\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''''''''''''''''''''''''''''''''\xb2\x1d\x10\x10\x10" +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +"((((((((((((((((((((((((((((((((''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''(((((''''''''''''''''''''''''" +"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''((((((" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''\x10''''\x10\x10'''''''\x10'\x10''''\x10\x10''''''''''''''''''''''''''''''''" "'''''''''\x10''''\x10\x10'''''''''''''''''''''''''''''''''\x10''''\x10\x10'''''''\x10" "'\x10''''\x10\x10'''''''''''''''\x10''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''\x10''''\x10\x10''''''''''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''\x10\x10\x10\x10p\xeb\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x89\x89\x89\x89\x89\x89\x89\x89\x89\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10" -"''''''''''''''''\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''\x10\x10\x10\x10n\xe9\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x87\x87\x87\x87\x87\x87\x87\x87\x87\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10" +"''''''''''''''''\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"\x9a'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" +"\x98'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" @@ -134921,125 +134919,125 @@ "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''''''''''''\xb4\xb4'''''''''''''''''" -"\xf8''''''''''''''''''''''''''\xc1\xa0\x10\x10\x10''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''''''''''''''''''''''''\xb4\xb4\xb4\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''\x10''''BBE\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''BBE\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''BB\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''\x10'''\x10BB\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''''''\x08\x082BBBBBBB22" -"222222B22BBBBBBBBBEB\xb4\xb4\xb4\x1d\xb4\xb4\xb4\xc9'p\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x10\x10\x10\x10\x10\x10" -"\xb9\xb9\xb9\xb9\xb9\xb9\x9a\xb9\xb9\xb9\xb9BBB\xf8\x10||||||||||\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''''''\xb2\xb2'''''''''''''''''" +"\xf6''''''''''''''''''''''''''\xbf\x9e\x10\x10\x10''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''''\xb2\xb2\xb2~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'''''''''''''\x10''''@@C\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''@@C\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''@@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''''''''\x10'''\x10@@\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''''''\x08\x080@@@@@@@00" +"000000 at 00@@@@@@@@@C@\xb2\xb2\xb2\x1d\xb2\xb2\xb2\xc7'n\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x10\x10\x10\x10\x10\x10" +"\xb7\xb7\xb7\xb7\xb7\xb7\x98\xb7\xb7\xb7\xb7@@@\xf6\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" "'''\x1d''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''''''''''''''o'\x10\x10\x10\x10\x10''''''''''''''''" +"'''''''''''''''''''''''''''''''''''''''''m'\x10\x10\x10\x10\x10''''''''''''''''" "''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''\x10\x10\x10BBB2222BB222\x10\x10\x10\x1022B222222npm\x10\x10\x10\x10" -"\xf0\x10\x10\x10\xb9\xb9||||||||||''''''''''''''''''''''''''''''\x10\x10'''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x102222222222222222" -"2'''''''22\x10\x10\x10\x10\x10\x10|||||||||||\x10\x10\x10\xb9\xb9\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" -"'''''''''''''''''''''''pm222\x10\x10\xb4\xb4''''''''''''''''''''''''''''''''" -"'''''''''''''''''''''2B2BBBBBBB\x10E2B22BBBBBBBB222222BBpppppppp\x10\x10m" -'||||||||||\x10\x10\x10\x10\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x1d\xb4\xb4\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''\x10\x10\x10@@@0000@@000\x10\x10\x10\x1000 at 000000lnk\x10\x10\x10\x10" +"\xee\x10\x10\x10\xb7\xb7zzzzzzzzzz''''''''''''''''''''''''''''''\x10\x10'''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x100000000000000000" +"0'''''''00\x10\x10\x10\x10\x10\x10zzzzzzzzzzz\x10\x10\x10\xb7\xb7\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee" +"'''''''''''''''''''''''nk000\x10\x10\xb2\xb2''''''''''''''''''''''''''''''''" +"'''''''''''''''''''''0 at 0@@@@@@@\x10C0 at 00@@@@@@@@000000@@nnnnnnnn\x10\x10k" +'zzzzzzzzzz\x10\x10\x10\x10\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x1d\xb2\xb2\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BBBB2'''''''''''''''''''''''''''''''''''''''''''''''D2BBBBB2B222" -"22B23'''''''\x10\x10\x10\x10||||||||||\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebpmppppppp\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10" -"BB2''''''''''''''''''''''''''''''2BBBB22BB3\x10\x10\x10''||||||||||\x10\x10\x10\x10\x10\x10" +"@@@@0'''''''''''''''''''''''''''''''''''''''''''''''B0@@@@@0 at 000" +"00 at 01'''''''\x10\x10\x10\x10zzzzzzzzzz\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9nknnnnnnn\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10" +"@@0''''''''''''''''''''''''''''''0@@@@00@@1\x10\x10\x10''zzzzzzzzzz\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"''''''''''''''''''''''''''''''''''''22222222BBBBBBBB22BD\x10\x10\x10\xb4\xb4\xb4\xb4\xb4" -"||||||||||\x10\x10\x10'''||||||||||''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb4\xb4" +"''''''''''''''''''''''''''''''''''''00000000@@@@@@@@00 at B\x10\x10\x10\xb2\xb2\xb2\xb2\xb2" +"zzzzzzzzzz\x10\x10\x10'''zzzzzzzzzz''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb2\xb2" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10ppp\xb4Cmmmmmppmmmmp2CCCCCCC''''m''''2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10nnn\xb2Akkkkknnkkkkn0AAAAAAA''''k''''0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' '\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' -'ppmpppppppmppqkmjpppppppppppppppppppppp\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10mpm' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\x16\x16\x16\x16\x16\x16\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x10\x10000000\x10\x10\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x16\x1600000000' -'\x16\x16\x16\x16\x16\x16\x10\x10000000\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16\x100\x100\x100\x100\x16\x16\x16\x16\x16\x16\x16\x1600000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10' -'\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x16\x16\x16--------\x16\x16\x16\x16\x16\x10\x16\x160000-\xcf\x16\xcf' -'\xcf\xcf\x16\x16\x16\x10\x16\x160000-\xcf\xcf\xcf\x16\x16\x16\x16\x10\x10\x16\x160000\x10\xcf\xcf\xcf\x16\x16\x16\x16\x16\x16\x16\x1600000\xcf\xcf\xcf\x10\x10\x16\x16\x16\x10\x16\x160000-\xcf\xcf\x10' -'\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\x07\x07\x07\x08\r\x99\x9a\x9a\x99\x99\x99\xb5\xb9\xa6\xa4\xc0\xa7\xa6\xa4\xc0\xa7\xb5\xb5\xb5\xb9\xb5\xb5\xb5\xb5\xf4\xf5\t\x0e\x0c\n\x0f\xf6\xaf\xb1\xaf\xaf\xb1\xb5\xb9\xb9\xb9\xa8\xa5\xb5\xb9\xb9\xb5\x93' -'\x93\xb9\xb9\xb9\xd3\xc1\xa0\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xe0\xb9\x93\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xf8\x07\x07\x07\x07\x07\x10\x10\x10\x10\x10\x07\x07\x07\x07\x07\x07\x87\x1d\x10\x10\x86\x87\x87\x87\x87\x87\xd5\xd5\xe0\xc1\xa0\x19' -'\x87\x86\x86\x86\x86\x87\x87\x87\x87\x87\xd5\xd5\xe0\xc1\xa0\x10\x1d\x1d\x1d\x1d\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc8\xc9\xc9\xc6\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10ppCCppppCCCpp6666p666CCpmpCCmmmmp\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"\xf0\xf00\xed\xf0\xed\xf00\xf0\xed\x16000\x16\x16000\x14\xf00\xed\xf0\xf100000\xf0\xf0\xf0\xed\xed\xf00\xf0.\xf00\xf00.00\xe9\x160000\x16''''\x16\xf0\xf0\x16\x1600" -'\xe1\xe0\xe0\xe0\xe00\x16\x16\x16\x16\xf0\xe0\xf0\xf0\x16\xeb\x8d\x8d\x8d\x8b\x8b\x8d\x8d\x8d\x8d\x8d\x8d\x8b\x8b\x8b\x8b\x8d~~~~~~~~~~~~\x80\x80\x80\x80~~~~~~~~~~\x80\x80\x80\x80\x80\x80' -'\x80\x80\x800\x16\x80\x80\x80\x80\x8b\x10\x10\x10\x10\x10\x10\xdb\xdb\xdb\xdb\xdb\xed\xed\xed\xed\xed\xe0\xe0\xf0\xf0\xf0\xf0\xe0\xf0\xf0\xe0\xf0\xf0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xf0\xf0\xdb\xf0\xdb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xdb\xe1\xdc\xdc\xe1\xe0\xe0\xdb\xdc\xe1\xe1\xdc\xe1\xe1\xe0\xdb\xe0\xdc\xd5\xd9\xe0\xdc\xe1\xe0\xe0\xe0\xdc\xe1\xe1\xdc\xdb\xdc\xdc\xe1\xe1\xdb\xe1\xdb\xe1\xdb\xdb\xdb\xdb\xdc\xdc\xe1\xdc\xe1\xe1\xe1\xe1\xe1\xdb\xdb\xdb\xdb\xe0\xe1\xe0\xe1\xdc\xdc\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xdc\xe1\xe1\xe1\xdc\xe0\xe0\xe0\xe0\xe0\xdc\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xdc\xdb\xe1\xe0\xdc\xdc\xdc\xdc\xe1\xe1\xdc\xdc\xe0\xe0\xdc\xdc\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xdc\xdc\xe1\xe1\xdc\xdc\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xdb\xe0\xe0\xe1\xdb\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xdb\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xdc' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe1\xe1\xe1\xe1\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe1\xe1\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xc4\xa3\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xf0\xe0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8b\x8b' -'\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x86\x86\x86\x86\x86\x86\x86\x86\x86\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' -'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x8e\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8c' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xed\xed\xed\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xed\xdb\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0' -'\xed\xdb\xf0\xf0\xf0\xf0\xed\xed\xed\xf0\xf0\xed\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xed\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xed\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xed\xed\xed\xf0\xed\xed\xed\xed\xf0\xed\xed\xf0\xdb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xeb\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xed' -'\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\x10\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\x10\xed\x10\x10\x10\x10\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed\xed' -'\x10\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xed\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\x10\xf0\xf0\xf0\xf0\x10\x10\x10\xf0\xed\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b' -'\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8d\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8d\xf0\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10' -'\xe1\xe0\xe0\xe1\xe1\xc1\xa0\xe0\xe1\xe1\xe0\x10\xe1\x10\x10\x10\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xc1\xa0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' +'nnknnnnnnnknnoikhnnnnnnnnnnnnnnnnnnnnnn\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10knk' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x10\x10......\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x16\x16........' +'\x16\x16\x16\x16\x16\x16\x10\x10......\x10\x10\x16\x16\x16\x16\x16\x16\x16\x16\x10.\x10.\x10.\x10.\x16\x16\x16\x16\x16\x16\x16\x16........\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10' +'\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x16\x16\x16++++++++\x16\x16\x16\x16\x16\x10\x16\x16....+\xcd\x16\xcd' +'\xcd\xcd\x16\x16\x16\x10\x16\x16....+\xcd\xcd\xcd\x16\x16\x16\x16\x10\x10\x16\x16....\x10\xcd\xcd\xcd\x16\x16\x16\x16\x16\x16\x16\x16.....\xcd\xcd\xcd\x10\x10\x16\x16\x16\x10\x16\x16....+\xcd\xcd\x10' +'\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\x07\x07\x07\x08\r\x97\x98\x98\x97\x97\x97\xb3\xb7\xa4\xa2\xbe\xa5\xa4\xa2\xbe\xa5\xb3\xb3\xb3\xb7\xb3\xb3\xb3\xb3\xf2\xf3\t\x0e\x0c\n\x0f\xf4\xad\xaf\xad\xad\xaf\xb3\xb7\xb7\xb7\xa6\xa3\xb3\xb7\xb7\xb3\x91' +'\x91\xb7\xb7\xb7\xd1\xbf\x9e\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xde\xb7\x91\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xf6\x07\x07\x07\x07\x07\x10\x10\x10\x10\x10\x07\x07\x07\x07\x07\x07\x85\x1d\x10\x10\x84\x85\x85\x85\x85\x85\xd3\xd3\xde\xbf\x9e\x19' +'\x85\x84\x84\x84\x84\x85\x85\x85\x85\x85\xd3\xd3\xde\xbf\x9e\x10\x1d\x1d\x1d\x1d\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc6\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10nnAAnnnnAAAnn4444n444AAnknAAkkkkn\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"\xee\xee.\xeb\xee\xeb\xee.\xee\xeb\x16...\x16\x16...\x14\xee.\xeb\xee\xef.....\xee\xee\xee\xeb\xeb\xee.\xee,\xee.\xee.,..\xe7\x16....\x16''''\x16\xee\xee\x16\x16.." +'\xdf\xde\xde\xde\xde.\x16\x16\x16\x16\xee\xde\xee\xee\x16\xe9\x8b\x8b\x8b\x89\x89\x8b\x8b\x8b\x8b\x8b\x8b\x89\x89\x89\x89\x8b||||||||||||~~~~||||||||||~~~~~~' +'~~~.\x16~~~~\x89\x10\x10\x10\x10\x10\x10\xd9\xd9\xd9\xd9\xd9\xeb\xeb\xeb\xeb\xeb\xde\xde\xee\xee\xee\xee\xde\xee\xee\xde\xee\xee\xde\xee\xee\xee\xee\xee\xee\xee\xde\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xee\xee\xd9\xee\xd9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xd9\xdf\xda\xda\xdf\xde\xde\xd9\xda\xdf\xdf\xda\xdf\xdf\xde\xd9\xde\xda\xd3\xd7\xde\xda\xdf\xde\xde\xde\xda\xdf\xdf\xda\xd9\xda\xda\xdf\xdf\xd9\xdf\xd9\xdf\xd9\xd9\xd9\xd9\xda\xda\xdf\xda\xdf\xdf\xdf\xdf\xdf\xd9\xd9\xd9\xd9\xde\xdf\xde\xdf\xda\xda\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xda\xdf\xdf\xdf\xda\xde\xde\xde\xde\xde\xda\xdf\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xda\xd9\xdf\xde\xda\xda\xda\xda\xdf\xdf\xda\xda\xde\xde\xda\xda\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xda\xda\xdf\xdf\xda\xda\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xde\xde\xd9\xde\xde\xdf\xd9\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xd9\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xda' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xee\xee\xee\xee\xee\xee\xee\xee\xdf\xdf\xdf\xdf\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xdf\xdf\xee\xee\xee\xee\xee\xee\xee\xc2\xa1\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xee\xde\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x89\x89' +'\x89\x89\x89\x89\x89\x89\x89\x89\x84\x84\x84\x84\x84\x84\x84\x84\x84\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8' +'\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\x8c\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89\x8a' '\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xc1\xa0\xc2\xa1\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe0\xe0\xc1\xa0\xc1\xa0\xe1\xe0\xe0\xe0\xe0\xe1\xe0\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xc1\xa0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe0\xe1\xe0\xe0\xe1\xe0\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0' -'\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe0\xe0\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1' -'\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe0\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe0\xe0\xe0\xe0\xe1\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe0\xe1\xe0\xe0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0\xe0' -'\xe0\xe0\xe0\xe0\xe0\xf0\xf0\xe0\xe0\xe0\xe0\xe0\xe0\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xed\xed\xed\xed\xed\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xeb\xd9\xee\xee\xee\xee\xeb\xeb\xee\xee' +'\xeb\xd9\xee\xee\xee\xee\xeb\xeb\xeb\xee\xee\xeb\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde' +'\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xeb\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee\xeb\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xeb\xee\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xeb\xeb\xeb\xee\xeb\xeb\xeb\xeb\xee\xeb\xeb\xee\xd9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xe9\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xeb' +'\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\xeb\x10\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' +'\x10\xee\xee\xee\xee\x10\xee\xee\xee\xee\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xeb\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\x10\xee\xee\xee\xee\x10\x10\x10\xee\xeb\xee\xee\xee\xee\xee\xee\xee\x10\x10\xee\xee\xee\xee\xee\xee\xee\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x89' +'\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8c\x8b\xee\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10' +'\xdf\xde\xde\xdf\xdf\xbf\x9e\xde\xdf\xdf\xde\x10\xdf\x10\x10\x10\xde\xde\xde\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xc0\x9f\xc0\x9f\xc0\x9f\xc0\x9f\xbf\x9e\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xbf\x9e\xc0\x9f\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xde\xde\xde\xde\xde\xde\xde' +'\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xde\xde\xbf\x9e\xbf\x9e\xdf\xde\xde\xde\xde\xdf\xde\xdf\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xbf\x9e\xde\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xdf\xdf\xde\xde\xdf\xde\xdf\xde\xde\xdf\xde\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde' +'\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xde\xdf\xdf\xde\xde\xdf\xdf\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf' +'\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xde\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xde\xde\xde\xde\xdf\xdf\xdf\xde\xde\xde\xde\xdf\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xde\xdf\xde\xde' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde\xde' +'\xde\xde\xde\xde\xde\xee\xee\xde\xde\xde\xde\xde\xde\x10\x10\x10\xee\xee\xee\xee\xee\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'00000000000000000000000000000000000000000000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x100\x16000\x16\x160\x160\x160\x160000\x160\x16\x160\x16\x16\x16\x16\x16\x16\x16\x1d00' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x16\xf0\xf0\xf0\xf0\xf0\xf00\x160\x16ppp\x10\x10\x10\x10\x10\x10\x10\xb9\xb9\xb9\xb9\x8d\xb9\xb9' +'...............................................\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10.\x16...\x16\x16.\x16.\x16.\x16....\x16.\x16\x16.\x16\x16\x16\x16\x16\x16\x16\x1d..' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\xee\xee\xee\xee\xee\xee.\x16.\x16nnn\x10\x10\x10\x10\x10\x10\x10\xb7\xb7\xb7\xb7\x8b\xb7\xb7' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" "''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x1d\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" "'''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''''\x10'''''''\x10'''''''\x10'''''''\x10" -"'''''''\x10'''''''\x10'''''''\x10'''''''\x10pppppppppppppppppppppppppppppppp" -'\xb9\xb9\xa8\xa5\xa8\xa5\xb9\xb9\xb9\xa8\xa5\xb9\xa8\xa5\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x9a\xb9\xb9\x9a\xb9\xa8\xa5\xb9\xb9\xa8\xa5\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xb9\xb9\xb9\xb9\xb9 \xb9\xb9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''\x10'''''''\x10'''''''\x10'''''''\x10nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" +'\xb7\xb7\xa6\xa3\xa6\xa3\xb7\xb7\xb7\xa6\xa3\xb7\xa6\xa3\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\x98\xb7\xb7\x98\xb7\xa6\xa3\xb7\xb7\xa6\xa3\xbf\x9e\xbf\x9e\xbf\x9e\xbf\x9e\xb7\xb7\xb7\xb7\xb7 \xb7\xb7\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10' -'\xf7\xbc\xbc\xbc\xf3\x1e*\x81\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\xf3\xf3\xc4\xa3\xc4\xa3\xc4\xa3\xc4\xa3\x9b\xc3\xa2\xa2\xf3\x81\x81\x81\x81\x81\x81\x81\x81\x81svwtuu\x9b\x1e\x1e\x1e\x1e\x1e\xf3\xf3\x81\x81\x81\x1e*\xbc\xf3\xf0' -'\x10***************************************************************' -'***********************\x10\x10rr\xd1\xd1\x1e\x1e*\x9b*******************************' -'***********************************************************\xbc\x1e\x1e\x1e*' -'\x10\x10\x10\x10\x10*****************************************\x10\x10\x10***************' -'****************************************************************' -'***************\x10\xec\xec\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec************************\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10****************' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\x10\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xea\xea\xea\xea\xea\xea\xea\xea\xf3\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xec' -'\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xf3' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10' +'\xf5\xba\xba\xba\xf1\x1e(\x7f\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\xf1\xf1\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa1\x99\xc1\xa0\xa0\xf1\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7fqturss\x99\x1e\x1e\x1e\x1e\x1e\xf1\xf1\x7f\x7f\x7f\x1e(\xba\xf1\xee' +'\x10(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((((((((((((\x10\x10pp\xcf\xcf\x1e\x1e(\x99(((((((((((((((((((((((((((((((' +'(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((\xba\x1e\x1e\x1e(' +'\x10\x10\x10\x10\x10(((((((((((((((((((((((((((((((((((((((((\x10\x10\x10(((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((((\x10\xea\xea\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10' +'\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10((((((((((((((((' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xf1\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xea' +'\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xf1\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xf1\xf1\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1\xf1\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xf1' '((((()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' @@ -135059,7 +135057,7 @@ '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' ')(()((()()((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((()((((((((((((((((((((((((((((((((((' '(((((((((((()((((((()()(((((((((((((((((((((((((((((((((((((((()' @@ -135140,46 +135138,42 @@ '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'*********************\x1e******************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'****************************************************************' -'*************\x10\x10\x10\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3' -"\xf3\xf3\xf3\xf3\xf3\xf3\xf3\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb4\xb4" -"''''''''''''\x1d\xb9\xb9\xb9''''''''''''''''||||||||||''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x100\x160\x160\x160\x160\x160\x16'p666\xb9\x10\x10\x10\x10\x10\x10\x10\x10pp\xb9!" -"0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''''''''''\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80pp\xb4\xb4\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10" -'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf!!!!!!!!!\xcf\xcf0\x160\x160\x160\x160\x160\x160\x16\x16\x160\x160\x160\x160\x160\x160\x160\x16' -'0\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x160\x16\x1d\x16\x16\x16\x16\x16\x16\x16\x160\x160\x1600\x16' -'0\x160\x160\x160\x16!\xcc\xcc0\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'(((((((((((((((((((((\x1e((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'(((((((((((((\x10\x10\x10\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1' +"\xf1\xf1\xf1\xf1\xf1\xf1\xf1\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''''''''''\x1d\x1d\x1d\x1d\x1d\x1d\xb2\xb2" +"''''''''''''\x1d\xb7\xb7\xb7''''''''''''''''zzzzzzzzzz''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +".\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10.\x16.\x16.\x16.\x16.\x16.\x16'n444\xb7\x10\x10\x10\x10\x10\x10\x10\x10nn\xb7!" +".\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''''''''''''''''''" +"''''''''''''''''''''''''''''''''''''''~~~~~~~~~~nn\xb2\xb2\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10" +'\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd!!!!!!!!!\xcd\xcd.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x16\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16' +'.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16.\x16\x1d\x16\x16\x16\x16\x16\x16\x16\x16.\x16.\x16..\x16' +'.\x16.\x16.\x16.\x16!\xca\xca.\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'''''" -"''B'''E''''B'''''''''''''''''''''''22BB2\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\xeb\xeb\xc9\xe8\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''''''\xb9\xb9\xb9\xb9\x10\x10\x10\x10\x10\x10\x10\x10" -"22''''''''''''''''''''''''''''''''''''''''''''''''''222222222222" -"2222E\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4\xb4||||||||||\x10\x10\x10\x10\x10\x10pppppppppppppppppp''''''\xb4\xb4\xb4'\x10\x10\x10\x10" -"||||||||||''''''''''''''''''''''''''''BBBBBmmm\xb4\xb4''''''''''''''''" -"'''''''BBBBBBBBBBB23\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4*****************************\x10\x10\x10" -"BBB2'''''''''''''''''''''''''''''''''''''''''''''''D22BBBB22B222" -'3\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x10\x1d||||||||||\x10\x10\x10\x10\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''''''''BBBBBB22BB22BB\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''B''''''''B2\x10\x10||||||||||\x10\x10\xb4\xb4\xb4\xb4''''''''''''''''\x1d''''''\xeb\xeb\xeb'2\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''''''''''''''''''''p'ppm''pp'''''pp" -"'p'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''\x1d\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''@'''C''''@'''''''''''''''''''''''00@@0\xee\xee\xee\xee\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\xe9\xe9\xc7\xe6\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''''''\xb7\xb7\xb7\xb7\x10\x10\x10\x10\x10\x10\x10\x10" +"00''''''''''''''''''''''''''''''''''''''''''''''''''000000000000" +"0000C\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2\xb2zzzzzzzzzz\x10\x10\x10\x10\x10\x10nnnnnnnnnnnnnnnnnn''''''\xb2\xb2\xb2'\x10\x10\x10\x10" +"zzzzzzzzzz''''''''''''''''''''''''''''@@@@@kkk\xb2\xb2''''''''''''''''" +"'''''''@@@@@@@@@@@01\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2(((((((((((((((((((((((((((((\x10\x10\x10" +"@@@0'''''''''''''''''''''''''''''''''''''''''''''''B00@@@@00 at 000" +'1\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\x10\x1dzzzzzzzzzz\x10\x10\x10\x10\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"'''''''''''''''''''''''''''''''''''''''''@@@@@@00@@00@@\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"'''@''''''''@0\x10\x10zzzzzzzzzz\x10\x10\xb2\xb2\xb2\xb2''''''''''''''''\x1d''''''\xe9\xe9\xe9'0\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''''''''''''''''''''n'nnk''nn'''''nn" +"'n'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''\x1d\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"'''''''''''''''''''''''''''''''''''22B22B22\xb42E\x10\x10||||||||||\x10\x10\x10\x10\x10\x10" +"'''''''''''''''''''''''''''''''''''00 at 00@00\xb20C\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10" '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' -'((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10****************' -'*******\x10\x10\x10\x10*************************************************\x10\x10\x10\x10' +'((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10((((((((((((((((' +'(((((((\x10\x10\x10\x10(((((((((((((((((((((((((((((((((((((((((((((((((\x10\x10\x10\x10' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' '\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13' @@ -135188,140 +135182,140 @@ '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' -'****************************************************************' -'*******************************************+*******+****+*******' -'**************************************************+*************' -'*****************+*+*****************************************+**' -'**********************************************\x11\x11****************' -'**********************************************\x11\x11****************' -'****************************************************************' -'**************************\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10,V,,,,,,,,,,\xd5,,,,,,,,,,,,,\x10,,,,,\x10,\x10' -',,\x10,,\x10,,,,,,,,,,$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((()((((((()(((()(((((((' +'(((((((((((((((((((((((((((((((((((((((((((((((((()(((((((((((((' +'((((((((((((((((()()((((((((((((((((((((((((((((((((((((((((()((' +'((((((((((((((((((((((((((((((((((((((((((((((\x11\x11((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((\x11\x11((((((((((((((((' +'((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' +'((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' +'\x16\x16\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x16\x16\x16\x16\x16\x10\x10\x10\x10\x10*T**********\xd3*************\x10*****\x10*\x10' +'**\x10**\x10**********$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$######$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\xc0\x9f' +'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\xbe\x9d' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$\x10\x10$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' -'$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$##\xc5\xf0\x10\x10' -'8888888888888888\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xc3\xa2\xbc\x10\x10\x10\x10\x10\x10ppppppp\x10\x10\x10\x10\x10\x10\x10\x10\x10\xbc\x9b\x9b\x95\x95\xc3\xa2\xc3\xa2\xc3\xa2\xc3\xa2\xc3\xa2\xc3' -'\xa2\xc3\xa2\xc3\xa2\xbc\xbc\xc3\xa2\xbc\xbc\xbc\xbc\x95\x95\x95\xae\xbc\xae\x10\xbc\xae\xbc\xbc\x9b\xc4\xa3\xc4\xa3\xc4\xa3\xb3\xbc\xbc\xd7\x98\xe5\xe5\xe4\x10\xbc\xcb\xb3\xbc\x10\x10\x10\x10#$#$#\x10#$#$#$#$#$' +'$$$$$$$$\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10$$$$$$$$$$##\xc3\xee\x10\x10' +'6666666666666666\xba\xba\xba\xba\xba\xba\xba\xc1\xa0\xba\x10\x10\x10\x10\x10\x10nnnnnnn\x10\x10\x10\x10\x10\x10\x10\x10\x10\xba\x99\x99\x93\x93\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1\xa0\xc1' +'\xa0\xc1\xa0\xc1\xa0\xba\xba\xc1\xa0\xba\xba\xba\xba\x93\x93\x93\xac\xba\xac\x10\xba\xac\xba\xba\x99\xc2\xa1\xc2\xa1\xc2\xa1\xb1\xba\xba\xd5\x96\xe3\xe3\xe2\x10\xba\xc9\xb1\xba\x10\x10\x10\x10#$#$#\x10#$#$#$#$#$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\x10\x10\x07' -'\x10\xb7\xb7\xb0\xc7\xb0\xb7\xb7\xbe\x9d\xb7\xd4\xab\x96\xab\xabyyyyyyyyyy\xab\xb7\xde\xdd\xde\xb7\xb7//////////////////////////\xbe\xb7\x9d\xce\x92' -'\xce\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbe\xdd\x9d\xdd\xbe\x9d\xb8\xbf\x9e\xb8\xb8%%%%%%%%%%\x1b%%%%%%%%%%%%%%%' +'\x10\xb5\xb5\xae\xc5\xae\xb5\xb5\xbc\x9b\xb5\xd2\xa9\x94\xa9\xa9wwwwwwwwww\xa9\xb5\xdc\xdb\xdc\xb5\xb5--------------------------\xbc\xb5\x9b\xcc\x90' +'\xcc\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbc\xdb\x9b\xdb\xbc\x9b\xb6\xbd\x9c\xb6\xb6%%%%%%%%%%\x1b%%%%%%%%%%%%%%%' '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x1a\x1a%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x10' -'\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%\x10\x10\x10\xc7\xc7\xdd\xce\xee\xc7\xc7\x10\xef\xdf\xdf\xdf\xdf\xef\xef\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x0b\x0b\x0b\xf0\xed\x10\x10' +'\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%%%%\x10\x10%%%\x10\x10\x10\xc5\xc5\xdb\xcc\xec\xc5\xc5\x10\xed\xdd\xdd\xdd\xdd\xed\xed\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x0b\x0b\x0b\xee\xeb\x10\x10' "''''''''''''\x10''''''''''''''''''''''''''\x10'''''''''''''''''''\x10''\x10'" "''''''''''''''\x10\x10''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10" -'\xb4\xb9\xeb\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x8d\x8d\x8d\x8d\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x8d\x10\x10\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebm\x10\x10' +'\xb2\xb7\xe9\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x8b\x8b\x8b\x8b\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x8b\x10\x10\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9k\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "'''''''''''''''''''''''''''''\x10\x10\x10''''''''''''''''''''''''''''''''" "'''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"'''''''''''''''''''''''''''''''\x10\x88\x88\x88\x88\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" -"'\x80''''''''\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -"''''''''''''''''''''''''''''''\x10\xb4''''''''''''''''''''''''''''''''" -"''''\x10\x10\x10\x10''''''''\xb4\x80\x80\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" -'0000000000000000000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +"'''''''''''''''''''''''''''''''\x10\x86\x86\x86\x86\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10''''''''''''''''" +"'~''''''''~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''\x10\xb2''''''''''''''''''''''''''''''''" +"''''\x10\x10\x10\x10''''''''\xb2~~~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +'........................................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' "\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16''''''''''''''''''''''''''''''''''''''''''''''''" -"''''''''''''''''''''''''''''''\x10\x10||||||||||\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"''''''''''''''''''''''''''''''\x10\x10zzzzzzzzzz\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,\x10\x10,\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10,,\x10\x10\x10,\x10\x10,' -',,,,,,,,,,,,,,,,,,,,,,\x10\xbd\x90\x90\x90\x90\x90\x90\x90\x90\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'******\x10\x10*\x10********************************************\x10**\x10\x10\x10*\x10\x10*' +'**********************\x10\xbb\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,\x90\x90\x90\x90\x90\x90\x10\x10\x10\xb9,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10\xbd' +'**********************\x8e\x8e\x8e\x8e\x8e\x8e\x10\x10\x10\xb7**************************\x10\x10\x10\x10\x10\xbb' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',BBB\x10BB\x10\x10\x10\x10\x10BmBp,,,,\x10,,,\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10pCm\x10\x10\x10\x10E' -'\x91\x91\x91\x91\x90\x90\x90\x90\x10\x10\x10\x10\x10\x10\x10\x10\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\x10\x10\x10\x10\x10\x10\x10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x90\x90\xbd' +'*@@@\x10@@\x10\x10\x10\x10\x10 at k@n****\x10***\x10***************************\x10\x10\x10\x10nAk\x10\x10\x10\x10C' +'\x8f\x8f\x8f\x8f\x8e\x8e\x8e\x8e\x10\x10\x10\x10\x10\x10\x10\x10\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\x10\x10\x10\x10\x10\x10\x10*****************************\x8e\x8e\xbb' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x10\x10\x10\xb9\xb9\xb9\xb9\xb9\xb9\xb9' -',,,,,,,,,,,,,,,,,,,,,,\x10\x10\x90\x90\x90\x90\x90\x90\x90\x90,,,,,,,,,,,,,,,,,,,\x10\x10\x10\x10\x10\x90\x90\x90\x90\x90\x90\x90\x90' +'******************************************************\x10\x10\x10\xb7\xb7\xb7\xb7\xb7\xb7\xb7' +'**********************\x10\x10\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e*******************\x10\x10\x10\x10\x10\x8e\x8e\x8e\x8e\x8e\x8e\x8e\x8e' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' -',,,,,,,,,\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'****************************************************************' +'*********\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x84\x84\x84\x84\x84\x84\x84\x84\x84\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x10' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x82\x82\x82\x82\x82\x82\x82\x82\x82\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -"BB2'''''''''''''''''''''''''''''''''''''''''''''222BBBB22ED\xb4\xb4\x08\xb4\xb4" -'\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +"@@0'''''''''''''''''''''''''''''''''''''''''''''000@@@@00CB\xb2\xb2\x08\xb2\xb2" +'\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" "'''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x7f\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80' -'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x7f\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb4\xb4\xb4\xb4\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~' +'~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xb2\xb2\xb2\xb2\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' "'''''''''''''''''''''''''''''''''''''''''''''''\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb44CCC\xeb\xeb\xeb544444\x07\x07\x07\x07\x07\x07\x07\x07mmmmm' -'mmm\xeb\xebpppppmm\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xebpppp\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb' -'\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xeb\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0ppp\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe922AAA\xe9\xe9\xe9322222\x07\x07\x07\x07\x07\x07\x07\x07kkkkk' +'kkk\xe9\xe9nnnnnkk\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9nnnn\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9' +'\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\xe9\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xeennn\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'00000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16000000000000' -'00000000000000\x16\x16\x16\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16000000000000000000000000' -'00\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160\x1000\x10\x100\x10\x1000\x10\x100000\x1000000000\x16\x16\x16\x16\x10\x16\x10\x16\x16\x16' -'\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x1600\x100000\x10\x1000000000\x100000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600\x100000\x10' -'00000\x100\x10\x10\x100000000\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000' -'000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x1600000000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160000' -'0000000000000000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x160000000000000000' -'0000000000\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10000000000000000000000000' -'0\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\x16\x16\x16\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160000000000000000000000000\xda\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x16\x16\x16\xe1\x16\x16\x16\x16\x16\x160\x16\x10\x10zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0' -'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16............' +'..............\x16\x16\x16\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16........................' +'..\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16.\x10..\x10\x10.\x10\x10..\x10\x10....\x10........\x16\x16\x16\x16\x10\x16\x10\x16\x16\x16' +'\x16\x16\x16\x16\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16..\x10....\x10\x10........\x10.......\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..\x10....\x10' +'.....\x10.\x10\x10\x10.......\x10\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16....................' +'......\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16..........................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16....' +'......................\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16................' +'..........\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x10\x10........................' +'.\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\x16\x16\x16\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.........................\xd8\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x16\x16\x16\xdf\x16\x16\x16\x16\x16\x16.\x16\x10\x10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee' +'\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x86\x10\x10\x10\x10\x10\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xeb\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\xea' -'\x10\x10\xea\x10\x10\x10\xea\x10\x10\x10\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\x10\xea\xea\x10\x10\xea' -'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\xea\xea\xea\x10\x10\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\x84\x84\x84\x84\x84\x84\x84\x84\x84\x84\x84\x10\x10\x10\x10\x10\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe8\xe9\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\xe8' +'\x10\x10\xe8\x10\x10\x10\xe8\x10\x10\x10\xe8\xe8\xe8\xe8\xe8\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\x10\xe8\xe8\x10\x10\xe8' +'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xe8\xe8\xe8\xe8\x10\x10\xe8\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'\xec\xec\xec\xec\xec\xec\xec\xec\xec\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'\xea\xea\xea\xea\xea\xea\xea\xea\xea\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '()((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((' @@ -135372,11 +135366,7 @@ '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' -'****************************************************************' -'****************************************************************' -'****************+***********************************************' -'****************************************************************' -'******************************\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' +'((((((((((((((((((((((((((((((\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' '\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11' @@ -135388,10 +135378,10 @@ '\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' -'8888888888888888888888888888888888888888888888888888888888888888' -'8888888888888888888888888888888888888888888888888888888888888888' -'8888888888888888888888888888888888888888888888888888888888888888' -'888888888888888888888888888888888888888888888888\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' +'6666666666666666666666666666666666666666666666666666666666666666' +'6666666666666666666666666666666666666666666666666666666666666666' +'6666666666666666666666666666666666666666666666666666666666666666' +'666666666666666666666666666666666666666666666666\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' '\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12' From noreply at buildbot.pypy.org Fri Mar 8 23:52:04 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Mar 2013 23:52:04 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130308225204.385071C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62259:be62e7062dea Date: 2013-03-08 17:51 -0500 http://bitbucket.org/pypy/pypy/changeset/be62e7062dea/ Log: merge heads diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -236,11 +236,6 @@ newformat = "".join(newformat) return _time.strftime(newformat, timetuple) -def _call_tzinfo_method(tzinfo, methname, tzinfoarg): - if tzinfo is None: - return None - return getattr(tzinfo, methname)(tzinfoarg) - # Just raise TypeError if the arg isn't None or a string. def _check_tzname(name): if name is not None and not isinstance(name, str): @@ -1336,7 +1331,9 @@ def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of UTC).""" - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(None) offset = _check_utc_offset("utcoffset", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1344,7 +1341,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _utcoffset(self): - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(None) offset = _check_utc_offset("utcoffset", offset) return offset @@ -1355,7 +1354,9 @@ it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", None) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(None) _check_tzname(name) return name @@ -1368,7 +1369,9 @@ need to consult dst() unless you're interested in displaying the DST info. """ - offset = _call_tzinfo_method(self._tzinfo, "dst", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(None) offset = _check_utc_offset("dst", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1376,7 +1379,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _dst(self): - offset = _call_tzinfo_method(self._tzinfo, "dst", None) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(None) offset = _check_utc_offset("dst", offset) return offset @@ -1420,7 +1425,10 @@ ord(string[0]), ord(string[1]), ord(string[2]), ord(string[3]), ord(string[4]), ord(string[5])) self._microsecond = (((us1 << 8) | us2) << 8) | us3 - self._tzinfo = tzinfo + if tzinfo is None or isinstance(tzinfo, _tzinfo_class): + self._tzinfo = tzinfo + else: + raise TypeError("bad tzinfo state arg") def __reduce__(self): return (time, self._getstate()) @@ -1710,7 +1718,9 @@ def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of UTC).""" - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(self) offset = _check_utc_offset("utcoffset", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1718,7 +1728,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _utcoffset(self): - offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(self) offset = _check_utc_offset("utcoffset", offset) return offset @@ -1729,7 +1741,9 @@ it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", self) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(self) _check_tzname(name) return name @@ -1742,7 +1756,9 @@ need to consult dst() unless you're interested in displaying the DST info. """ - offset = _call_tzinfo_method(self._tzinfo, "dst", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(self) offset = _check_utc_offset("dst", offset) if offset is not None: offset = timedelta(minutes=offset) @@ -1750,7 +1766,9 @@ # Return an integer (or None) instead of a timedelta (or None). def _dst(self): - offset = _call_tzinfo_method(self._tzinfo, "dst", self) + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(self) offset = _check_utc_offset("dst", offset) return offset @@ -1907,7 +1925,10 @@ ord(string[7]), ord(string[8]), ord(string[9])) self._year = yhi * 256 + ylo self._microsecond = (((us1 << 8) | us2) << 8) | us3 - self._tzinfo = tzinfo + if tzinfo is None or isinstance(tzinfo, _tzinfo_class): + self._tzinfo = tzinfo + else: + raise TypeError("bad tzinfo state arg") def __reduce__(self): return (self.__class__, self._getstate()) diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -25,6 +25,16 @@ e = raises(TypeError, datetime.datetime, '123') assert e.value.args[0] == 'an integer is required' + datetime.time('\x01' * 6, None) + with raises(TypeError) as e: + datetime.time('\x01' * 6, 123) + assert str(e.value) == "bad tzinfo state arg" + + datetime.datetime('\x01' * 10, None) + with raises(TypeError) as e: + datetime.datetime('\x01' * 10, 123) + assert str(e.value) == "bad tzinfo state arg" + def test_strptime(): import time, sys if sys.version_info < (2, 6): From noreply at buildbot.pypy.org Sat Mar 9 04:15:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 04:15:19 +0100 (CET) Subject: [pypy-commit] pypy default: add an underscore for the implementation-specific tmxxx Message-ID: <20130309031519.9C0331C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62260:76c922af812e Date: 2013-03-08 19:59 -0500 http://bitbucket.org/pypy/pypy/changeset/76c922af812e/ Log: add an underscore for the implementation-specific tmxxx diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -353,7 +353,7 @@ # second-guess timezones or DST. Instead fold whatever adjustments you want # into the minutes argument (and the constructor will normalize). -class tmxxx: +class _tmxxx: ordinal = None @@ -960,7 +960,7 @@ def __add__(self, other): "Add a date to a timedelta." if isinstance(other, timedelta): - t = tmxxx(self._year, + t = _tmxxx(self._year, self._month, self._day + other.days) self._checkOverflow(t.year) @@ -1585,7 +1585,7 @@ hh, mm, ss = self.hour, self.minute, self.second offset = self._utcoffset() if offset: # neither None nor 0 - tm = tmxxx(y, m, d, hh, mm - offset) + tm = _tmxxx(y, m, d, hh, mm - offset) y, m, d = tm.year, tm.month, tm.day hh, mm = tm.hour, tm.minute return _build_struct_time(y, m, d, hh, mm, ss, 0) @@ -1856,7 +1856,7 @@ "Add a datetime and a timedelta." if not isinstance(other, timedelta): return NotImplemented - t = tmxxx(self._year, + t = _tmxxx(self._year, self._month, self._day + other.days, self._hour, From noreply at buildbot.pypy.org Sat Mar 9 04:15:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 04:15:20 +0100 (CET) Subject: [pypy-commit] pypy default: remove this outdated comment Message-ID: <20130309031520.EBEBD1C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62261:12abfbe582c6 Date: 2013-03-08 19:59 -0500 http://bitbucket.org/pypy/pypy/changeset/12abfbe582c6/ Log: remove this outdated comment diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -1540,11 +1540,6 @@ ss = min(ss, 59) # clamp out leap seconds if the platform has them return cls(y, m, d, hh, mm, ss, us) - # XXX This is supposed to do better than we *can* do by using time.time(), - # XXX if the platform supports a more accurate way. The C implementation - # XXX uses gettimeofday on platforms that have it, but that isn't - # XXX available from Python. So now() may return different results - # XXX across the implementations. @classmethod def now(cls, tz=None): "Construct a datetime from time.time() and optional time zone info." From noreply at buildbot.pypy.org Sat Mar 9 04:15:30 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 04:15:30 +0100 (CET) Subject: [pypy-commit] pypy py3k: remove this outdated comment Message-ID: <20130309031530.17FA01C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62262:a71debf85c96 Date: 2013-03-08 20:01 -0500 http://bitbucket.org/pypy/pypy/changeset/a71debf85c96/ Log: remove this outdated comment diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -1418,11 +1418,6 @@ ss = min(ss, 59) # clamp out leap seconds if the platform has them return cls(y, m, d, hh, mm, ss, us) - # XXX This is supposed to do better than we *can* do by using time.time(), - # XXX if the platform supports a more accurate way. The C implementation - # XXX uses gettimeofday on platforms that have it, but that isn't - # XXX available from Python. So now() may return different results - # XXX across the implementations. @classmethod def now(cls, tz=None): "Construct a datetime from time.time() and optional time zone info." From noreply at buildbot.pypy.org Sat Mar 9 04:15:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 04:15:31 +0100 (CET) Subject: [pypy-commit] pypy default: speed up datetime.timedelta(microseconds={float, long}) Message-ID: <20130309031531.B67EF1C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62263:ff6a7d8ef4b1 Date: 2013-03-08 22:02 -0500 http://bitbucket.org/pypy/pypy/changeset/ff6a7d8ef4b1/ Log: speed up datetime.timedelta(microseconds={float,long}) diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -498,37 +498,28 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = _round(microseconds) - seconds, microseconds = divmod(microseconds, 1e6) - assert microseconds == int(microseconds) - assert seconds == int(seconds) - days, seconds = divmod(seconds, 24.*3600.) - assert days == int(days) - assert seconds == int(seconds) - d += int(days) - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 - else: + microseconds = int(_round(microseconds)) seconds, microseconds = divmod(microseconds, 1000000) days, seconds = divmod(seconds, 24*3600) d += days - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 - microseconds = float(microseconds) + s += int(seconds) + microseconds = int(microseconds) + else: + microseconds = int(microseconds) + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += int(seconds) microseconds += usdouble - microseconds = _round(microseconds) + microseconds = int(_round(microseconds)) + assert isinstance(s, int) + assert isinstance(microseconds, int) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 # Just a little bit of carrying possible for microseconds and seconds. - assert isinstance(microseconds, float) - assert int(microseconds) == microseconds - us = int(microseconds) - seconds, us = divmod(us, 1000000) - s += seconds # cant't overflow - assert isinstance(s, int) + seconds, us = divmod(microseconds, 1000000) + s += seconds days, s = divmod(s, 24*3600) d += days From noreply at buildbot.pypy.org Sat Mar 9 04:15:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 04:15:33 +0100 (CET) Subject: [pypy-commit] pypy default: simplify Message-ID: <20130309031533.11F071C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62264:e9feed2a56c2 Date: 2013-03-08 22:07 -0500 http://bitbucket.org/pypy/pypy/changeset/e9feed2a56c2/ Log: simplify diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -25,7 +25,7 @@ return 0 if x == y else 1 if x > y else -1 def _round(x): - return _math.floor(x + 0.5) if x >= 0.0 else _math.ceil(x - 0.5) + return int(_math.floor(x + 0.5) if x >= 0.0 else _math.ceil(x - 0.5)) MINYEAR = 1 MAXYEAR = 9999 @@ -498,7 +498,7 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = int(_round(microseconds)) + microseconds = _round(microseconds) seconds, microseconds = divmod(microseconds, 1000000) days, seconds = divmod(seconds, 24*3600) d += days @@ -511,7 +511,7 @@ d += days s += int(seconds) microseconds += usdouble - microseconds = int(_round(microseconds)) + microseconds = _round(microseconds) assert isinstance(s, int) assert isinstance(microseconds, int) assert abs(s) <= 3 * 24 * 3600 @@ -1498,7 +1498,7 @@ converter = _time.localtime if tz is None else _time.gmtime t, frac = divmod(t, 1.0) - us = int(_round(frac * 1e6)) + us = _round(frac * 1e6) # If timestamp is less than one microsecond smaller than a # full second, us can be rounded up to 1000000. In this case, @@ -1518,7 +1518,7 @@ def utcfromtimestamp(cls, t): "Construct a UTC datetime from a POSIX timestamp (like time.time())." t, frac = divmod(t, 1.0) - us = int(_round(frac * 1e6)) + us = _round(frac * 1e6) # If timestamp is less than one microsecond smaller than a # full second, us can be rounded up to 1000000. In this case, From noreply at buildbot.pypy.org Sat Mar 9 04:15:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 04:15:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: speed up datetime.timedelta(microseconds={float, long}) Message-ID: <20130309031534.52B0D1C39E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62265:555ca1703de0 Date: 2013-03-08 22:09 -0500 http://bitbucket.org/pypy/pypy/changeset/555ca1703de0/ Log: speed up datetime.timedelta(microseconds={float,long}) diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -400,37 +400,28 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = float(_round(microseconds)) - seconds, microseconds = divmod(microseconds, 1e6) - assert microseconds == int(microseconds) - assert seconds == int(seconds) - days, seconds = divmod(seconds, 24.*3600.) - assert days == int(days) - assert seconds == int(seconds) - d += int(days) - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 - else: + microseconds = _round(microseconds) seconds, microseconds = divmod(microseconds, 1000000) days, seconds = divmod(seconds, 24*3600) d += days - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 - microseconds = float(microseconds) + s += int(seconds) + microseconds = int(microseconds) + else: + microseconds = int(microseconds) + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += int(seconds) microseconds += usdouble - microseconds = float(_round(microseconds)) + microseconds = _round(microseconds) + assert isinstance(s, int) + assert isinstance(microseconds, int) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 # Just a little bit of carrying possible for microseconds and seconds. - assert isinstance(microseconds, float) - assert int(microseconds) == microseconds - us = int(microseconds) - seconds, us = divmod(us, 1000000) - s += seconds # cant't overflow - assert isinstance(s, int) + seconds, us = divmod(microseconds, 1000000) + s += seconds days, s = divmod(s, 24*3600) d += days From noreply at buildbot.pypy.org Sat Mar 9 05:51:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 05:51:25 +0100 (CET) Subject: [pypy-commit] pypy default: modernization Message-ID: <20130309045125.69BBE1C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62266:4ffacf3b9058 Date: 2013-03-08 23:50 -0500 http://bitbucket.org/pypy/pypy/changeset/4ffacf3b9058/ Log: modernization diff --git a/lib_pypy/disassembler.py b/lib_pypy/disassembler.py --- a/lib_pypy/disassembler.py +++ b/lib_pypy/disassembler.py @@ -4,6 +4,7 @@ view on things """ +from __future__ import print_function import sys import types import inspect @@ -77,27 +78,25 @@ x = x.func_code if hasattr(x, '__dict__'): xxx - items = x.__dict__.items() - items.sort() + items = sorted(x.__dict__.items()) for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType): - print "Disassembly of %s:" % name + print("Disassembly of %s:" % name) try: dis(x1) except TypeError, msg: - print "Sorry:", msg - print + print("Sorry:", msg) + print() elif hasattr(x, 'co_code'): return disassemble(x) elif isinstance(x, str): return disassemble_string(x) else: - raise TypeError, \ - "don't know how to disassemble %s objects" % \ - type(x).__name__ + raise TypeError("don't know how to disassemble %s objects" % \ + type(x).__name__) def distb(tb=None): """Disassemble a traceback (default: last traceback).""" @@ -105,7 +104,7 @@ try: tb = sys.last_traceback except AttributeError: - raise RuntimeError, "no last traceback to disassemble" + raise RuntimeError("no last traceback to disassemble") while tb.tb_next: tb = tb.tb_next disassemble(tb.tb_frame.f_code, tb.tb_lasti) @@ -148,7 +147,7 @@ extended_arg = 0 i = i+2 if op == EXTENDED_ARG: - extended_arg = oparg*65536L + extended_arg = oparg*65536 if op in hasconst: opargstr = repr(co.co_consts[oparg]) elif op in hasname: @@ -180,54 +179,54 @@ op = ord(c) if i == lasti: xxx - print '-->', + print('-->', end=' ') else: xxx - print ' ', + print(' ', end=' ') if i in labels: xxx - print '>>', + print('>>', end=' ') else: xxx - print ' ', + print(' ', end=' ') xxxx - print repr(i).rjust(4), - print opname[op].ljust(15), + print(repr(i).rjust(4), end=' ') + print(opname[op].ljust(15), end=' ') i = i+1 if op >= HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 i = i+2 xxx - print repr(oparg).rjust(5), + print(repr(oparg).rjust(5), end=' ') if op in hasconst: if constants: xxx - print '(' + repr(constants[oparg]) + ')', + print('(' + repr(constants[oparg]) + ')', end=' ') else: xxx - print '(%d)'%oparg, + print('(%d)'%oparg, end=' ') elif op in hasname: if names is not None: xxx - print '(' + names[oparg] + ')', + print('(' + names[oparg] + ')', end=' ') else: xxx - print '(%d)'%oparg, + print('(%d)'%oparg, end=' ') elif op in hasjrel: xxx - print '(to ' + repr(i + oparg) + ')', + print('(to ' + repr(i + oparg) + ')', end=' ') elif op in haslocal: if varnames: xxx - print '(' + varnames[oparg] + ')', + print('(' + varnames[oparg] + ')', end=' ') else: xxx - print '(%d)' % oparg, + print('(%d)' % oparg, end=' ') elif op in hascompare: xxx - print '(' + cmp_op[oparg] + ')', + print('(' + cmp_op[oparg] + ')', end=' ') xxx - print + print() disco = disassemble # XXX For backwards compatibility From noreply at buildbot.pypy.org Sat Mar 9 05:51:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 05:51:26 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130309045126.B2BD71C39DF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62267:c4ddf78907d3 Date: 2013-03-08 23:51 -0500 http://bitbucket.org/pypy/pypy/changeset/c4ddf78907d3/ Log: merge default diff --git a/lib_pypy/disassembler.py b/lib_pypy/disassembler.py --- a/lib_pypy/disassembler.py +++ b/lib_pypy/disassembler.py @@ -4,6 +4,7 @@ view on things """ +from __future__ import print_function import sys import types import inspect @@ -77,7 +78,7 @@ x = x.__code__ if hasattr(x, '__dict__'): xxx - sorted(x.__dict__.items()) + items = sorted(x.__dict__.items()) for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, From noreply at buildbot.pypy.org Sat Mar 9 06:38:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 06:38:49 +0100 (CET) Subject: [pypy-commit] pypy default: backport some lib_pypy fixes/modernizations from py3k Message-ID: <20130309053849.B942B1C13B1@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62268:9d25b203f026 Date: 2013-03-09 00:13 -0500 http://bitbucket.org/pypy/pypy/changeset/9d25b203f026/ Log: backport some lib_pypy fixes/modernizations from py3k diff --git a/lib_pypy/_md5.py b/lib_pypy/_md5.py --- a/lib_pypy/_md5.py +++ b/lib_pypy/_md5.py @@ -316,7 +316,7 @@ else: padLen = 120 - index - padding = ['\200'] + ['\000'] * 63 + padding = [b'\200'] + [b'\000'] * 63 self.update(padding[:padLen]) # Append length (before padding). diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py --- a/lib_pypy/_pypy_interact.py +++ b/lib_pypy/_pypy_interact.py @@ -4,7 +4,7 @@ import os -def interactive_console(mainmodule=None): +def interactive_console(mainmodule=None, quiet=False): # set sys.{ps1,ps2} just before invoking the interactive interpreter. This # mimics what CPython does in pythonrun.c if not hasattr(sys, 'ps1'): @@ -12,17 +12,18 @@ if not hasattr(sys, 'ps2'): sys.ps2 = '.... ' # - try: - from _pypy_irc_topic import some_topic - text = "And now for something completely different: ``%s''" % ( - some_topic(),) - while len(text) >= 80: - i = text[:80].rfind(' ') - print text[:i] - text = text[i+1:] - print text - except ImportError: - pass + if not quiet: + try: + from _pypy_irc_topic import some_topic + text = "And now for something completely different: ``%s''" % ( + some_topic(),) + while len(text) >= 80: + i = text[:80].rfind(' ') + print(text[:i]) + text = text[i+1:] + print(text) + except ImportError: + pass # try: if not os.isatty(sys.stdin.fileno()): diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py --- a/lib_pypy/_pypy_irc_topic.py +++ b/lib_pypy/_pypy_irc_topic.py @@ -167,7 +167,25 @@ "vg'f yvxryl grzcbenel hagvy sberire" nevtb """ +from string import ascii_uppercase, ascii_lowercase + +def rot13(data): + """ A simple rot-13 encoder since `str.encode('rot13')` was removed from + Python as of version 3.0. It rotates both uppercase and lowercase letters individually. + """ + total = [] + for char in data: + if char in ascii_uppercase: + index = (ascii_uppercase.find(char) + 13) % 26 + total.append(ascii_uppercase[index]) + elif char in ascii_lowercase: + index = (ascii_lowercase.find(char) + 13) % 26 + total.append(ascii_lowercase[index]) + else: + total.append(char) + return "".join(total) + def some_topic(): import time lines = __doc__.splitlines() - return lines[int(time.time()) % len(lines)].decode('rot13') + return rot13(lines[int(time.time()) % len(lines)]) diff --git a/lib_pypy/_structseq.py b/lib_pypy/_structseq.py --- a/lib_pypy/_structseq.py +++ b/lib_pypy/_structseq.py @@ -43,8 +43,7 @@ field.__name__ = name dict['n_fields'] = len(fields_by_index) - extra_fields = fields_by_index.items() - extra_fields.sort() + extra_fields = sorted(fields_by_index.iteritems()) n_sequence_fields = 0 while extra_fields and extra_fields[0][0] == n_sequence_fields: extra_fields.pop(0) diff --git a/lib_pypy/pwd.py b/lib_pypy/pwd.py --- a/lib_pypy/pwd.py +++ b/lib_pypy/pwd.py @@ -167,10 +167,10 @@ from os import getuid uid = getuid() pw = getpwuid(uid) - print "uid %s: %s" % (pw.pw_uid, pw) + print("uid %s: %s" % (pw.pw_uid, pw)) name = pw.pw_name - print "name %r: %s" % (name, getpwnam(name)) - print "All:" + print("name %r: %s" % (name, getpwnam(name))) + print("All:") for pw in getpwall(): - print pw + print(pw) From noreply at buildbot.pypy.org Sat Mar 9 06:38:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 06:38:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130309053851.311621C13B1@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: py3k Changeset: r62269:6823e86baaea Date: 2013-03-09 00:38 -0500 http://bitbucket.org/pypy/pypy/changeset/6823e86baaea/ Log: merge default diff --git a/lib_pypy/_md5.py b/lib_pypy/_md5.py --- a/lib_pypy/_md5.py +++ b/lib_pypy/_md5.py @@ -319,7 +319,7 @@ else: padLen = 120 - index - padding = [0o200] + [0] * 63 + padding = [b'\200'] + [b'\000'] * 63 self.update(padding[:padLen]) # Append length (before padding). diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py --- a/lib_pypy/_pypy_irc_topic.py +++ b/lib_pypy/_pypy_irc_topic.py @@ -168,7 +168,7 @@ """ from string import ascii_uppercase, ascii_lowercase - + def rot13(data): """ A simple rot-13 encoder since `str.encode('rot13')` was removed from Python as of version 3.0. It rotates both uppercase and lowercase letters individually. @@ -184,7 +184,7 @@ else: total.append(char) return "".join(total) - + def some_topic(): import time lines = __doc__.splitlines() diff --git a/lib_pypy/_structseq.py b/lib_pypy/_structseq.py --- a/lib_pypy/_structseq.py +++ b/lib_pypy/_structseq.py @@ -43,8 +43,7 @@ field.__name__ = name dict['n_fields'] = len(fields_by_index) - extra_fields = list(fields_by_index.items()) - extra_fields.sort() + extra_fields = sorted(fields_by_index.items()) n_sequence_fields = 0 while extra_fields and extra_fields[0][0] == n_sequence_fields: extra_fields.pop(0) diff --git a/lib_pypy/pwd.py b/lib_pypy/pwd.py --- a/lib_pypy/pwd.py +++ b/lib_pypy/pwd.py @@ -166,9 +166,9 @@ from os import getuid uid = getuid() pw = getpwuid(uid) - print(("uid %s: %s" % (pw.pw_uid, pw))) + print("uid %s: %s" % (pw.pw_uid, pw)) name = pw.pw_name - print(("name %r: %s" % (name, getpwnam(name)))) + print("name %r: %s" % (name, getpwnam(name))) print("All:") for pw in getpwall(): print(pw) From noreply at buildbot.pypy.org Sat Mar 9 08:00:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 08:00:56 +0100 (CET) Subject: [pypy-commit] pypy default: make sure hg knows this is a copy of _marshal from lib_pypy Message-ID: <20130309070056.9AAE51C0305@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62270:f0497ed91d44 Date: 2013-03-09 02:00 -0500 http://bitbucket.org/pypy/pypy/changeset/f0497ed91d44/ Log: make sure hg knows this is a copy of _marshal from lib_pypy diff --git a/rpython/translator/sandbox/_marshal.py b/rpython/translator/sandbox/_marshal.py --- a/rpython/translator/sandbox/_marshal.py +++ b/rpython/translator/sandbox/_marshal.py @@ -4,9 +4,17 @@ This module contains functions that can read and write Python values in a binary format. The format is specific to Python, but independent of machine architecture issues (e.g., you can write a Python value to a file on a PC, transport the file to a Sun, and read it back there). Details of the format may change between Python versions. """ +# NOTE: This module is used in the Python3 interpreter, but also by +# the "sandboxed" process. It must work for Python2 as well. + import types from _codecs import utf_8_decode, utf_8_encode +try: + intern +except NameError: + from sys import intern + try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -50,7 +58,7 @@ if func: break else: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") func(self, x) def w_long64(self, x): @@ -73,7 +81,7 @@ def dump_none(self, x): self._write(TYPE_NONE) - dispatch[types.NoneType] = dump_none + dispatch[type(None)] = dump_none def dump_bool(self, x): if x: @@ -84,7 +92,7 @@ def dump_stopiter(self, x): if x is not StopIteration: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") self._write(TYPE_STOPITER) dispatch[type(StopIteration)] = dump_stopiter @@ -92,10 +100,11 @@ self._write(TYPE_ELLIPSIS) try: - dispatch[types.EllipsisType] = dump_ellipsis + dispatch[type(Ellipsis)] = dump_ellipsis except NameError: pass + # In Python3, this function is not used; see dump_long() below. def dump_int(self, x): y = x>>31 if y and y != -1: @@ -104,7 +113,7 @@ else: self._write(TYPE_INT) self.w_long(x) - dispatch[types.IntType] = dump_int + dispatch[int] = dump_int def dump_long(self, x): self._write(TYPE_LONG) @@ -119,27 +128,32 @@ self.w_long(len(digits) * sign) for d in digits: self.w_short(d) - dispatch[types.LongType] = dump_long + try: + long + except NameError: + dispatch[int] = dump_long + else: + dispatch[long] = dump_long def dump_float(self, x): write = self._write write(TYPE_FLOAT) - s = `x` + s = repr(x) write(chr(len(s))) write(s) - dispatch[types.FloatType] = dump_float + dispatch[float] = dump_float def dump_complex(self, x): write = self._write write(TYPE_COMPLEX) - s = `x.real` + s = repr(x.real) write(chr(len(s))) write(s) - s = `x.imag` + s = repr(x.imag) write(chr(len(s))) write(s) try: - dispatch[types.ComplexType] = dump_complex + dispatch[complex] = dump_complex except NameError: pass @@ -149,7 +163,7 @@ self._write(TYPE_STRING) self.w_long(len(x)) self._write(x) - dispatch[types.StringType] = dump_string + dispatch[bytes] = dump_string def dump_unicode(self, x): self._write(TYPE_UNICODE) @@ -157,21 +171,26 @@ s, len_s = utf_8_encode(x) self.w_long(len_s) self._write(s) - dispatch[types.UnicodeType] = dump_unicode + try: + unicode + except NameError: + dispatch[str] = dump_unicode + else: + dispatch[unicode] = dump_unicode def dump_tuple(self, x): self._write(TYPE_TUPLE) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.TupleType] = dump_tuple + dispatch[tuple] = dump_tuple def dump_list(self, x): self._write(TYPE_LIST) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.ListType] = dump_list + dispatch[list] = dump_list def dump_dict(self, x): self._write(TYPE_DICT) @@ -179,7 +198,7 @@ self.dump(key) self.dump(value) self._write(TYPE_NULL) - dispatch[types.DictionaryType] = dump_dict + dispatch[dict] = dump_dict def dump_code(self, x): self._write(TYPE_CODE) @@ -253,7 +272,7 @@ try: return self.dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) def r_short(self): lo = ord(self._read(1)) @@ -271,7 +290,7 @@ d = ord(s[3]) x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -281,14 +300,14 @@ b = ord(self._read(1)) c = ord(self._read(1)) d = ord(self._read(1)) - e = long(ord(self._read(1))) - f = long(ord(self._read(1))) - g = long(ord(self._read(1))) - h = long(ord(self._read(1))) + e = ord(self._read(1)) + f = ord(self._read(1)) + g = ord(self._read(1)) + h = ord(self._read(1)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x def load_null(self): @@ -325,10 +344,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = self.r_short() - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long @@ -460,7 +479,7 @@ self.bufpos += 4 x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -470,14 +489,14 @@ b = ord(_read1(self)) c = ord(_read1(self)) d = ord(_read1(self)) - e = long(ord(_read1(self))) - f = long(ord(_read1(self))) - g = long(ord(_read1(self))) - h = long(ord(_read1(self))) + e = ord(_read1(self)) + f = ord(_read1(self)) + g = ord(_read1(self)) + h = ord(_read1(self)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x _load_dispatch = {} @@ -499,7 +518,7 @@ self.bufpos += 1 return _load_dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) except IndexError: raise EOFError @@ -541,10 +560,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = _r_short(self) - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long From noreply at buildbot.pypy.org Sat Mar 9 20:45:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 20:45:21 +0100 (CET) Subject: [pypy-commit] pypy default: have sqlite only build/use a row_cast_map if needed Message-ID: <20130309194521.252B41C13DD@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62271:672017bcae87 Date: 2013-03-09 14:44 -0500 http://bitbucket.org/pypy/pypy/changeset/672017bcae87/ Log: have sqlite only build/use a row_cast_map if needed diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1078,6 +1078,8 @@ self._exhausted = False def _build_row_cast_map(self): + if not self.__con._detect_types: + return self.__row_cast_map = [] for i in xrange(_lib.sqlite3_column_count(self._statement)): converter = None @@ -1211,10 +1213,13 @@ self.column_count = _lib.sqlite3_column_count(self._statement) row = [] for i in xrange(self.column_count): - typ = _lib.sqlite3_column_type(self._statement, i) + if self.__con._detect_types: + converter = self.__row_cast_map[i] + else: + converter = None - converter = self.__row_cast_map[i] if converter is None: + typ = _lib.sqlite3_column_type(self._statement, i) if typ == _lib.SQLITE_NULL: val = None elif typ == _lib.SQLITE_INTEGER: From noreply at buildbot.pypy.org Sat Mar 9 21:11:00 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 21:11:00 +0100 (CET) Subject: [pypy-commit] pypy default: reorder these functions Message-ID: <20130309201100.A55E81C13DD@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62272:3dbab3e443a7 Date: 2013-03-09 15:03 -0500 http://bitbucket.org/pypy/pypy/changeset/3dbab3e443a7/ Log: reorder these functions diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1077,37 +1077,6 @@ self._in_use = False self._exhausted = False - def _build_row_cast_map(self): - if not self.__con._detect_types: - return - self.__row_cast_map = [] - for i in xrange(_lib.sqlite3_column_count(self._statement)): - converter = None - - if self.__con._detect_types & PARSE_COLNAMES: - colname = _lib.sqlite3_column_name(self._statement, i) - if colname is not None: - colname = colname.decode('utf-8') - type_start = -1 - key = None - for pos in range(len(colname)): - if colname[pos] == '[': - type_start = pos + 1 - elif colname[pos] == ']' and type_start != -1: - key = colname[type_start:pos] - converter = converters[key.upper()] - - if converter is None and self.__con._detect_types & PARSE_DECLTYPES: - decltype = _lib.sqlite3_column_decltype(self._statement, i) - if decltype is not None: - decltype = decltype.decode('utf-8') - decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" - if '(' in decltype: - decltype = decltype[:decltype.index('(')] - converter = converters.get(decltype.upper(), None) - - self.__row_cast_map.append(converter) - if sys.version_info[0] < 3: def __check_decodable(self, param): if self.__con.text_factory in (unicode, OptimizedUnicode, @@ -1192,22 +1161,36 @@ else: raise ValueError("parameters are of unsupported type") - def _next(self, cursor): - if self._exhausted: - raise StopIteration - item = self._item + def _build_row_cast_map(self): + if not self.__con._detect_types: + return + self.__row_cast_map = [] + for i in xrange(_lib.sqlite3_column_count(self._statement)): + converter = None - ret = _lib.sqlite3_step(self._statement) - if ret == _lib.SQLITE_DONE: - self._exhausted = True - self._item = None - elif ret != _lib.SQLITE_ROW: - exc = self.__con._get_exception(ret) - _lib.sqlite3_reset(self._statement) - raise exc + if self.__con._detect_types & PARSE_COLNAMES: + colname = _lib.sqlite3_column_name(self._statement, i) + if colname is not None: + colname = colname.decode('utf-8') + type_start = -1 + key = None + for pos in range(len(colname)): + if colname[pos] == '[': + type_start = pos + 1 + elif colname[pos] == ']' and type_start != -1: + key = colname[type_start:pos] + converter = converters[key.upper()] - self._readahead(cursor) - return item + if converter is None and self.__con._detect_types & PARSE_DECLTYPES: + decltype = _lib.sqlite3_column_decltype(self._statement, i) + if decltype is not None: + decltype = decltype.decode('utf-8') + decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" + if '(' in decltype: + decltype = decltype[:decltype.index('(')] + converter = converters.get(decltype.upper(), None) + + self.__row_cast_map.append(converter) def _readahead(self, cursor): self.column_count = _lib.sqlite3_column_count(self._statement) @@ -1218,7 +1201,15 @@ else: converter = None - if converter is None: + if converter is not None: + blob = _lib.sqlite3_column_blob(self._statement, i) + if not blob: + val = None + else: + blob_len = _lib.sqlite3_column_bytes(self._statement, i) + val = bytes(string_at(blob, blob_len)) + val = converter(val) + else: typ = _lib.sqlite3_column_type(self._statement, i) if typ == _lib.SQLITE_NULL: val = None @@ -1236,14 +1227,6 @@ blob = _lib.sqlite3_column_blob(self._statement, i) blob_len = _lib.sqlite3_column_bytes(self._statement, i) val = _BLOB_TYPE(string_at(blob, blob_len)) - else: - blob = _lib.sqlite3_column_blob(self._statement, i) - if not blob: - val = None - else: - blob_len = _lib.sqlite3_column_bytes(self._statement, i) - val = bytes(string_at(blob, blob_len)) - val = converter(val) row.append(val) row = tuple(row) @@ -1251,6 +1234,23 @@ row = self._row_factory(cursor, row) self._item = row + def _next(self, cursor): + if self._exhausted: + raise StopIteration + item = self._item + + ret = _lib.sqlite3_step(self._statement) + if ret == _lib.SQLITE_DONE: + self._exhausted = True + self._item = None + elif ret != _lib.SQLITE_ROW: + exc = self.__con._get_exception(ret) + _lib.sqlite3_reset(self._statement) + raise exc + + self._readahead(cursor) + return item + def _get_description(self): if self._kind == Statement._DML: return None From noreply at buildbot.pypy.org Sat Mar 9 21:11:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Mar 2013 21:11:02 +0100 (CET) Subject: [pypy-commit] pypy default: this variable is internal Message-ID: <20130309201102.2E8771C13DD@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62273:b09b4f5c8026 Date: 2013-03-09 15:09 -0500 http://bitbucket.org/pypy/pypy/changeset/b09b4f5c8026/ Log: this variable is internal diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1193,9 +1193,9 @@ self.__row_cast_map.append(converter) def _readahead(self, cursor): - self.column_count = _lib.sqlite3_column_count(self._statement) row = [] - for i in xrange(self.column_count): + num_cols = _lib.sqlite3_column_count(self._statement) + for i in xrange(num_cols): if self.__con._detect_types: converter = self.__row_cast_map[i] else: From noreply at buildbot.pypy.org Sun Mar 10 12:43:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Mar 2013 12:43:24 +0100 (CET) Subject: [pypy-commit] pypy default: Improve a bit issue #1412: dotviewer python path Message-ID: <20130310114324.D07761C026F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62274:a37006b7fffa Date: 2013-03-10 12:43 +0100 http://bitbucket.org/pypy/pypy/changeset/a37006b7fffa/ Log: Improve a bit issue #1412: dotviewer python path diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -128,7 +128,14 @@ def spawn_local_handler(): if hasattr(sys, 'pypy_objspaceclass'): - python = '/usr/bin/python' + # if 'python' is actually PyPy, e.g. in a virtualenv, then + # try hard to find a real CPython + for python in ['/usr/local/bin/python', '/usr/bin/python']: + if os.path.exists(python): + break + else: + # did not work, fall back to 'python' + python = 'python' else: python = sys.executable args = [python, '-u', GRAPHSERVER, '--stdio'] From noreply at buildbot.pypy.org Sun Mar 10 15:52:07 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 10 Mar 2013 15:52:07 +0100 (CET) Subject: [pypy-commit] pypy default: Don't crash the interpreter when compiling an ast with invalid (non increasing) line numbers Message-ID: <20130310145207.F01481C01AF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r62275:3e8a666e96f0 Date: 2013-03-10 15:51 +0100 http://bitbucket.org/pypy/pypy/changeset/3e8a666e96f0/ Log: Don't crash the interpreter when compiling an ast with invalid (non increasing) line numbers diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py --- a/pypy/interpreter/astcompiler/assemble.py +++ b/pypy/interpreter/astcompiler/assemble.py @@ -424,7 +424,8 @@ if instr.lineno: # compute deltas line = instr.lineno - current_line - assert line >= 0 + if line < 0: + continue addr = offset - current_off # Python assumes that lineno always increases with # increasing bytecode address (lnotab is unsigned char). diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py --- a/pypy/module/_ast/test/test_ast.py +++ b/pypy/module/_ast/test/test_ast.py @@ -314,3 +314,18 @@ ast.fix_missing_locations(m) exc = raises(TypeError, compile, m, "", "exec") + def test_hacked_lineno(self): + import _ast + stmt = '''if 1: + try: + foo + except Exception as error: + bar + except Baz as error: + bar + ''' + mod = compile(stmt, "", "exec", _ast.PyCF_ONLY_AST) + # These lineno are invalid, but should not crash the interpreter. + mod.body[0].body[0].handlers[0].lineno = 7 + mod.body[0].body[0].handlers[1].lineno = 6 + code = compile(mod, "", "exec") From noreply at buildbot.pypy.org Sun Mar 10 19:57:07 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Mar 2013 19:57:07 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: another stupid conflict Message-ID: <20130310185707.317BF1C13EB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62278:653828eef49d Date: 2013-03-10 20:56 +0200 http://bitbucket.org/pypy/pypy/changeset/653828eef49d/ Log: another stupid conflict diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -978,11 +978,7 @@ elif kind == REF: box = BoxPtr(self.cpu.get_ref_value(self.deadframe, num)) elif kind == FLOAT: -<<<<<<< local - box = BoxFloat(self.cpu.get_float_value(self.deadframe,num)) -======= - box = BoxFloat(self.cpu.get_latest_value_float(self.deadframe, num)) ->>>>>>> other + box = BoxFloat(self.cpu.get_float_value(self.deadframe, num)) else: assert 0, "bad kind: %d" % ord(kind) self.liveboxes[num] = box From noreply at buildbot.pypy.org Sun Mar 10 20:25:27 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Sun, 10 Mar 2013 20:25:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Changed mapping of w_objects to shadows: Message-ID: <20130310192527.0922B1C13EB@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r157:665a6c1c322f Date: 2013-03-10 19:26 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/665a6c1c322f/ Log: Changed mapping of w_objects to shadows: Every w_object has at most one shadow and that shadow can not be removed Refactored test for shadow to has_shadow() method to reduce the number of send sites of _shadow Added ObserveeShadow to fix a problem with patching a method in a methoddict (see test test_miniimage.test_cached_methoddict) Readded invalid flag for methoddicts. Removed invalid-flag sets for class-shadows during objspace- generation. Instead, allowed sync_cache-calls before the whole object has been read. diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -236,11 +236,11 @@ return "<%s %s>" % (self.__class__.__name__, self) def __str__(self): - if isinstance(self, W_PointersObject) and self._shadow is not None: + if isinstance(self, W_PointersObject) and self.has_shadow(): return self._shadow.getname() else: name = None - if self.w_class._shadow is not None: + if self.w_class.has_shadow(): name = self.w_class._shadow.name return "a %s" % (name or '?',) @@ -269,6 +269,7 @@ vars = self._vars = [None] * size for i in range(size): # do it by hand for the JIT's sake vars[i] = w_nil + self._shadow = None def at0(self, space, index0): # To test, at0 = in varsize part @@ -279,7 +280,7 @@ self.store(space, index0 + self.instsize(space), w_value) def fetch(self, space, n0): - if self._shadow is not None: + if self.has_shadow(): return self._shadow.fetch(n0) return self._fetch(n0) @@ -287,7 +288,7 @@ return self._vars[n0] def store(self, space, n0, w_value): - if self._shadow is not None: + if self.has_shadow(): return self._shadow.store(n0, w_value) return self._store(n0, w_value) @@ -305,7 +306,7 @@ return self.varsize(space) def size(self): - if self._shadow is not None: + if self.has_shadow(): return self._shadow.size() return self._size() @@ -317,12 +318,13 @@ isinstance(self._vars, list)) def store_shadow(self, shadow): + assert self._shadow is None or self._shadow is shadow self._shadow = shadow @objectmodel.specialize.arg(2) def attach_shadow_of_class(self, space, TheClass): shadow = TheClass(space, self) - self._shadow = shadow + self.store_shadow(shadow) shadow.attach_shadow() return shadow @@ -331,9 +333,9 @@ shadow = self._shadow if not isinstance(shadow, TheClass): if shadow is not None: - shadow.detach_shadow() + raise DetachingShadowError(shadow, TheClass) shadow = self.attach_shadow_of_class(space, TheClass) - shadow.sync_shadow() + shadow.synchronize() return shadow def get_shadow(self, space): @@ -369,6 +371,13 @@ from spyvm.shadow import CachedObjectShadow return self.as_special_get_shadow(space, CachedObjectShadow) + def as_observed_get_shadow(self, space): + from spyvm.shadow import ObserveeShadow + return self.as_special_get_shadow(space, ObserveeShadow) + + def has_shadow(self): + return self._shadow is not None + def become(self, w_other): if not isinstance(w_other, W_PointersObject): return False @@ -508,7 +517,7 @@ self.header, w_other.header = w_other.header, self.header self.literalsize, w_other.literalsize = w_other.literalsize, self.literalsize self.islarge, w_other.islarge = w_other.islarge, self.islarge - self._shadow = w_other._shadow = None + self._shadow, w_other._shadow = w_other._shadow, self._shadow W_AbstractObjectWithIdentityHash._become(self, w_other) return True @@ -594,12 +603,13 @@ """NOT RPYTHON Only for testing""" self.literals = literals - self._shadow = None + if self.has_shadow(): + self._shadow.update() def setbytes(self, bytes): self.bytes = bytes - def as_compiledmethod_get_shadow(self, space): + def as_compiledmethod_get_shadow(self, space=None): from shadow import CompiledMethodShadow if self._shadow is None: self._shadow = CompiledMethodShadow(self) @@ -617,7 +627,8 @@ self.setheader(header) else: self.literals[index0-1] = w_value - self._shadow = None + if self.has_shadow(): + self._shadow.update() def store(self, space, index0, w_v): self.atput0(space, index0, w_v) @@ -650,7 +661,16 @@ def setchar(self, index0, character): assert index0 >= 0 self.bytes[index0] = character - self._shadow = None + if self.has_shadow(): + self._shadow.update() + + def has_shadow(self): + return self._shadow is not None + +class DetachingShadowError(Exception): + def __init__(self, old_shadow, new_shadow_class): + self.old_shadow = old_shadow + self.new_shadow_class = new_shadow_class # Use black magic to create w_nil without running the constructor, # thus allowing it to be used even in the constructor of its own diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -55,8 +55,10 @@ # XXX proto_shadow = instantiate(shadow.ClassShadow) proto_shadow.space = self - proto_shadow.invalid = False + proto_shadow.name = '' proto_shadow.w_superclass = w_Class + proto_shadow.version = shadow.Version() + w_ProtoObjectClass._shadow = None w_ProtoObjectClass.store_shadow(proto_shadow) # at this point, all classes that still lack a w_class are themselves # metaclasses @@ -299,10 +301,10 @@ s._w_self = w_class s.w_superclass = w_superclass s.name = name + s.version = shadow.Version() s.instance_size = instsize s.instance_kind = format s.w_methoddict = None s.instance_varsized = varsized or format != shadow.POINTERS - s.invalid = False w_class.store_shadow(s) return w_class diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -23,40 +23,37 @@ def getname(self): return repr(self) def attach_shadow(self): pass - def detach_shadow(self): pass - def sync_shadow(self): pass - + def synchronize(self): pass + class AbstractCachingShadow(AbstractShadow): + _immutable_fields_ = ['version?'] _attr_ = [] def __init__(self, space, w_self): AbstractShadow.__init__(self, space, w_self) + self.version = Version() - def detach_shadow(self): - self.invalidate_shadow() + def attach_shadow(self): + self.w_self().store_shadow(self) + self.update() - def invalidate_shadow(self): + def update(self): """This should get called whenever the base Smalltalk object changes.""" - self._w_self.store_shadow(None) + self.sync_cache() - def attach_shadow(self): - self.update_shadow() - - def sync_shadow(self): - pass - - def update_shadow(self): - self.w_self().store_shadow(self) - self.sync_cache() + def synchronize(self): + self.update() def sync_cache(self): raise NotImplementedError() def store(self, n0, w_value): - self.invalidate_shadow() AbstractShadow.store(self, n0, w_value) + self.update() +class Version: + pass # ____________________________________________________________ POINTERS = 0 @@ -77,55 +74,63 @@ (i.e. used as the class of another Smalltalk object). """ - _immutable_fields_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"] + _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"] - name = None def __init__(self, space, w_self): - self.name = "" + # fields added here should also be in objspace.py:60ff, 300ff + self.name = '' AbstractCachingShadow.__init__(self, space, w_self) def getname(self): return "%s class" % (self.name or '?',) def sync_cache(self): + from spyvm.objspace import UnwrappingError "Update the ClassShadow with data from the w_self class." w_self = self.w_self() + if w_self.size() == 0: + return + # read and painfully decode the format - classformat = self.space.unwrap_int( - w_self._fetch(constants.CLASS_FORMAT_INDEX)) - # The classformat in Squeak, as an integer value, is: - # <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec> - # <6 bits=instSize\\64><1 bit=0> - # In Slang the value is read directly as a boxed integer, so that - # the code gets a "pointer" whose bits are set as above, but - # shifted one bit to the left and with the lowest bit set to 1. + try: + classformat = self.space.unwrap_int( + w_self._fetch(constants.CLASS_FORMAT_INDEX)) + # The classformat in Squeak, as an integer value, is: + # <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec> + # <6 bits=instSize\\64><1 bit=0> + # In Slang the value is read directly as a boxed integer, so that + # the code gets a "pointer" whose bits are set as above, but + # shifted one bit to the left and with the lowest bit set to 1. - # compute the instance size (really the size, not the number of bytes) - instsize_lo = (classformat >> 1) & 0x3F - instsize_hi = (classformat >> (9 + 1)) & 0xC0 - self.instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr - # decode the instSpec - format = (classformat >> 7) & 15 - self.instance_varsized = format >= 2 - if format < 4: - self.instance_kind = POINTERS - elif format == 4: - self.instance_kind = WEAK_POINTERS - elif format == 6: - self.instance_kind = WORDS - if self.instance_size != 0: - raise ClassShadowError("can't have both words and a non-zero " - "base instance size") - elif 8 <= format <= 11: - self.instance_kind = BYTES - if self.instance_size != 0: - raise ClassShadowError("can't have both bytes and a non-zero " - "base instance size") - elif 12 <= format <= 15: - self.instance_kind = COMPILED_METHOD - else: - raise ClassShadowError("unknown format %d" % (format,)) + # compute the instance size (really the size, not the number of bytes) + instsize_lo = (classformat >> 1) & 0x3F + instsize_hi = (classformat >> (9 + 1)) & 0xC0 + self.instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr + # decode the instSpec + format = (classformat >> 7) & 15 + self.instance_varsized = format >= 2 + if format < 4: + self.instance_kind = POINTERS + elif format == 4: + self.instance_kind = WEAK_POINTERS + elif format == 6: + self.instance_kind = WORDS + if self.instance_size != 0: + raise ClassShadowError("can't have both words and a non-zero " + "base instance size") + elif 8 <= format <= 11: + self.instance_kind = BYTES + if self.instance_size != 0: + raise ClassShadowError("can't have both bytes and a non-zero " + "base instance size") + elif 12 <= format <= 15: + self.instance_kind = COMPILED_METHOD + else: + raise ClassShadowError("unknown format %d" % (format,)) + except UnwrappingError: + assert w_self._fetch(constants.CLASS_FORMAT_INDEX) is self.space.w_nil + pass # not enough information stored in w_self, yet self.guess_class_name() @@ -140,8 +145,11 @@ else: assert isinstance(w_superclass, model.W_PointersObject) self.w_superclass = w_superclass + self.version = Version() def guess_class_name(self): + if self.name != '': + return self.name w_self = self.w_self() w_name = None @@ -164,6 +172,9 @@ if isinstance(w_name, model.W_BytesObject): self.name = w_name.as_string() + else: + self.name = None + self.version = Version() def new(self, extrasize=0): w_cls = self.w_self() @@ -215,15 +226,6 @@ " Number of named instance variables for each instance of this class " return self.instance_size - def inherits_from(self, s_superclass): - classshadow = self - while classshadow is not None: - if classshadow is s_superclass: - return True - classshadow = classshadow.s_superclass() - else: - return False - # _______________________________________________________________ # Methods for querying the format word, taken from the blue book: @@ -241,12 +243,25 @@ look_in_shadow = look_in_shadow.s_superclass() raise MethodNotFound(self, w_selector) + # _______________________________________________________________ + # Methods used only in testing + + def inherits_from(self, s_superclass): + classshadow = self + while classshadow is not None: + if classshadow is s_superclass: + return True + classshadow = classshadow.s_superclass() + else: + return False + def initialize_methoddict(self): "NOT_RPYTHON" # this is only for testing. if self.w_methoddict is None: self.w_methoddict = model.W_PointersObject(None, 2) self.w_methoddict._store(1, model.W_PointersObject(None, 0)) - self.s_methoddict().invalid = False + self.s_methoddict().sync_cache() + self.s_methoddict().invalid = False def installmethod(self, w_selector, w_method): "NOT_RPYTHON" # this is only for testing. @@ -259,16 +274,36 @@ class MethodDictionaryShadow(AbstractCachingShadow): + _immutable_fields_ = ['invalid?'] + + def __init__(self, space, w_self): + self.invalid = True + AbstractCachingShadow.__init__(self, space, w_self) + + def find_selector(self, w_selector): + if self.invalid: + self.sync_cache() + jit.promote(self) + version = self.version + jit.promote(version) + return self._safe_find_selector(w_selector, version) + @jit.elidable - def find_selector(self, w_selector): + def _safe_find_selector(self, w_selector, version): + assert version is self.version return self.methoddict.get(w_selector, None) + def update(self): + # Sync_cache at this point has not the desired effect, because in + # the Smalltalk Implementation, the dictionary changes first. Afterwards + # its contents array is filled with the value belonging to the new key. + self.invalid = True + def sync_cache(self): w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX) assert isinstance(w_values, model.W_PointersObject) - s_values = w_values.get_shadow(self.space) - # XXX Should add! - # s_values.notifyinvalid(self) + s_values = w_values.as_observed_get_shadow(self.space) + s_values.notify(self) size = self.w_self().size() - constants.METHODDICT_NAMES_INDEX self.methoddict = {} for i in range(size): @@ -283,6 +318,8 @@ self.methoddict[w_selector] = w_compiledmethod selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector + self.version = Version() + self.invalid = False class AbstractRedirectingShadow(AbstractShadow): @@ -310,12 +347,12 @@ self.copy_from_w_self(i) w_self._vars = None - def detach_shadow(self): - w_self = self.w_self() - assert isinstance(w_self, model.W_PointersObject) - w_self._vars = [self.space.w_nil] * self._w_self_size - for i in range(self._w_self_size): - self.copy_to_w_self(i) + # def detach_shadow(self): + # w_self = self.w_self() + # assert isinstance(w_self, model.W_PointersObject) + # w_self._vars = [self.space.w_nil] * self._w_self_size + # for i in range(self._w_self_size): + # self.copy_to_w_self(i) def copy_from_w_self(self, n0): self.store(n0, self.w_self()._fetch(n0)) @@ -846,14 +883,31 @@ return '%s %s (%i)' % (block, self.w_method().get_identifier_string(), self.pc() + 1) class CompiledMethodShadow(object): - _immutable_fields_ = ["_w_self", "bytecode", - "literals[*]", "bytecodeoffset", - "literalsize", "tempsize", "primitive", - "argsize", "islarge", - "w_compiledin"] + _attr_ = ["_w_self", "bytecode", + "literals[*]", "bytecodeoffset", + "literalsize", "tempsize", "primitive", + "argsize", "islarge", + "w_compiledin"] + _immutable_fields_ = ["version?", "_w_self"] def __init__(self, w_compiledmethod): self._w_self = w_compiledmethod + self.update() + + def w_self(self): + return self._w_self + + def getliteral(self, index): + return self.literals[index] + + def getliteralsymbol(self, index): + w_literal = self.getliteral(index) + assert isinstance(w_literal, model.W_BytesObject) + return w_literal.as_string() # XXX performance issue here + + def update(self): + w_compiledmethod = self._w_self + self.version = Version() self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() @@ -876,32 +930,13 @@ association = wrapper.AssociationWrapper(None, w_association) self.w_compiledin = association.value() - def w_self(self): - return self._w_self - - def getliteral(self, index): - return self.literals[index] - - def getliteralsymbol(self, index): - w_literal = self.getliteral(index) - assert isinstance(w_literal, model.W_BytesObject) - return w_literal.as_string() # XXX performance issue here - def create_frame(self, space, receiver, arguments, sender = None): assert len(arguments) == self.argsize s_new = MethodContextShadow.make_context( space, self, receiver, arguments, sender) return s_new -class Version: - pass - class CachedObjectShadow(AbstractCachingShadow): - _immutable_fields_ = ['version?'] - - def __init__(self, space, w_self): - AbstractCachingShadow.__init__(self, space, w_self) - self.version = Version() def fetch(self, n0): jit.promote(self) @@ -918,5 +953,20 @@ self.version = Version() return self._w_self._store(n0, w_value) - def update_shadow(self): - self.version = Version() \ No newline at end of file + def update(self): + self.version = Version() + +class ObserveeShadow(AbstractShadow): + _attr_ = ['dependent'] + def __init__(self, space, w_self): + AbstractShadow.__init__(self, space, w_self) + self.dependent = None + + def store(self, n0, w_value): + AbstractShadow.store(self, n0, w_value) + self.dependent.update() + + def notify(self, dependent): + if self.dependent is not None and dependent is not self.dependent: + raise RuntimeError('Meant to be observed by only one value, so far') + self.dependent = dependent \ No newline at end of file diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -227,6 +227,7 @@ self.init_g_objects() self.init_w_objects() self.fillin_w_objects() + self.synchronize_shadows() def read_version(self): # 1 word version @@ -300,6 +301,12 @@ for chunk in self.chunks.itervalues(): chunk.g_object.fillin_w_object() + def synchronize_shadows(self): + for chunk in self.chunks.itervalues(): + casted = chunk.g_object.w_object + if isinstance(casted, model.W_PointersObject) and casted.has_shadow(): + casted._shadow.update() + def init_compactclassesarray(self): """ from the blue book (CompiledMethod Symbol Array PseudoContext LargePositiveInteger nil MethodDictionary Association Point Rectangle nil TranslatedMethod BlockContext MethodContext nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) """ special = self.chunks[self.specialobjectspointer] @@ -491,9 +498,6 @@ self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" - else: - #XXX invalidate shadow here - pass return self.w_object def fillin_w_object(self): @@ -515,9 +519,6 @@ def fillin_pointersobject(self, w_pointersobject): assert self.pointers is not None - # XXX is the following needed? - if w_pointersobject._shadow is not None: - w_pointersobject._shadow.detach_shadow() w_pointersobject._vars = [g_object.w_object for g_object in self.pointers] w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -7,7 +7,9 @@ tools.setup_module(tools, filename='bootstrapped.image') def find_symbol_in_methoddict_of(string, s_class): - methoddict_w = s_class.s_methoddict().methoddict + s_methoddict = s_class.s_methoddict() + s_methoddict.sync_cache() + methoddict_w = s_methoddict.methoddict for each in methoddict_w.keys(): if each.as_string() == string: return each @@ -55,4 +57,4 @@ sends = perform(w(5), 'benchFib') t1 = time.time() t = t1 - t0 - print str(tools.space.unwrap_int(sends)/t) + " sends per second" \ No newline at end of file + print str(tools.space.unwrap_int(sends)/t) + " sends per second" diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -62,7 +62,8 @@ assert space.w_nil._shadow is None for (w_class, _, _, methname) in methods: s_class = w_class.as_class_get_shadow(space) - del s_class.s_methoddict().methoddict[fakesymbol(methname)] + s_class.update() + s_class.s_methoddict().update() def fakesymbol(s, _cache={}): try: diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -270,7 +270,7 @@ perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) w_result = perform(w(10), "testBecome") assert space.unwrap_int(w_result) == 42 - + def perform(w_receiver, selector, *arguments_w): return interp.perform(w_receiver, selector, *arguments_w) @@ -282,6 +282,20 @@ assert isinstance(s_ctx, shadow.MethodContextShadow) assert s_ctx.top().is_same_object(space.w_true) +def test_cached_methoddict_compile(): + sourcecode = """fib + ^self < 2 + ifTrue: [ 1 ] + ifFalse: [ ((self - 1) fib + (self - 2) fib) + 1 ]""" + perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) + assert perform(w(5), "fib").is_same_object(w(15)) + sourcecode = """fib + ^self < 2 + ifTrue: [ 1 ] + ifFalse: [ (self - 1) fib + (self - 2) fib ]""" + perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) + assert perform(w(10), "fib").is_same_object(w(89)) + def test_step_run_something(): from spyvm.test import test_miniimage setup_module(test_miniimage, filename='running-something-mini.image') diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -1,5 +1,5 @@ import random -from spyvm import model, shadow, constants +from spyvm import model, shadow, constants, interpreter from spyvm import objspace space = objspace.ObjSpace() @@ -42,6 +42,7 @@ w_class.store(space, constants.CLASS_FORMAT_INDEX, space.wrap_int(format)) if name is not None: w_class.store(space, constants.CLASS_NAME_INDEX, space.wrap_string(name)) + w_class.as_class_get_shadow(space).s_methoddict().sync_cache() return w_class def basicshape(name, format, kind, varsized, instsize): @@ -152,32 +153,24 @@ assert s_object.getbytecode() == 101 assert s_object.s_home() == s_object -def test_attach_detach_mc(): +def test_attach_mc(): w_m = method() w_object = methodcontext(pc=13, method=w_m) old_vars = w_object._vars s_object = w_object.as_methodcontext_get_shadow(space) assert w_object._vars is None - s_object.detach_shadow() - assert w_object._vars == old_vars - assert w_object._vars is not old_vars -def test_attach_detach_bc(): +def test_attach_bc(): w_object = blockcontext(pc=13) old_vars = w_object._vars s_object = w_object.as_blockcontext_get_shadow(space) assert w_object._vars is None - s_object.detach_shadow() - assert w_object._vars == old_vars - assert w_object._vars is not old_vars def test_replace_to_bc(): w_object = blockcontext(pc=13) old_vars = w_object._vars s_object = w_object.as_blockcontext_get_shadow(space) - s_object.detach_shadow() - s_classshadow = shadow.ClassShadow(space, w_object) - w_object._shadow = s_classshadow + s_object._shadow = None s_newobject = w_object.as_blockcontext_get_shadow(space) assert ([s_newobject.fetch(i) for i in range(s_newobject.size())] == [s_object.fetch(i) for i in range(s_newobject.size())]) @@ -197,16 +190,13 @@ w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) - assert w_compiledmethod._shadow is None - - shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) + assert w_compiledmethod._shadow is not None assert shadow.literals == [17, 41] w_compiledmethod.atput0(space, 14, space.wrap_int(ord("x"))) - assert w_compiledmethod._shadow is None - shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abx" + assert shadow is w_compiledmethod.as_compiledmethod_get_shadow(space) def test_cached_object_shadow(): w_o = space.wrap_list([0, 1, 2, 3, 4, 5, 6, 7]) @@ -216,4 +206,24 @@ assert w_o.at0(space, i) == i w_o.atput0(space, 0, 8) assert version is not s_o.version - assert w_o.at0(space, 0) == 8 \ No newline at end of file + assert w_o.at0(space, 0) == 8 + +def test_observee_shadow(): + notified = False + class Observer(): + def __init__(self): self.notified = False + def update(self): self.notified = True + o = Observer() + w_o = w_Array.as_class_get_shadow(space).new(1) + w_o.as_observed_get_shadow(space).notify(o) + assert not o.notified + w_o.store(space, 0, 1) + assert o.notified + assert w_o.fetch(space, 0) == 1 + try: + w_o._shadow.notify(Observer()) + except RuntimeError: + pass + else: + assert False + diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -53,9 +53,3 @@ return model.W_SmallInteger(rerased.erase_int(val)) except OverflowError: raise WrappingError("integer too large to fit into a tagged pointer") - -make classes - - -Unclarities: -[ ] should image loading invalidate the shadows of the precreated objects? \ No newline at end of file From noreply at buildbot.pypy.org Sun Mar 10 20:25:28 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Sun, 10 Mar 2013 20:25:28 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Patched MethodDictShadow to assume that for every change in self, there afterwards will be a change in its contents-array, before it will be asked for an entry. Message-ID: <20130310192528.29F6E1C13EB@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r158:eadb01e2add1 Date: 2013-03-10 19:37 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/eadb01e2add1/ Log: Patched MethodDictShadow to assume that for every change in self, there afterwards will be a change in its contents-array, before it will be asked for an entry. Because of that assumption, we can patch our cache then, instead of during lookup diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -281,8 +281,7 @@ AbstractCachingShadow.__init__(self, space, w_self) def find_selector(self, w_selector): - if self.invalid: - self.sync_cache() + assert not self.invalid jit.promote(self) version = self.version jit.promote(version) @@ -293,12 +292,19 @@ assert version is self.version return self.methoddict.get(w_selector, None) - def update(self): - # Sync_cache at this point has not the desired effect, because in + # Remove update call for changes to ourselves: + # Whenever a method is added, it's keyword is added to w_self, then the + # w_compiled_method is added to our observee. + # Sync_cache at this point would not have the desired effect, because in # the Smalltalk Implementation, the dictionary changes first. Afterwards # its contents array is filled with the value belonging to the new key. + def store(self, n0, w_value): + AbstractShadow.store(self, n0, w_value) self.invalid = True + def update(self): + self.sync_cache() + def sync_cache(self): w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX) assert isinstance(w_values, model.W_PointersObject) @@ -313,8 +319,10 @@ raise ClassShadowError("bogus selector in method dict") w_compiledmethod = w_values._fetch(i) if not isinstance(w_compiledmethod, model.W_CompiledMethod): - raise ClassShadowError("the methoddict must contain " - "CompiledMethods only for now") + raise ClassShadowError("The methoddict must contain " + "CompiledMethods only, for now. " + "If the value observed is nil, our " + "invalidating mechanism may be broken.") self.methoddict[w_selector] = w_compiledmethod selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector From noreply at buildbot.pypy.org Sun Mar 10 20:25:29 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Sun, 10 Mar 2013 20:25:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Switched from saving w_superclass to s_superclass Message-ID: <20130310192529.4ABA61C13EB@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r159:3c05ce8c677c Date: 2013-03-10 20:25 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/3c05ce8c677c/ Log: Switched from saving w_superclass to s_superclass Patched W_PointerObject#become and test to ensure that the backlink w_self also points to the correct object refactored patching of ProtoObjectClass shadow of objspace diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -259,9 +259,9 @@ class W_PointersObject(W_AbstractObjectWithClassReference): """Common object.""" _attrs_ = ['_shadow', '_vars'] + + _shadow = None # Default value - _shadow = None # Default value - @jit.unroll_safe def __init__(self, w_class, size): """Create new object with size = fixed + variable size.""" @@ -269,7 +269,7 @@ vars = self._vars = [None] * size for i in range(size): # do it by hand for the JIT's sake vars[i] = w_nil - self._shadow = None + self._shadow = None # Default value def at0(self, space, index0): # To test, at0 = in varsize part @@ -382,7 +382,11 @@ if not isinstance(w_other, W_PointersObject): return False self._vars, w_other._vars = w_other._vars, self._vars + # switching means also switching shadows self._shadow, w_other._shadow = w_other._shadow, self._shadow + # shadow links are in both directions -> also update shadows + if self.has_shadow(): self._shadow._w_self = self + if w_other.has_shadow(): w_other._shadow._w_self = w_other W_AbstractObjectWithClassReference._become(self, w_other) return True @@ -499,10 +503,11 @@ ### variables. The number of bytes used for this purpose is the value of ### the last byte in the method. - _shadow = None + _shadow = None # Default value _likely_methodname = "" def __init__(self, bytecount=0, header=0): + self._shadow = None self.setheader(header) self.bytes = ["\x00"] * bytecount diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -53,13 +53,8 @@ w_Class = self.classtable["w_Class"] w_Metaclass = self.classtable["w_Metaclass"] # XXX - proto_shadow = instantiate(shadow.ClassShadow) - proto_shadow.space = self - proto_shadow.name = '' - proto_shadow.w_superclass = w_Class - proto_shadow.version = shadow.Version() - w_ProtoObjectClass._shadow = None - w_ProtoObjectClass.store_shadow(proto_shadow) + proto_shadow = w_ProtoObjectClass._shadow + proto_shadow.store_w_superclass(w_Class) # at this point, all classes that still lack a w_class are themselves # metaclasses for nm, w_cls_obj in self.classtable.items(): @@ -299,7 +294,7 @@ s = instantiate(shadow.ClassShadow) s.space = space s._w_self = w_class - s.w_superclass = w_superclass + s.store_w_superclass(w_superclass) s.name = name s.version = shadow.Version() s.instance_size = instsize diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -74,7 +74,7 @@ (i.e. used as the class of another Smalltalk object). """ - _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"] + _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "_s_superclass"] def __init__(self, space, w_self): # fields added here should also be in objspace.py:60ff, 300ff @@ -141,10 +141,10 @@ w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX) if w_superclass.is_same_object(self.space.w_nil): - self.w_superclass = None + self._s_superclass = None else: assert isinstance(w_superclass, model.W_PointersObject) - self.w_superclass = w_superclass + self._s_superclass = w_superclass.as_class_get_shadow(self.space) self.version = Version() def guess_class_name(self): @@ -194,9 +194,9 @@ return jit.promote(self.w_methoddict.as_methoddict_get_shadow(self.space)) def s_superclass(self): - if self.w_superclass is None: + if self._s_superclass is None: return None - return self.w_superclass.as_class_get_shadow(self.space) + return self._s_superclass # _______________________________________________________________ # Methods for querying the format word, taken from the blue book: @@ -226,23 +226,37 @@ " Number of named instance variables for each instance of this class " return self.instance_size + def store_w_superclass(self, w_class): + if w_class is None: + self._s_superclass = None + else: + self._s_superclass = w_class.as_class_get_shadow(self.space) + # _______________________________________________________________ # Methods for querying the format word, taken from the blue book: def __repr__(self): return "" % (self.name or '?',) + def lookup(self, w_selector): + jit.promote(self) + version = self.version + jit.promote(version) + return self.safe_lookup(w_selector, version) + @jit.unroll_safe - def lookup(self, w_selector): + def safe_lookup(self, w_selector, version): + assert version is self.version look_in_shadow = self jit.promote(w_selector) while look_in_shadow is not None: w_method = look_in_shadow.s_methoddict().find_selector(w_selector) if w_method is not None: return w_method.as_compiledmethod_get_shadow(self.space) - look_in_shadow = look_in_shadow.s_superclass() + look_in_shadow = look_in_shadow._s_superclass raise MethodNotFound(self, w_selector) + # _______________________________________________________________ # Methods used only in testing diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -213,7 +213,9 @@ res = w_clsa.become(w_clsb) assert res assert w_clsa.as_class_get_shadow(space) is s_clsb + assert s_clsa._w_self is w_clsb assert w_clsb.as_class_get_shadow(space) is s_clsa + assert s_clsb._w_self is w_clsa def test_word_atput(): i = model.W_SmallInteger(100) From noreply at buildbot.pypy.org Sun Mar 10 20:41:12 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 10 Mar 2013 20:41:12 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix for appdirect testing Message-ID: <20130310194112.909061C140C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62279:a88c319e44e5 Date: 2013-03-10 12:40 -0700 http://bitbucket.org/pypy/pypy/changeset/a88c319e44e5/ Log: fix for appdirect testing diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -46,8 +46,7 @@ def get_name(): return __name__ def get_file(): - return __file__ - """ + return __file__""" space = cls.space w = space.wrap w_co = space.call_method(space.builtin, 'compile', From noreply at buildbot.pypy.org Sun Mar 10 20:48:26 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Sun, 10 Mar 2013 20:48:26 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: refactored ClassShadow to hold onto s_methoddict instead of w_methoddict Message-ID: <20130310194826.94C3D1C1411@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r160:9d99442f994d Date: 2013-03-10 20:48 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/9d99442f994d/ Log: refactored ClassShadow to hold onto s_methoddict instead of w_methoddict diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -299,7 +299,7 @@ s.version = shadow.Version() s.instance_size = instsize s.instance_kind = format - s.w_methoddict = None + s._s_methoddict = None s.instance_varsized = varsized or format != shadow.POINTERS w_class.store_shadow(s) return w_class diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -74,10 +74,10 @@ (i.e. used as the class of another Smalltalk object). """ - _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "_s_superclass"] + _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "_s_methoddict", "_s_superclass"] def __init__(self, space, w_self): - # fields added here should also be in objspace.py:60ff, 300ff + # fields added here should also be in objspace.py:56ff, 300ff self.name = '' AbstractCachingShadow.__init__(self, space, w_self) @@ -137,7 +137,8 @@ # read the methoddict w_methoddict = w_self._fetch(constants.CLASS_METHODDICT_INDEX) assert isinstance(w_methoddict, model.W_PointersObject) - self.w_methoddict = w_methoddict + if not w_methoddict.is_same_object(self.space.w_nil): + self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space) w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX) if w_superclass.is_same_object(self.space.w_nil): @@ -191,7 +192,8 @@ return w_new def s_methoddict(self): - return jit.promote(self.w_methoddict.as_methoddict_get_shadow(self.space)) + jit.promote(self._s_methoddict.version) + return self._s_methoddict def s_superclass(self): if self._s_superclass is None: @@ -271,9 +273,10 @@ def initialize_methoddict(self): "NOT_RPYTHON" # this is only for testing. - if self.w_methoddict is None: - self.w_methoddict = model.W_PointersObject(None, 2) - self.w_methoddict._store(1, model.W_PointersObject(None, 0)) + if self._s_methoddict is None: + w_methoddict = model.W_PointersObject(None, 2) + w_methoddict._store(1, model.W_PointersObject(None, 0)) + self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space) self.s_methoddict().sync_cache() self.s_methoddict().invalid = False @@ -316,10 +319,9 @@ AbstractShadow.store(self, n0, w_value) self.invalid = True - def update(self): - self.sync_cache() - def sync_cache(self): + if self.w_self().size() == 0: + return w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX) assert isinstance(w_values, model.W_PointersObject) s_values = w_values.as_observed_get_shadow(self.space) @@ -991,4 +993,7 @@ def notify(self, dependent): if self.dependent is not None and dependent is not self.dependent: raise RuntimeError('Meant to be observed by only one value, so far') - self.dependent = dependent \ No newline at end of file + self.dependent = dependent + + def update(self): pass + \ No newline at end of file From noreply at buildbot.pypy.org Sun Mar 10 22:28:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Mar 2013 22:28:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the stack alignment (I think) Message-ID: <20130310212832.7E2531C13FD@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62280:9db1c0dd3831 Date: 2013-03-10 23:27 +0200 http://bitbucket.org/pypy/pypy/changeset/9db1c0dd3831/ Log: fix the stack alignment (I think) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1125,8 +1125,7 @@ stack_depth += 1 stack_depth += loc.get_width() // WORD if stack_depth > stack_max: - stack_depth = align_stack_words(stack_depth) - align = (stack_depth - stack_max) + align = align_stack_words(stack_depth - stack_max) self.mc.SUB_ri(esp.value, align * WORD) if can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') @@ -1202,8 +1201,7 @@ max(floats - len(unused_xmm), 0)) align = 0 if stack_depth > stack_max: - stack_depth = align_stack_words(stack_depth) - align = (stack_depth - stack_max) + align = align_stack_words(stack_depth - stack_max) if can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, align * WORD) From noreply at buildbot.pypy.org Mon Mar 11 01:32:03 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 11 Mar 2013 01:32:03 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: shrank the execution time of the test for changed methoddicts Message-ID: <20130311003203.6ECB51C026F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r161:a61885e1f0db Date: 2013-03-11 00:08 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a61885e1f0db/ Log: shrank the execution time of the test for changed methoddicts diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -191,6 +191,9 @@ raise NotImplementedError(self.instance_kind) return w_new + def w_methoddict(self): + return self.w_self()._fetch(constants.CLASS_METHODDICT_INDEX) + def s_methoddict(self): jit.promote(self._s_methoddict.version) return self._s_methoddict @@ -292,9 +295,11 @@ class MethodDictionaryShadow(AbstractCachingShadow): _immutable_fields_ = ['invalid?'] + _attr_ = ['methoddict'] def __init__(self, space, w_self): self.invalid = True + self.methoddict = {} AbstractCachingShadow.__init__(self, space, w_self) def find_selector(self, w_selector): @@ -996,4 +1001,3 @@ self.dependent = dependent def update(self): pass - \ No newline at end of file diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -282,7 +282,9 @@ assert isinstance(s_ctx, shadow.MethodContextShadow) assert s_ctx.top().is_same_object(space.w_true) -def test_cached_methoddict_compile(): +def test_cached_methoddict(): + py.test.skip('Should test the same as test_shadow.test_cached_methoddict, as long ' + 'as the implementation of MethodDictionary>>#at:put does not change.') sourcecode = """fib ^self < 2 ifTrue: [ 1 ] diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -227,3 +227,29 @@ else: assert False +def test_cached_methoddict(): + # create a methoddict + foo = model.W_CompiledMethod(0) + bar = model.W_CompiledMethod(0) + baz = model.W_CompiledMethod(0) + methods = {'foo': foo, + 'bar': bar} + w_class = build_smalltalk_class("Demo", 0x90, methods=methods) + s_class = w_class.as_class_get_shadow(space) + s_methoddict = s_class.s_methoddict() + s_methoddict.sync_cache() + i = 0 + key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) + while key is space.w_nil: + key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) + i = i + 1 + + assert (s_class.lookup(key) is foo.as_compiledmethod_get_shadow(space) + or s_class.lookup(key) is bar.as_compiledmethod_get_shadow(space)) + # change that entry + w_array = s_class.w_methoddict()._fetch(constants.METHODDICT_VALUES_INDEX) + version = s_methoddict.version + w_array.atput0(space, i, baz) + + assert s_class.lookup(key) is baz.as_compiledmethod_get_shadow(space) + assert version is not s_methoddict.version \ No newline at end of file From noreply at buildbot.pypy.org Mon Mar 11 01:32:04 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 11 Mar 2013 01:32:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: removed version from methoddict Message-ID: <20130311003204.8BC301C026F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r162:52374f03b7ac Date: 2013-03-11 00:23 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/52374f03b7ac/ Log: removed version from methoddict added back link from methoddict to s_class to change s_class version when s_methoddict changes removed synchronize methods in favor of update methods removed the elidable annotations, resulting in horrible traces for this version the idea is that promoting the class version is sufficient for elidable lookups for that, only subclass links are missing diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -335,7 +335,7 @@ if shadow is not None: raise DetachingShadowError(shadow, TheClass) shadow = self.attach_shadow_of_class(space, TheClass) - shadow.synchronize() + shadow.update() return shadow def get_shadow(self, space): diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -23,7 +23,7 @@ def getname(self): return repr(self) def attach_shadow(self): pass - def synchronize(self): pass + def update(self): pass class AbstractCachingShadow(AbstractShadow): _immutable_fields_ = ['version?'] @@ -42,9 +42,6 @@ object changes.""" self.sync_cache() - def synchronize(self): - self.update() - def sync_cache(self): raise NotImplementedError() @@ -139,6 +136,7 @@ assert isinstance(w_methoddict, model.W_PointersObject) if not w_methoddict.is_same_object(self.space.w_nil): self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space) + self._s_methoddict.s_class = self w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX) if w_superclass.is_same_object(self.space.w_nil): @@ -195,7 +193,6 @@ return self.w_self()._fetch(constants.CLASS_METHODDICT_INDEX) def s_methoddict(self): - jit.promote(self._s_methoddict.version) return self._s_methoddict def s_superclass(self): @@ -292,27 +289,22 @@ method = w_method.as_compiledmethod_get_shadow(self.space) method.w_compiledin = self.w_self() -class MethodDictionaryShadow(AbstractCachingShadow): +class MethodDictionaryShadow(AbstractShadow): - _immutable_fields_ = ['invalid?'] + _immutable_fields_ = ['invalid?', 's_class'] _attr_ = ['methoddict'] def __init__(self, space, w_self): self.invalid = True + self.s_class = None self.methoddict = {} - AbstractCachingShadow.__init__(self, space, w_self) + AbstractShadow.__init__(self, space, w_self) def find_selector(self, w_selector): assert not self.invalid - jit.promote(self) - version = self.version - jit.promote(version) - return self._safe_find_selector(w_selector, version) + return self.methoddict.get(w_selector, None) - @jit.elidable - def _safe_find_selector(self, w_selector, version): - assert version is self.version - return self.methoddict.get(w_selector, None) + def update(self): return self.sync_cache() # Remove update call for changes to ourselves: # Whenever a method is added, it's keyword is added to w_self, then the @@ -347,7 +339,8 @@ self.methoddict[w_selector] = w_compiledmethod selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector - self.version = Version() + if self.s_class: + self.s_class.version = Version() self.invalid = False diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -248,8 +248,8 @@ or s_class.lookup(key) is bar.as_compiledmethod_get_shadow(space)) # change that entry w_array = s_class.w_methoddict()._fetch(constants.METHODDICT_VALUES_INDEX) - version = s_methoddict.version + version = s_class.version w_array.atput0(space, i, baz) assert s_class.lookup(key) is baz.as_compiledmethod_get_shadow(space) - assert version is not s_methoddict.version \ No newline at end of file + assert version is not s_class.version \ No newline at end of file From noreply at buildbot.pypy.org Mon Mar 11 01:32:05 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 11 Mar 2013 01:32:05 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added version updates when superclass changes Message-ID: <20130311003205.AEAFC1C026F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r163:d8785e33876b Date: 2013-03-11 01:31 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d8785e33876b/ Log: added version updates when superclass changes still missing are the appropriate annotations, weak ref instead of set() to subclasses diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -293,10 +293,12 @@ # XXX s = instantiate(shadow.ClassShadow) s.space = space + s.version = shadow.Version() s._w_self = w_class + s.subclass_s = set() + s._s_superclass = None s.store_w_superclass(w_superclass) s.name = name - s.version = shadow.Version() s.instance_size = instsize s.instance_kind = format s._s_methoddict = None diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -49,6 +49,9 @@ AbstractShadow.store(self, n0, w_value) self.update() + def change(self): + self.version = Version() + class Version: pass # ____________________________________________________________ @@ -71,11 +74,14 @@ (i.e. used as the class of another Smalltalk object). """ - _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "_s_methoddict", "_s_superclass"] + _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", + "_s_methoddict", "_s_superclass", "subclass_s"] def __init__(self, space, w_self): # fields added here should also be in objspace.py:56ff, 300ff self.name = '' + self._s_superclass = None + self.subclass_s = set() AbstractCachingShadow.__init__(self, space, w_self) def getname(self): @@ -143,8 +149,8 @@ self._s_superclass = None else: assert isinstance(w_superclass, model.W_PointersObject) - self._s_superclass = w_superclass.as_class_get_shadow(self.space) - self.version = Version() + self.store_w_superclass(w_superclass) + self.changed() def guess_class_name(self): if self.name != '': @@ -173,7 +179,7 @@ self.name = w_name.as_string() else: self.name = None - self.version = Version() + self.changed() def new(self, extrasize=0): w_cls = self.w_self() @@ -232,7 +238,27 @@ if w_class is None: self._s_superclass = None else: - self._s_superclass = w_class.as_class_get_shadow(self.space) + s_scls = w_class.as_class_get_shadow(self.space) + if self._s_superclass is s_scls: + return + elif (self._s_superclass is not None + and self._s_superclass is not s_scls): + self._s_superclass.detach_s_class(self) + self._s_superclass = s_scls + self._s_superclass.attach_s_class(self) + + def attach_s_class(self, s_other): self.subclass_s.add(s_other) + def detach_s_class(self, s_other): self.subclass_s.remove(s_other) + + def changed(self): + self.superclass_changed(Version()) + + # this is done, because the class-hierarchy contains cycles + def superclass_changed(self, version): + if self.version is not version: + self.version = version + for s_class in self.subclass_s: + s_class.superclass_changed(version) # _______________________________________________________________ # Methods for querying the format word, taken from the blue book: @@ -340,7 +366,7 @@ selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector if self.s_class: - self.s_class.version = Version() + self.s_class.changed() self.invalid = False @@ -975,8 +1001,7 @@ self.version = Version() return self._w_self._store(n0, w_value) - def update(self): - self.version = Version() + def update(self): pass class ObserveeShadow(AbstractShadow): _attr_ = ['dependent'] diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -252,4 +252,25 @@ w_array.atput0(space, i, baz) assert s_class.lookup(key) is baz.as_compiledmethod_get_shadow(space) - assert version is not s_class.version \ No newline at end of file + assert version is not s_class.version + +def test_updating_class_changes_subclasses(): + w_parent = build_smalltalk_class("Demo", 0x90, + methods={'bar': model.W_CompiledMethod(0)}) + w_class = build_smalltalk_class("Demo", 0x90, + methods={'foo': model.W_CompiledMethod(0)}, w_superclass=w_parent) + s_class = w_class.as_class_get_shadow(space) + version = s_class.version + + w_method = model.W_CompiledMethod(0) + key = space.wrap_string('foo') + + s_md = w_parent.as_class_get_shadow(space).s_methoddict() + s_md.sync_cache() + w_ary = s_md._w_self._fetch(constants.METHODDICT_VALUES_INDEX) + s_md._w_self.atput0(space, 0, key) + w_ary.atput0(space, 0, w_method) + + assert s_class.lookup(key) is w_method.as_compiledmethod_get_shadow(space) + assert s_class.version is not version + assert s_class.version is w_parent.as_class_get_shadow(space).version From noreply at buildbot.pypy.org Mon Mar 11 04:13:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 04:13:55 +0100 (CET) Subject: [pypy-commit] pypy default: unify sqlite execute and executemany Message-ID: <20130311031355.940791C026F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62281:b1628dd8444b Date: 2013-03-10 21:27 -0400 http://bitbucket.org/pypy/pypy/changeset/b1628dd8444b/ Log: unify sqlite execute and executemany diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -839,14 +839,14 @@ return func(self, *args, **kwargs) return wrapper - @__check_cursor_wrap - def execute(self, sql, params=[]): + def __execute(self, multiple, sql, many_params): self.__locked = True try: self.__description = None self._reset = False if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") + self.__rowcount = -1 self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -858,68 +858,46 @@ if not self.__connection._in_transaction: self.__connection._begin() - self.__statement._set_params(params) + if multiple and self.__statement._kind != Statement._DML: + raise ProgrammingError("executemany is only for DML statements") - # Actually execute the SQL statement - ret = _lib.sqlite3_step(self.__statement._statement) - if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): - self.__statement._reset() - self.__connection._in_transaction = \ - not _lib.sqlite3_get_autocommit(self.__connection._db) - raise self.__connection._get_exception(ret) + for params in many_params: + self.__statement._set_params(params) - if self.__statement._kind == Statement._DML: - self.__statement._reset() + # Actually execute the SQL statement + ret = _lib.sqlite3_step(self.__statement._statement) + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): + self.__statement._reset() + self.__connection._in_transaction = \ + not _lib.sqlite3_get_autocommit(self.__connection._db) + raise self.__connection._get_exception(ret) - if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: - self.__statement._build_row_cast_map() - self.__statement._readahead(self) - else: - self.__statement._item = None - self.__statement._exhausted = True + if self.__statement._kind == Statement._DML: + self.__statement._reset() - self.__rowcount = -1 - if self.__statement._kind == Statement._DML: - self.__rowcount = _lib.sqlite3_changes(self.__connection._db) + if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: + self.__statement._build_row_cast_map() + self.__statement._readahead(self) + else: + self.__statement._item = None + self.__statement._exhausted = True + + if self.__statement._kind == Statement._DML: + if self.__rowcount == -1: + self.__rowcount = 0 + self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False return self @__check_cursor_wrap + def execute(self, sql, params=[]): + return self.__execute(False, sql, [params]) + + @__check_cursor_wrap def executemany(self, sql, many_params): - self.__locked = True - try: - self.__description = None - self._reset = False - if not isinstance(sql, basestring): - raise ValueError("operation parameter must be str or unicode") - self.__statement = self.__connection._statement_cache.get( - sql, self.row_factory) - - if self.__statement._kind == Statement._DML: - if self.__connection._isolation_level is not None: - if not self.__connection._in_transaction: - self.__connection._begin() - else: - raise ProgrammingError( - "executemany is only for DML statements") - - self.__rowcount = 0 - for params in many_params: - self.__statement._set_params(params) - ret = _lib.sqlite3_step(self.__statement._statement) - if ret != _lib.SQLITE_DONE: - self.__statement._reset() - self.__connection._in_transaction = \ - not _lib.sqlite3_get_autocommit(self.__connection._db) - raise self.__connection._get_exception(ret) - self.__statement._reset() - self.__rowcount += _lib.sqlite3_changes(self.__connection._db) - finally: - self.__locked = False - - return self + return self.__execute(True, sql, many_params) def executescript(self, sql): self.__description = None From noreply at buildbot.pypy.org Mon Mar 11 04:13:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 04:13:56 +0100 (CET) Subject: [pypy-commit] pypy default: more sqlite cleanups Message-ID: <20130311031356.F38AE1C026F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62282:afd9bafe842a Date: 2013-03-10 22:15 -0400 http://bitbucket.org/pypy/pypy/changeset/afd9bafe842a/ Log: more sqlite cleanups diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -513,7 +513,7 @@ def _begin(self): statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, - byref(statement), None) + byref(statement), None) try: if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -537,7 +537,7 @@ statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, - byref(statement), None) + byref(statement), None) try: if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -566,7 +566,7 @@ statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, - byref(statement), None) + byref(statement), None) try: if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -600,10 +600,10 @@ if isinstance(name, unicode): name = name.encode('utf-8') ret = _lib.sqlite3_create_function(self._db, name, num_args, - _lib.SQLITE_UTF8, None, - c_closure, - cast(None, _STEP), - cast(None, _FINAL)) + _lib.SQLITE_UTF8, None, + c_closure, + cast(None, _STEP), + cast(None, _FINAL)) if ret != _lib.SQLITE_OK: raise self.OperationalError("Error creating function") @@ -669,10 +669,10 @@ if isinstance(name, unicode): name = name.encode('utf-8') ret = _lib.sqlite3_create_function(self._db, name, num_args, - _lib.SQLITE_UTF8, None, - cast(None, _FUNC), - c_step_callback, - c_final_callback) + _lib.SQLITE_UTF8, None, + cast(None, _FUNC), + c_step_callback, + c_final_callback) if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -842,10 +842,10 @@ def __execute(self, multiple, sql, many_params): self.__locked = True try: - self.__description = None self._reset = False if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") + self.__description = None self.__rowcount = -1 self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -900,19 +900,19 @@ return self.__execute(True, sql, many_params) def executescript(self, sql): - self.__description = None + self.__check_cursor() self._reset = False - self.__check_cursor() - statement = c_void_p() if isinstance(sql, unicode): sql = sql.encode('utf-8') elif not isinstance(sql, str): raise ValueError("script argument must be unicode or string.") - c_sql = c_char_p(sql) + sql = c_char_p(sql) + statement = c_void_p() self.__connection.commit() while True: - rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) + rc = _lib.sqlite3_prepare(self.__connection._db, sql, -1, + byref(statement), byref(sql)) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -933,7 +933,7 @@ if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) - if not c_sql.value: + if not sql.value: break return self @@ -1020,24 +1020,26 @@ self._exhausted = False self._row_factory = None - self._statement = c_void_p() - next_char = c_char_p() if isinstance(sql, unicode): sql = sql.encode('utf-8') + sql = c_char_p(sql) + self._statement = c_void_p() - ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) + ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, + byref(self._statement), byref(sql)) if ret == _lib.SQLITE_OK and self._statement.value is None: - # an empty statement, we work around that, as it's the least trouble - ret = _lib.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) + # an empty statement, work around that, as it's the least trouble + sql = c_char_p(b"select 42") + ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, + byref(self._statement), byref(sql)) self._kind = Statement._DQL if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) - next_char = next_char.value.decode('utf-8') - if _check_remaining_sql(next_char): - raise Warning("One and only one statement required: %r" % - next_char) + sql = sql.value.decode('utf-8') + if _check_remaining_sql(sql): + raise Warning("You can only execute one statement at a time.") def __del__(self): if self._statement: @@ -1086,13 +1088,16 @@ rc = _lib.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, unicode): param = param.encode("utf-8") - rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, + len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, str): self.__check_decodable(param) - rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, + len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, (buffer, bytes)): param = bytes(param) - rc = _lib.sqlite3_bind_blob(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_blob(self._statement, idx, param, + len(param), _lib.SQLITE_TRANSIENT) else: rc = -1 return rc @@ -1163,7 +1168,9 @@ decltype = _lib.sqlite3_column_decltype(self._statement, i) if decltype is not None: decltype = decltype.decode('utf-8') - decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" + # if multiple words, use first, eg. + # "INTEGER NOT NULL" => "INTEGER" + decltype = decltype.split()[0] if '(' in decltype: decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) From noreply at buildbot.pypy.org Mon Mar 11 05:14:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 05:14:44 +0100 (CET) Subject: [pypy-commit] pypy default: improve dotviewer search for system cpython Message-ID: <20130311041444.C5FE61C026F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62286:05243549ef64 Date: 2013-03-11 00:07 -0400 http://bitbucket.org/pypy/pypy/changeset/05243549ef64/ Log: improve dotviewer search for system cpython diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -130,10 +130,10 @@ if hasattr(sys, 'pypy_objspaceclass'): # if 'python' is actually PyPy, e.g. in a virtualenv, then # try hard to find a real CPython - for python in ['/usr/local/bin/python', '/usr/bin/python']: - if os.path.exists(python): - break - else: + try: + python = subprocess.check_output(['env', '-i', 'which', 'python']) + python = python.strip() + except subprocess.CalledProcessError: # did not work, fall back to 'python' python = 'python' else: From noreply at buildbot.pypy.org Mon Mar 11 05:14:46 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 05:14:46 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130311041446.0B8EF1C026F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62287:105fa978d547 Date: 2013-03-11 00:14 -0400 http://bitbucket.org/pypy/pypy/changeset/105fa978d547/ Log: merge heads diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -9,6 +9,7 @@ PREFIX = os.path.normpath(sys.prefix) +EXEC_PREFIX = os.path.normpath(sys.exec_prefix) project_base = os.path.dirname(os.path.abspath(sys.executable)) python_build = False From noreply at buildbot.pypy.org Mon Mar 11 10:29:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 10:29:57 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for id(complex) when imag < 0 Message-ID: <20130311092957.D7CDD1C033F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62288:18d3311a2498 Date: 2013-03-11 05:29 -0400 http://bitbucket.org/pypy/pypy/changeset/18d3311a2498/ Log: test and fix for id(complex) when imag < 0 diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -9,7 +9,7 @@ from rpython.rlib.rfloat import ( formatd, DTSF_STR_PRECISION, isinf, isnan, copysign) from rpython.rlib import jit, rcomplex -from rpython.rlib.rarithmetic import intmask +from rpython.rlib.rarithmetic import intmask, r_ulonglong import math @@ -41,7 +41,7 @@ real = space.float_w(space.getattr(self, space.wrap("real"))) imag = space.float_w(space.getattr(self, space.wrap("imag"))) real_b = rbigint.fromrarith_int(float2longlong(real)) - imag_b = rbigint.fromrarith_int(float2longlong(imag)) + imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag))) val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag)) return space.newlong_from_rbigint(val) diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py --- a/pypy/objspace/std/test/test_obj.py +++ b/pypy/objspace/std/test/test_obj.py @@ -203,7 +203,9 @@ l.append(i + sys.maxint) l.append(i - sys.maxint) l.append(i + 1j) + l.append(i - 1j) l.append(1 + i * 1j) + l.append(1 - i * 1j) s = str(i) l.append(s) u = unicode(s) From noreply at buildbot.pypy.org Mon Mar 11 11:07:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 11:07:03 +0100 (CET) Subject: [pypy-commit] pypy default: another attempt at dotviewer path search Message-ID: <20130311100703.887BC1C1428@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62289:889d20441589 Date: 2013-03-11 06:06 -0400 http://bitbucket.org/pypy/pypy/changeset/889d20441589/ Log: another attempt at dotviewer path search diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -131,8 +131,8 @@ # if 'python' is actually PyPy, e.g. in a virtualenv, then # try hard to find a real CPython try: - python = subprocess.check_output(['env', '-i', 'which', 'python']) - python = python.strip() + python = subprocess.check_output( + 'env -i $SHELL -l -c "which python"', shell=True).strip() except subprocess.CalledProcessError: # did not work, fall back to 'python' python = 'python' From noreply at buildbot.pypy.org Mon Mar 11 11:29:15 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 11 Mar 2013 11:29:15 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix for build_frame_realloc_slowpath and _restore_exception Message-ID: <20130311102915.D0E8D1C1421@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62290:9c6fa4ed86cc Date: 2013-03-11 11:27 +0100 http://bitbucket.org/pypy/pypy/changeset/9c6fa4ed86cc/ Log: fix for build_frame_realloc_slowpath and _restore_exception diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -240,11 +240,16 @@ assert excvalloc.is_reg() self.store_reg(mc, excvalloc, r.ip) else: + assert exctploc is not r.fp # load exc_value from JITFRAME and put it in pos_exc_value ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') self.load_reg(mc, tmpreg, r.fp, ofs) self.store_reg(mc, tmpreg, r.ip) + # reset exc_value in the JITFRAME + mc.gen_load_int(tmpreg.value, 0) + self.store_reg(mc, tmpreg, r.fp, ofs) + # restore pos_exception from exctploc register mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) self.store_reg(mc, exctploc, r.ip) @@ -796,7 +801,7 @@ # store a possibly present exception # we use a callee saved reg here as a tmp for the exc. - self._store_and_reset_exception(mc, None, r.fp, on_frame=True) + self._store_and_reset_exception(mc, None, r.r4, on_frame=True) # call realloc_frame, it takes two arguments # arg0: the old jitframe @@ -804,11 +809,11 @@ # mc.BL(self.cpu.realloc_frame) + # set fp to the new jitframe returned from the previous call + mc.MOV_rr(r.fp.value, r.r0.value) + # restore a possibly present exception - self._restore_exception(mc, None, r.fp) - - # set fp to the new jitframe - mc.MOV_rr(r.fp.value, r.r0.value) + self._restore_exception(mc, None, r.r4) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: From noreply at buildbot.pypy.org Mon Mar 11 11:48:34 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 11 Mar 2013 11:48:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed generation replacing the set with a dictionary Message-ID: <20130311104834.969F51C1408@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r164:ac2243dae585 Date: 2013-03-11 11:48 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ac2243dae585/ Log: fixed generation replacing the set with a dictionary diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -295,7 +295,7 @@ code = s_method.primitive if interp.should_trace(): print "%sActually calling primitive %d" % (interp._last_indent, code,) - func = primitives.prim_table[code] + func = primitives.prim_holder.prim_table[code] try: # note: argcount does not include rcvr return func(interp, self, argcount) diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -295,7 +295,7 @@ s.space = space s.version = shadow.Version() s._w_self = w_class - s.subclass_s = set() + s.subclass_s = {} s._s_superclass = None s.store_w_superclass(w_superclass) s.name = name diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -35,6 +35,12 @@ # Squeak has primitives all the way up to 575 # So all optional primitives will default to the bytecode implementation prim_table = [make_failing(i) for i in range(576)] + +class PrimitiveHolder(object): + _immutable_fields_ = ["prim_table[*]"] + +prim_holder = PrimitiveHolder() +prim_holder.prim_table = prim_table # clean up namespace: del i prim_table_implemented_only = [] diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -81,7 +81,7 @@ # fields added here should also be in objspace.py:56ff, 300ff self.name = '' self._s_superclass = None - self.subclass_s = set() + self.subclass_s = {} AbstractCachingShadow.__init__(self, space, w_self) def getname(self): @@ -247,8 +247,11 @@ self._s_superclass = s_scls self._s_superclass.attach_s_class(self) - def attach_s_class(self, s_other): self.subclass_s.add(s_other) - def detach_s_class(self, s_other): self.subclass_s.remove(s_other) + def attach_s_class(self, s_other): + self.subclass_s[s_other] = None + + def detach_s_class(self, s_other): + del self.subclass_s[s_other] def changed(self): self.superclass_changed(Version()) @@ -270,9 +273,10 @@ jit.promote(self) version = self.version jit.promote(version) - return self.safe_lookup(w_selector, version) + w_method = self.safe_lookup(w_selector, version) + return w_method.as_compiledmethod_get_shadow(self.space) - @jit.unroll_safe + @jit.elidable def safe_lookup(self, w_selector, version): assert version is self.version look_in_shadow = self @@ -280,7 +284,7 @@ while look_in_shadow is not None: w_method = look_in_shadow.s_methoddict().find_selector(w_selector) if w_method is not None: - return w_method.as_compiledmethod_get_shadow(self.space) + return w_method look_in_shadow = look_in_shadow._s_superclass raise MethodNotFound(self, w_selector) @@ -946,6 +950,14 @@ return self._w_self def getliteral(self, index): + jit.promote(self) + version = self.version + jit.promote(version) + return self.safe_getliteral(index, version) + + @jit.elidable + def safe_getliteral(self, index, version): + assert version is self.version return self.literals[index] def getliteralsymbol(self, index): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -298,6 +298,9 @@ perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) assert perform(w(10), "fib").is_same_object(w(89)) +def test_get_env(): + import pdb; pdb.set_trace() + def test_step_run_something(): from spyvm.test import test_miniimage setup_module(test_miniimage, filename='running-something-mini.image') From noreply at buildbot.pypy.org Mon Mar 11 13:30:41 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 11 Mar 2013 13:30:41 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: create python-bitblt branch Message-ID: <20130311123041.33F4D1C1408@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r165:b1dfe51b9b09 Date: 2013-03-11 13:30 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/b1dfe51b9b09/ Log: create python-bitblt branch diff --git a/images/mini.image b/images/mini.image index 4e0739b0aa769798ae904fee0eff0b0eac8c8368..1bc58a0fd06c4079c4651f707226768f724e405e GIT binary patch [cut] diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -75,8 +75,8 @@ s_new_context = p.s_new_context def c_loop(self, s_context): - # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) - # print padding + s_context.short_str() + padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) + print padding + s_context.short_str() old_pc = 0 while True: pc = s_context._pc diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -369,6 +369,14 @@ from spyvm.shadow import CachedObjectShadow return self.as_special_get_shadow(space, CachedObjectShadow) + def as_bitblt_get_shadow(self, space): + from spyvm.shadow import BitBltShadow + return self.as_special_get_shadow(space, BitBltShadow) + + def as_form_get_shadow(self, space): + from spyvm.shadow import FormShadow + return self.as_special_get_shadow(space, FormShadow) + def become(self, w_other): if not isinstance(w_other, W_PointersObject): return False diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -513,7 +513,7 @@ INPUT_SEMAPHORE = 93 GET_NEXT_EVENT = 94 INPUT_WORD = 95 -OBSOLETE_INDEXED = 96 +BITBLT_COPY_BITS = 96 # OBSOLETE_INDEXED = 96 SNAPSHOT = 97 STORE_IMAGE_SEGMENT = 98 LOAD_IMAGE_SEGMENT = 99 @@ -521,7 +521,7 @@ BE_CURSOR = 101 BE_DISPLAY = 102 SCAN_CHARACTERS = 103 -# OBSOLETE_INDEXED = 104 # also 96 +OBSOLETE_INDEXED = 104 # also 96 STRING_REPLACE = 105 SCREEN_SIZE = 106 MOUSE_BUTTONS = 107 @@ -533,6 +533,21 @@ def func(interp, s_frame, w_rcvr): raise PrimitiveNotYetWrittenError() + at expose_primitive(BITBLT_COPY_BITS, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15: + raise PrimitiveFailedError + # See BlueBook p.356ff + s_bitblt = w_rcvr.as_bitblt_get_shadow(interp.space) + s_bitblt.clip_range() + if s_bitblt.w <= 0 or s_bitblt.h <= 0: + return w_rcvr # null range + s_bitblt.compute_masks() + s_bitblt.check_overlap() + s_bitblt.calculate_offsets() + s_bitblt.copy_loop() + return w_rcvr + @expose_primitive(BE_CURSOR, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): # TODO: Use info from cursor object. @@ -671,6 +686,7 @@ @expose_primitive(DRAW_RECTANGLE, unwrap_spec=[object, int, int, int, int]) def func(interp, s_frame, w_rcvr, left, right, top, bottom): + import pdb; pdb.set_trace() raise PrimitiveNotYetWrittenError() diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -692,8 +692,11 @@ return 0 def short_str(self): - return 'BlockContext of %s (%i)' % (self.w_method().get_identifier_string(), - self.pc() + 1) + return 'BlockContext of %s (%s) [%i]' % ( + self.w_method().get_identifier_string(), + self.w_receiver(), + self.pc() + 1 + ) class MethodContextShadow(ContextPartShadow): _attr_ = ['w_closure_or_nil', '_w_receiver', '__w_method'] @@ -843,7 +846,12 @@ def short_str(self): block = '[] of' if self.is_closure_context() else '' - return '%s %s (%i)' % (block, self.w_method().get_identifier_string(), self.pc() + 1) + return '%s %s (%s) [%i]' % ( + block, + self.w_method().get_identifier_string(), + self.w_receiver(), + self.pc() + 1 + ) class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", @@ -919,4 +927,240 @@ return self._w_self._store(n0, w_value) def update_shadow(self): - self.version = Version() \ No newline at end of file + self.version = Version() + + +class BitBltShadow(AbstractCachingShadow): + _attrs_ = [# From BitBlt + "dest_form", "source_form", "halftone_bits", + "combination_rule", "dest_x", "dest_y", "width", + "height", "source_x", "source_y", "clip_x", "clip_y", + "clip_width", "clip_height", "color_map", + # From BitBltSimulation + "w", "h", "sx", "sy", "dx", "dy", + "dest_bits", "dest_raster", "source_bits", "source_raster", + "halftone_bits", "skew", "mask1", "mask2", "skew_mask", + "n_words", "h_dir", "v_dir", "preload", "source_index", + "dest_index", "source_delta", "dest_delta"] + + RightMasks = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, 32767, 65535] + AllOnes = 65535 + + def sync_cache(self): + self.dest_form = self.fetch(0).as_form_get_shadow(self.space) + w_source_form = self.fetch(1) + if w_source_form is self.space.w_nil: + self.source_form = None + else: + self.source_form = w_source_form.as_form_get_shadow(self.space) + w_halftone_form = self.fetch(2) + if w_halftone_form is self.space.w_nil: + self.halftone_bits = None + elif isinstance(w_halftone_form, model.W_PointersObject): + self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits + elif isinstance(w_halftone_form, model.W_WordsObject): + self.halftone_bits = w_halftone_form.words + elif isinstance(w_halftone_form, model.W_BytesObject): + self.halftone_bits = [ord(byte) for byte in w_halftone_form.bytes] + self.combination_rule = self.space.unwrap_int(self.fetch(3)) + self.dest_x = self.space.unwrap_int(self.fetch(4)) + self.dest_y = self.space.unwrap_int(self.fetch(5)) + self.width = self.space.unwrap_int(self.fetch(6)) + self.height = self.space.unwrap_int(self.fetch(7)) + self.source_x = self.space.unwrap_int(self.fetch(8)) + self.source_y = self.space.unwrap_int(self.fetch(9)) + self.clip_x = self.space.unwrap_int(self.fetch(10)) + self.clip_y = self.space.unwrap_int(self.fetch(11)) + self.clip_width = self.space.unwrap_int(self.fetch(12)) + self.clip_height = self.space.unwrap_int(self.fetch(13)) + self.color_map = self.fetch(14) + + def clip_range(self): + if self.dest_x >= self.clip_x: + self.sx = self.source_x + self.dx = self.dest_x + self.w = self.width + else: + self.sx = self.source_x + (self.clip_x - self.dest_x) + self.w = self.width - (self.clip_x - self.dest_x) + self.dx = self.clip_x + if self.dx + self.w > self.clip_x + self.clip_width: + self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width)) + if self.dest_x >= self.clip_y: + self.sy = self.source_y + self.dy = self.dest_y + self.h = self.height + else: + self.sy = self.source_y + self.clip_y - self.dest_y + self.h = self.height - (self.clip_y - self.dest_y) + self.dy = self.clip_y + if self.dy + self.h > self.clip_y + self.clip_height: + self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height)) + if self.sx < 0: + self.dx = self.dx - self.sx + self.w = self.w + self.sx + self.sx = 0 + if self.source_form and self.sx + self.w > self.source_form.width: + self.w = self.w - (self.sx + self.w - self.source_form.width) + if self.sy < 0: + self.dy = self.dy - self.su + self.h = self.h + self.sy + self.sy = 0 + if self.source_form and self.sy + self.h > self.source_form.height: + self.h = self.h - (self.sy + self.h - self.source_form.height) + + def compute_masks(self): + self.dest_bits = self.dest_form.bits + self.dest_raster = (self.dest_form.width - 1) / 16 + 1 + if self.source_form: + self.source_bits = self.source_form.bits + self.source_raster = (self.source_form.width - 1) / 16 + 1 + self.skew = (self.sx - self.dx) & 15 + start_bits = 16 - (self.dx & 15) + self.mask1 = BitBltShadow.RightMasks[start_bits] + end_bits = 15 - ((self.dx + self.w - 1) & 15) + self.mask2 = ~BitBltShadow.RightMasks[end_bits] + if self.skew == 0: + self.skew_mask = 0 + else: + self.skew_mask = BitBltShadow.RightMasks[16 - self.skew] + if self.w < start_bits: + self.mask1 = self.mask1 & self.mask2 + self.mask2 = 0 + self.n_words = 1 + else: + self.n_words = (self.w - start_bits - 1) / 16 + 2 + + def check_overlap(self): + self.h_dir = 1 + self.v_dir = 1 + if (self.source_form.w_self().is_same_object(self.dest_form.w_self()) and + self.dy >= self.sy): + if self.dy > self.sy: + self.v_dir = -1 + self.sy = self.sy + self.h - 1 + self.dy = self.dy + self.h - 1 + elif self.dx > self.sx: + self.h_dir = -1 + self.sx = self.sx + self.w - 1 + self.dx = self.dx + self.w - 1 + self.skew_mask = ~self.skew_mask + self.mask1, self.mask2 = self.mask2, self.mask1 + + def calculate_offsets(self): + self.preload = self.source_form and self.skew_mask != 0 and self.skew <= (self.sx & 15) + if self.h_dir < 0: + self.preload = not self.preload + self.source_index = self.sy * self.source_raster + self.sx / 16 + self.dest_index = self.dy * self.dest_raster + self.dx / 16 + self.source_delta = ((self.source_raster * + self.v_dir - + (self.n_words + (1 if self.preload else 0))) * + self.h_dir) + self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir + + def copy_loop(self): + for i in xrange(self.h): + if self.halftone_bits: + halftone_word = self.halftone_bits[self.dy & 15] + self.dy = self.dy + self.v_dir + else: + halftone_word = BitBltShadow.AllOnes + skew_word = halftone_word + if self.preload: + prev_word = self.source_bits[self.source_index] + self.source_index = self.source_index + self.h_dir + else: + prev_word = 0 + merge_mask = self.mask1 + for word in xrange(self.n_words): + if self.source_form: + prev_word = prev_word & self.skew_mask + this_word = self.source_bits[self.source_index] + skew_word = prev_word | (this_word & ~self.skew_mask) + prev_word = this_word + skew_word = (self.bit_shift(skew_word, self.skew) | + self.bit_shift(skew_word, self.skew - 16)) + merge_word = self.merge( + skew_word & halftone_word, + self.dest_bits[self.dest_index] + ) + self.dest_bits[self.dest_index] = ( + (merge_mask & merge_word) | + (~merge_mask & self.dest_bits[self.dest_index]) + ) + self.source_index = self.source_index + self.h_dir + self.dest_index = self.dest_index + self.h_dir + if word == (self.n_words - 1): + merge_mask = self.mask2 + else: + merge_mask = BitBltShadow.AllOnes + self.source_index = self.source_index + self.source_delta + self.dest_index = self.dest_index + self.dest_delta + self.dest_form.replace_bits(self.dest_bits) + + def bit_shift(self, target, amount): + if amount > 0: + return target << amount + else: + return target >> -amount + + def merge(self, source_word, dest_word): + if self.combination_rule == 0: + return 0 + elif self.combination_rule == 1: + return source_word & dest_word + elif self.combination_rule == 2: + return source_word & ~dest_word + elif self.combination_rule == 3: + return source_word + elif self.combination_rule == 4: + return ~source_word & dest_word + elif self.combination_rule == 5: + return dest_word + elif self.combination_rule == 6: + return source_word ^ dest_word + elif self.combination_rule == 7: + return source_word | dest_word + elif self.combination_rule == 8: + return ~source_word & ~dest_word + elif self.combination_rule == 9: + return ~source_word ^ dest_word + elif self.combination_rule == 10: + return ~dest_word + elif self.combination_rule == 11: + return source_word | ~dest_word + elif self.combination_rule == 12: + return ~source_word + elif self.combination_rule == 13: + return ~source_word | dest_word + elif self.combination_rule == 14: + return ~source_word | ~dest_word + elif self.combination_rule == 15: + return BitBltShadow.AllOnes + + +class FormShadow(AbstractCachingShadow): + _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] + + def sync_cache(self): + w_bits = self.fetch(0) + if isinstance(w_bits, model.W_WordsObject): + self.bits = w_bits.words + else: + self.bits = [ord(byte) for byte in w_bits.bytes] + self.width = self.space.unwrap_int(self.fetch(1)) + self.height = self.space.unwrap_int(self.fetch(2)) + self.depth = self.space.unwrap_int(self.fetch(3)) + w_offset = self.fetch(4) + if not w_offset is self.space.w_nil: + self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) + self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) + + def replace_bits(self, bits): + w_bits = self.fetch(0) + if isinstance(bits, model.W_WordsObject): + w_bits.words[:] = bits + else: + w_bits.bytes[:] = [chr(byte) for byte in bits] From noreply at buildbot.pypy.org Mon Mar 11 16:55:41 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 11 Mar 2013 16:55:41 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: disable singlefloat on ARMHF Message-ID: <20130311155541.8D3CF1C39E5@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62291:0af8d7b9a125 Date: 2013-03-11 17:54 +0200 http://bitbucket.org/pypy/pypy/changeset/0af8d7b9a125/ Log: disable singlefloat on ARMHF 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 @@ -114,3 +114,4 @@ """ARM v7 uses hardfp ABI, requires vfp""" use_hf_abi = True supports_floats = False + supports_singlefloats = False From noreply at buildbot.pypy.org Mon Mar 11 17:08:25 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 11 Mar 2013 17:08:25 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: Remove unused _condition_ handling in ExtRegistryEntry Message-ID: <20130311160825.242FA1C143B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62292:ffab5deb828b Date: 2013-03-11 16:07 +0000 http://bitbucket.org/pypy/pypy/changeset/ffab5deb828b/ Log: Remove unused _condition_ handling in ExtRegistryEntry diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -22,17 +22,11 @@ for k in key: selfcls._register(dict, k) else: - for basecls in selfcls.__mro__: - if '_condition_' in basecls.__dict__: - cond = basecls.__dict__['_condition_'] - break - else: - cond = None try: family = dict[key] except KeyError: family = dict[key] = ClassFamily() - family.add(selfcls, cond) + family.add(selfcls) def _register_value(selfcls, key): selfcls._register(EXT_REGISTRY_BY_VALUE, key) diff --git a/rpython/rtyper/test/test_extregistry.py b/rpython/rtyper/test/test_extregistry.py --- a/rpython/rtyper/test/test_extregistry.py +++ b/rpython/rtyper/test/test_extregistry.py @@ -9,7 +9,7 @@ from rpython.rtyper.test.test_llinterp import interpret from rpython.rtyper.rmodel import Repr -def dummy(): +def dummy(): raiseNameError class Entry(ExtRegistryEntry): @@ -20,7 +20,7 @@ def func(): x = dummy() return x - + a = RPythonAnnotator() s = a.build_types(func, []) assert isinstance(s, annmodel.SomeInteger) @@ -38,20 +38,20 @@ def func(): x = dummy2() return x - + a = RPythonAnnotator() s = a.build_types(func, []) assert isinstance(s, annmodel.SomeInteger) - + def test_register_type_with_callable(): class DummyType(object): pass - + dummy_type = DummyType() - + def func(): return dummy_type - + class Entry(ExtRegistryEntry): _type_ = DummyType def compute_annotation(self): @@ -65,15 +65,15 @@ def test_register_metatype(): class MetaType(type): pass - + class RealClass(object): __metaclass__ = MetaType - + real_class = RealClass() - + def func(): return real_class - + class Entry(ExtRegistryEntry): _metatype_ = MetaType def compute_annotation(self): @@ -88,13 +88,13 @@ def test_register_metatype_2(): class MetaType(type): pass - + class RealClass(object): __metaclass__ = MetaType - + def func(real_class): return real_class - + class Entry(ExtRegistryEntry): _metatype_ = MetaType def compute_annotation(self): @@ -119,7 +119,7 @@ def func(): return dummy_func() - + res = interpret(func, []) assert res == 42 @@ -127,18 +127,18 @@ def test_register_type_with_get_repr(): class DummyClass(object): pass - + class SomeDummyObject(annmodel.SomeObject): def rtyper_makerepr(self, rtyper): entry = extregistry.lookup_type(self.knowntype) return entry.get_repr(rtyper, self) - + def rtyper_makekey( self ): return self.__class__, self.knowntype class DummyRepr(Repr): lowleveltype = lltype.Signed - + def convert_const(self, value): return 42 @@ -155,14 +155,14 @@ return DummyRepr() dummy_class = DummyClass() - + def func(): return dummy_class - + res = interpret(func, []) - + assert res == 42 - + def test_register_unhashable(): lst1 = [5, 6] lst2 = [5, 6] @@ -178,26 +178,3 @@ _about_ = n1 assert isinstance(extregistry.lookup(n1), Entry) assert isinstance(extregistry.lookup(n2), Entry) - -def test_condition(): - stuff = object() - class Entry(ExtRegistryEntry): - _about_ = stuff - _condition_ = lambda n: n == 'yes' - assert isinstance(extregistry.lookup(stuff, 'yes'), Entry) - py.test.raises(KeyError, "extregistry.lookup(stuff, 'no')") - py.test.raises(KeyError, "extregistry.lookup(stuff)") - - class Entry2(ExtRegistryEntry): - _about_ = stuff - assert isinstance(extregistry.lookup(stuff, 'yes'), Entry) - assert isinstance(extregistry.lookup(stuff, 'no'), Entry2) - assert isinstance(extregistry.lookup(stuff), Entry2) - - otherstuff = object() - class Entry3(Entry): - _about_ = otherstuff - # _condition_ is inherited from Entry - assert isinstance(extregistry.lookup(otherstuff, 'yes'), Entry3) - py.test.raises(KeyError, "extregistry.lookup(otherstuff, 'no')") - py.test.raises(KeyError, "extregistry.lookup(otherstuff)") From noreply at buildbot.pypy.org Mon Mar 11 18:44:00 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 11 Mar 2013 18:44:00 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: kill unused ClassFamily.conditionals Message-ID: <20130311174400.17B621C3A12@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62293:d237feec99cf Date: 2013-03-11 16:22 +0000 http://bitbucket.org/pypy/pypy/changeset/d237feec99cf/ Log: kill unused ClassFamily.conditionals diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -41,24 +41,13 @@ def __init__(self): self.default = None - self.conditionals = [] def add(self, cls, cond=None): - if cond is None: - assert self.default is None, ( - "duplicate extregistry entry %r" % (cls,)) - self.default = cls - else: - self.conditionals.append((cls, cond)) + assert self.default is None, ( + "duplicate extregistry entry %r" % (cls,)) + self.default = cls def match(self, config): - if config is not None: - matches = [cls for cls, cond in self.conditionals - if cond(config)] - if matches: - assert len(matches) == 1, ( - "multiple extregistry matches: %r" % (matches,)) - return matches[0] if self.default: return self.default raise KeyError("no default extregistry entry") From noreply at buildbot.pypy.org Mon Mar 11 18:44:01 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 11 Mar 2013 18:44:01 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: kill ClassFamily, store Entries directly in the registries Message-ID: <20130311174401.62DB41C3A1A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62294:4bc2b9dcd4a1 Date: 2013-03-11 17:43 +0000 http://bitbucket.org/pypy/pypy/changeset/4bc2b9dcd4a1/ Log: kill ClassFamily, store Entries directly in the registries diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -22,11 +22,9 @@ for k in key: selfcls._register(dict, k) else: - try: - family = dict[key] - except KeyError: - family = dict[key] = ClassFamily() - family.add(selfcls) + if key in dict: + raise ValueError("duplicate extregistry entry %r" % (selfcls,)) + dict[key] = selfcls def _register_value(selfcls, key): selfcls._register(EXT_REGISTRY_BY_VALUE, key) @@ -37,21 +35,6 @@ def _register_metatype(selfcls, key): selfcls._register(EXT_REGISTRY_BY_METATYPE, key) -class ClassFamily(object): - - def __init__(self): - self.default = None - - def add(self, cls, cond=None): - assert self.default is None, ( - "duplicate extregistry entry %r" % (cls,)) - self.default = cls - - def match(self, config): - if self.default: - return self.default - raise KeyError("no default extregistry entry") - class ExtRegistryEntry(object): __metaclass__ = AutoRegisteringType @@ -144,9 +127,9 @@ def _lookup_type_cls(tp, config): try: - return EXT_REGISTRY_BY_TYPE[tp].match(config) + return EXT_REGISTRY_BY_TYPE[tp] except (KeyError, TypeError): - return EXT_REGISTRY_BY_METATYPE[type(tp)].match(config) + return EXT_REGISTRY_BY_METATYPE[type(tp)] def lookup_type(tp, config=None): Entry = _lookup_type_cls(tp, config) @@ -161,7 +144,7 @@ def _lookup_cls(instance, config): try: - return EXT_REGISTRY_BY_VALUE[instance].match(config) + return EXT_REGISTRY_BY_VALUE[instance] except (KeyError, TypeError): return _lookup_type_cls(type(instance), config) From noreply at buildbot.pypy.org Mon Mar 11 20:22:12 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 11 Mar 2013 20:22:12 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: kill useless config parameters from extregistry public interface Message-ID: <20130311192212.E88D01C3A12@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62295:21ceb561baa3 Date: 2013-03-11 19:21 +0000 http://bitbucket.org/pypy/pypy/changeset/21ceb561baa3/ Log: kill useless config parameters from extregistry public interface diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -125,36 +125,36 @@ # ____________________________________________________________ # Public interface to access the registry -def _lookup_type_cls(tp, config): +def _lookup_type_cls(tp): try: return EXT_REGISTRY_BY_TYPE[tp] except (KeyError, TypeError): return EXT_REGISTRY_BY_METATYPE[type(tp)] -def lookup_type(tp, config=None): - Entry = _lookup_type_cls(tp, config) +def lookup_type(tp, _ignored=None): + Entry = _lookup_type_cls(tp) return Entry(tp) -def is_registered_type(tp, config=None): +def is_registered_type(tp, _ignored=None): try: - _lookup_type_cls(tp, config) + _lookup_type_cls(tp) except KeyError: return False return True -def _lookup_cls(instance, config): +def _lookup_cls(instance): try: return EXT_REGISTRY_BY_VALUE[instance] except (KeyError, TypeError): - return _lookup_type_cls(type(instance), config) + return _lookup_type_cls(type(instance)) -def lookup(instance, config=None): - Entry = _lookup_cls(instance, config) +def lookup(instance, _ignored=None): + Entry = _lookup_cls(instance) return Entry(type(instance), instance) -def is_registered(instance, config=None): +def is_registered(instance, _ignored=None): try: - _lookup_cls(instance, config) + _lookup_cls(instance) except KeyError: return False return True From noreply at buildbot.pypy.org Mon Mar 11 20:44:14 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 11 Mar 2013 20:44:14 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: kill unused SomeExternalObject Message-ID: <20130311194414.631581C3A11@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62296:969996d0f71b Date: 2013-03-11 19:43 +0000 http://bitbucket.org/pypy/pypy/changeset/969996d0f71b/ Log: kill unused SomeExternalObject diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -11,7 +11,7 @@ from rpython.annotator.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue from rpython.annotator.model import SomeInstance, SomeBuiltin, SomeIterator from rpython.annotator.model import SomePBC, SomeFloat, s_None, SomeByteArray -from rpython.annotator.model import SomeExternalObject, SomeWeakRef +from rpython.annotator.model import SomeWeakRef from rpython.annotator.model import SomeAddress, SomeTypedAddressAccess from rpython.annotator.model import SomeSingleFloat, SomeLongFloat, SomeType from rpython.annotator.model import unionof, UnionError, missing_operation @@ -131,7 +131,7 @@ def is_((obj1, obj2)): r = SomeBool() if obj2.is_constant(): - if obj1.is_constant(): + if obj1.is_constant(): r.const = obj1.const is obj2.const if obj2.const is None and not obj1.can_be_none(): r.const = False @@ -148,12 +148,12 @@ annotator = bk.annotator op = block.operations[i] - assert op.opname == "is_" - assert len(op.args) == 2 + assert op.opname == "is_" + assert len(op.args) == 2 def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): - add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, + add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, bk.valueoftype(src_obj.const)) assert annotator.binding(op.args[tgt_arg]) == tgt_obj @@ -179,7 +179,7 @@ getbookkeeper().count("coerce", obj1, obj2) return pair(obj1, obj2).union() # reasonable enough - # approximation of an annotation intersection, the result should be the annotation obj or + # approximation of an annotation intersection, the result should be the annotation obj or # the intersection of obj and improvement def improve((obj, improvement)): if not improvement.contains(obj) and obj.contains(improvement): @@ -330,7 +330,7 @@ return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') - + add_knowntypedata(knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): @@ -341,7 +341,7 @@ # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) - if (isinstance(op.args[1], Constant) and + if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: @@ -362,14 +362,14 @@ class __extend__(pairtype(SomeBool, SomeBool)): def union((boo1, boo2)): - s = SomeBool() - if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): - s.const = boo1.const + s = SomeBool() + if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): + s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) s.set_knowntypedata(ktd) - return s + return s def and_((boo1, boo2)): s = SomeBool() @@ -394,13 +394,13 @@ if boo2.const: s.const = True return s - + def xor((boo1, boo2)): s = SomeBool() if boo1.is_constant() and boo2.is_constant(): s.const = boo1.const ^ boo2.const return s - + class __extend__(pairtype(SomeString, SomeString)): def union((str1, str2)): @@ -503,7 +503,7 @@ return s_string.__class__() class __extend__(pairtype(SomeFloat, SomeFloat)): - + def union((flt1, flt2)): return SomeFloat() @@ -520,13 +520,13 @@ class __extend__(pairtype(SomeSingleFloat, SomeSingleFloat)): - + def union((flt1, flt2)): return SomeSingleFloat() class __extend__(pairtype(SomeLongFloat, SomeLongFloat)): - + def union((flt1, flt2)): return SomeLongFloat() @@ -618,7 +618,7 @@ class __extend__(pairtype(SomeTuple, SomeInteger)): - + def getitem((tup1, int2)): if int2.is_immutable_constant(): try: @@ -632,7 +632,7 @@ class __extend__(pairtype(SomeList, SomeInteger)): - + def mul((lst1, int2)): return lst1.listdef.offspring() @@ -651,27 +651,27 @@ getitem_idx_key = getitem_idx def setitem((lst1, int2), s_value): - getbookkeeper().count("list_setitem", int2) + getbookkeeper().count("list_setitem", int2) lst1.listdef.mutate() lst1.listdef.generalize(s_value) setitem.can_only_throw = [IndexError] def delitem((lst1, int2)): - getbookkeeper().count("list_delitem", int2) + getbookkeeper().count("list_delitem", int2) lst1.listdef.resize() delitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] @@ -683,14 +683,14 @@ class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem_idx.can_only_throw = [IndexError] @@ -702,7 +702,7 @@ class __extend__(pairtype(SomeInteger, SomeString), pairtype(SomeInteger, SomeUnicodeString)): - + def mul((int1, str2)): # xxx do we want to support this getbookkeeper().count("str_mul", str2, int1) return str2.basestringclass() @@ -722,7 +722,7 @@ return result class __extend__(pairtype(SomeInteger, SomeList)): - + def mul((int1, lst2)): return lst2.listdef.offspring() @@ -795,7 +795,7 @@ class __extend__(pairtype(SomePBC, SomePBC)): - def union((pbc1, pbc2)): + def union((pbc1, pbc2)): d = pbc1.descriptions.copy() d.update(pbc2.descriptions) return SomePBC(d, can_be_None = pbc1.can_be_None or pbc2.can_be_None) @@ -862,7 +862,6 @@ _make_none_union('SomeUnicodeString', 'can_be_None=True') _make_none_union('SomeList', 'obj.listdef') _make_none_union('SomeDict', 'obj.dictdef') -_make_none_union('SomeExternalObject', 'obj.knowntype') _make_none_union('SomeWeakRef', 'obj.classdef') # getitem on SomePBCs, in particular None fails @@ -889,12 +888,6 @@ raise AnnotatorError('add on %r' % pbc) return s_ImpossibleValue -class __extend__(pairtype(SomeExternalObject, SomeExternalObject)): - def union((ext1, ext2)): - if ext1.knowntype == ext2.knowntype: - return SomeExternalObject(ext1.knowntype) - return SomeObject() - # ____________________________________________________________ # annotation of low-level types from rpython.annotator.model import SomePtr, SomeOOInstance, SomeOOClass diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -83,7 +83,7 @@ def fmt_knowntype(self, t): return t.__name__ - + def contains(self, other): if self == other: return True @@ -482,16 +482,6 @@ """ knowntype = MethodType -class SomeExternalObject(SomeObject): - """Stands for an object of 'external' type. External types have a Repr - controlled by rpython.rtyper.extregistry.""" - - def __init__(self, knowntype): - self.knowntype = knowntype - - def can_be_none(self): - return True - class SomeImpossibleValue(SomeObject): """The empty set. Instances are placeholders for objects that will never show up at run-time, e.g. elements of an empty list.""" @@ -568,7 +558,7 @@ immutable = True def __init__(self, ll_ptrtype, func): self.ll_ptrtype = ll_ptrtype - self.func = func + self.func = func def can_be_none(self): return False @@ -678,7 +668,7 @@ T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets) return SomeInteriorPtr(T) return lltype_to_annotation(lltype.typeOf(v)) - + # ____________________________________________________________ class UnionError(Exception): @@ -729,14 +719,14 @@ def commonbase(cls1, cls2): # XXX single inheritance only XXX hum l1 = inspect.getmro(cls1) - l2 = inspect.getmro(cls2) - if l1[-1] != object: - l1 = l1 + (object,) - if l2[-1] != object: - l2 = l2 + (object,) - for x in l1: - if x in l2: - return x + l2 = inspect.getmro(cls2) + if l1[-1] != object: + l1 = l1 + (object,) + if l2[-1] != object: + l2 = l2 + (object,) + for x in l1: + if x in l2: + return x assert 0, "couldn't get to commonbase of %r and %r" % (cls1, cls2) def missing_operation(cls, name): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -9,7 +9,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ + SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -366,7 +366,7 @@ s_value = dct.dictdef.read_value() return (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)) - + def len(dct): if dct._is_empty(): return immutablevalue(0) @@ -746,29 +746,9 @@ bookkeeper = getbookkeeper() for arg, expected in zip(args.unpack()[0], self.args_s): assert expected.contains(arg) - + return self.s_result -class __extend__(SomeExternalObject): - def getattr(p, s_attr): - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - s_value = entry.get_field_annotation(p.knowntype, attr) - return s_value - else: - return SomeObject() - getattr.can_only_throw = [] - - def setattr(p, s_attr, s_value): - assert s_attr.is_constant() - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - entry.set_field_annotation(p.knowntype, attr, s_value) - - def is_true(p): - return s_Bool - # annotation of low-level types from rpython.annotator.model import SomePtr, SomeLLADTMeth from rpython.annotator.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth @@ -835,7 +815,7 @@ return SomeOOBoundMeth(r.ootype, s_attr.const) return ll_to_annotation(v) - def setattr(r, s_attr, s_value): + def setattr(r, s_attr, s_value): assert s_attr.is_constant(), "setattr on ref %r with non-constant field-name" % r.ootype v = annotation_to_lltype(s_value) example = r.ootype._example() diff --git a/rpython/rtyper/rexternalobj.py b/rpython/rtyper/rexternalobj.py deleted file mode 100644 --- a/rpython/rtyper/rexternalobj.py +++ /dev/null @@ -1,21 +0,0 @@ -from rpython.annotator import model as annmodel -from rpython.rtyper import extregistry -from rpython.rtyper.lltypesystem import lltype - -# ExternalObjects - - -class __extend__(annmodel.SomeExternalObject): - def rtyper_makerepr(self, rtyper): - # delegate to the get_repr() of the extregistrered Entry class - entry = extregistry.lookup_type(self.knowntype) - return entry.get_repr(rtyper, self) - - def rtyper_makekey(self): - # grab all attributes of the SomeExternalObject for the key - attrs = lltype.frozendict(self.__dict__) - if 'const' in attrs: - del attrs['const'] - if 'const_box' in attrs: - del attrs['const_box'] - return self.__class__, attrs diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -1012,7 +1012,6 @@ from rpython.rtyper import rrange from rpython.rtyper import rstr, rdict, rlist, rbytearray from rpython.rtyper import rclass, rbuiltin, rpbc -from rpython.rtyper import rexternalobj from rpython.rtyper import rptr from rpython.rtyper import rgeneric from rpython.rtyper import rweakref From noreply at buildbot.pypy.org Mon Mar 11 22:33:56 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 11 Mar 2013 22:33:56 +0100 (CET) Subject: [pypy-commit] pypy default: cpyext: Correctly invalidate the type cache when tp_dict is updated directly. Message-ID: <20130311213357.05DAE1C3A1A@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r62297:4e520ab34e44 Date: 2013-03-11 22:33 +0100 http://bitbucket.org/pypy/pypy/changeset/4e520ab34e44/ Log: cpyext: Correctly invalidate the type cache when tp_dict is updated directly. Fixes issue1106. diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -85,6 +85,8 @@ """Base class for all cpyext tests.""" spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array', 'itertools', 'rctime', 'binascii']) + spaceconfig['std.withmethodcache'] = True + enable_leak_checking = True @staticmethod diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -288,7 +288,38 @@ class C(object): pass assert module.name_by_heaptype(C) == "C" - + + def test_type_dict(self): + foo = self.import_module("foo") + module = self.import_extension('test', [ + ("hack_tp_dict", "METH_O", + ''' + PyTypeObject *type = args->ob_type; + PyObject *a1 = PyLong_FromLong(1); + PyObject *a2 = PyLong_FromLong(2); + PyObject *value; + + if (PyDict_SetItemString(type->tp_dict, "a", + a1) < 0) + return NULL; + Py_DECREF(a1); + PyType_Modified(type); + value = PyObject_GetAttrString(type, "a"); + Py_DECREF(value); + + if (PyDict_SetItemString(type->tp_dict, "a", + a2) < 0) + return NULL; + Py_DECREF(a2); + PyType_Modified(type); + value = PyObject_GetAttrString(type, "a"); + return value; + ''' + ) + ]) + obj = foo.new() + assert module.hack_tp_dict(obj) == 2 + class TestTypes(BaseApiTest): def test_type_attributes(self, space, api): @@ -326,7 +357,7 @@ w_obj = api._PyType_Lookup(w_type, space.wrap("__invalid")) assert w_obj is None assert api.PyErr_Occurred() is None - + class AppTestSlots(AppTestCpythonExtensionBase): def test_some_slots(self): module = self.import_extension('foo', [ diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -729,6 +729,9 @@ subtypes. This function must be called after any manual modification of the attributes or base classes of the type. """ - # PyPy already takes care of direct modifications to type.__dict__ - # (which is a W_DictProxyObject). - pass + # Invalidate the type cache in case of a builtin type. + if not isinstance(w_obj, W_TypeObject): + return + if w_obj.is_cpytype(): + w_obj.mutated(None) + diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py --- a/pypy/objspace/std/dictproxyobject.py +++ b/pypy/objspace/std/dictproxyobject.py @@ -54,10 +54,11 @@ raise if not w_type.is_cpytype(): raise - # xxx obscure workaround: allow cpyext to write to type->tp_dict - # xxx even in the case of a builtin type. - # xxx like CPython, we assume that this is only done early after - # xxx the type is created, and we don't invalidate any cache. + # Allow cpyext to write to type->tp_dict even in the case + # of a builtin type. + # Like CPython, we assume that this is only done early + # after the type is created, and we don't invalidate any + # cache. User code shoud call PyType_Modified(). w_type.dict_w[key] = w_value def setdefault(self, w_dict, w_key, w_default): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -161,7 +161,7 @@ generic mutation. """ space = w_self.space - assert w_self.is_heaptype() + assert w_self.is_heaptype() or w_self.is_cpytype() if (not space.config.objspace.std.withtypeversion and not space.config.objspace.std.getattributeshortcut and not space.config.objspace.std.withidentitydict and From noreply at buildbot.pypy.org Mon Mar 11 23:02:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Mar 2013 23:02:02 +0100 (CET) Subject: [pypy-commit] pypy default: unused error message in sqlite Message-ID: <20130311220202.A85EF1C3A12@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62298:7d7942e84071 Date: 2013-03-11 16:56 -0400 http://bitbucket.org/pypy/pypy/changeset/7d7942e84071/ Log: unused error message in sqlite diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -480,8 +480,6 @@ @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): - if not isinstance(sql, basestring): - raise Warning("SQL is of wrong type. Must be string or unicode.") return self._statement_cache.get(sql, self.row_factory) def cursor(self, factory=None): @@ -1007,7 +1005,7 @@ self.__con = connection if not isinstance(sql, basestring): - raise ValueError("sql must be a string") + raise Warning("SQL is of wrong type. Must be string or unicode.") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): self._kind = Statement._DML From noreply at buildbot.pypy.org Mon Mar 11 23:16:06 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 11 Mar 2013 23:16:06 +0100 (CET) Subject: [pypy-commit] pypy default: re-enable the keys fastpath: the DictStrategy method was renamed to w_keys a Message-ID: <20130311221606.279C81C3A1C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62299:977a0cb12965 Date: 2013-03-11 15:15 -0700 http://bitbucket.org/pypy/pypy/changeset/977a0cb12965/ Log: re-enable the keys fastpath: the DictStrategy method was renamed to w_keys a while back diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py --- a/pypy/objspace/std/dictproxyobject.py +++ b/pypy/objspace/std/dictproxyobject.py @@ -82,7 +82,7 @@ def length(self, w_dict): return len(self.unerase(w_dict.dstorage).dict_w) - def keys(self, w_dict): + def w_keys(self, w_dict): space = self.space return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys()) From noreply at buildbot.pypy.org Mon Mar 11 23:19:52 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 11 Mar 2013 23:19:52 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130311221952.40BC71C3A1A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62300:0d2d672668f3 Date: 2013-03-11 15:19 -0700 http://bitbucket.org/pypy/pypy/changeset/0d2d672668f3/ Log: merge default diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -128,7 +128,14 @@ def spawn_local_handler(): if hasattr(sys, 'pypy_objspaceclass'): - python = '/usr/bin/python' + # if 'python' is actually PyPy, e.g. in a virtualenv, then + # try hard to find a real CPython + try: + python = subprocess.check_output( + 'env -i $SHELL -l -c "which python"', shell=True).strip() + except subprocess.CalledProcessError: + # did not work, fall back to 'python' + python = 'python' else: python = sys.executable args = [python, '-u', GRAPHSERVER, '--stdio'] diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -9,6 +9,7 @@ PREFIX = os.path.normpath(sys.prefix) +EXEC_PREFIX = os.path.normpath(sys.exec_prefix) project_base = os.path.dirname(os.path.abspath(sys.executable)) python_build = False diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -480,8 +480,6 @@ @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): - if not isinstance(sql, basestring): - raise Warning("SQL is of wrong type. Must be string or unicode.") return self._statement_cache.get(sql, self.row_factory) def cursor(self, factory=None): @@ -513,7 +511,7 @@ def _begin(self): statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, - byref(statement), None) + byref(statement), None) try: if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -537,7 +535,7 @@ statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, - byref(statement), None) + byref(statement), None) try: if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -566,7 +564,7 @@ statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, - byref(statement), None) + byref(statement), None) try: if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -600,10 +598,10 @@ if isinstance(name, unicode): name = name.encode('utf-8') ret = _lib.sqlite3_create_function(self._db, name, num_args, - _lib.SQLITE_UTF8, None, - c_closure, - cast(None, _STEP), - cast(None, _FINAL)) + _lib.SQLITE_UTF8, None, + c_closure, + cast(None, _STEP), + cast(None, _FINAL)) if ret != _lib.SQLITE_OK: raise self.OperationalError("Error creating function") @@ -669,10 +667,10 @@ if isinstance(name, unicode): name = name.encode('utf-8') ret = _lib.sqlite3_create_function(self._db, name, num_args, - _lib.SQLITE_UTF8, None, - cast(None, _FUNC), - c_step_callback, - c_final_callback) + _lib.SQLITE_UTF8, None, + cast(None, _FUNC), + c_step_callback, + c_final_callback) if ret != _lib.SQLITE_OK: raise self._get_exception(ret) @@ -839,14 +837,14 @@ return func(self, *args, **kwargs) return wrapper - @__check_cursor_wrap - def execute(self, sql, params=[]): + def __execute(self, multiple, sql, many_params): self.__locked = True try: - self.__description = None self._reset = False if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") + self.__description = None + self.__rowcount = -1 self.__statement = self.__connection._statement_cache.get( sql, self.row_factory) @@ -858,83 +856,61 @@ if not self.__connection._in_transaction: self.__connection._begin() - self.__statement._set_params(params) + if multiple and self.__statement._kind != Statement._DML: + raise ProgrammingError("executemany is only for DML statements") - # Actually execute the SQL statement - ret = _lib.sqlite3_step(self.__statement._statement) - if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): - self.__statement._reset() - self.__connection._in_transaction = \ - not _lib.sqlite3_get_autocommit(self.__connection._db) - raise self.__connection._get_exception(ret) + for params in many_params: + self.__statement._set_params(params) - if self.__statement._kind == Statement._DML: - self.__statement._reset() + # Actually execute the SQL statement + ret = _lib.sqlite3_step(self.__statement._statement) + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): + self.__statement._reset() + self.__connection._in_transaction = \ + not _lib.sqlite3_get_autocommit(self.__connection._db) + raise self.__connection._get_exception(ret) - if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: - self.__statement._build_row_cast_map() - self.__statement._readahead(self) - else: - self.__statement._item = None - self.__statement._exhausted = True + if self.__statement._kind == Statement._DML: + self.__statement._reset() - self.__rowcount = -1 - if self.__statement._kind == Statement._DML: - self.__rowcount = _lib.sqlite3_changes(self.__connection._db) + if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: + self.__statement._build_row_cast_map() + self.__statement._readahead(self) + else: + self.__statement._item = None + self.__statement._exhausted = True + + if self.__statement._kind == Statement._DML: + if self.__rowcount == -1: + self.__rowcount = 0 + self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False return self @__check_cursor_wrap + def execute(self, sql, params=[]): + return self.__execute(False, sql, [params]) + + @__check_cursor_wrap def executemany(self, sql, many_params): - self.__locked = True - try: - self.__description = None - self._reset = False - if not isinstance(sql, basestring): - raise ValueError("operation parameter must be str or unicode") - self.__statement = self.__connection._statement_cache.get( - sql, self.row_factory) - - if self.__statement._kind == Statement._DML: - if self.__connection._isolation_level is not None: - if not self.__connection._in_transaction: - self.__connection._begin() - else: - raise ProgrammingError( - "executemany is only for DML statements") - - self.__rowcount = 0 - for params in many_params: - self.__statement._set_params(params) - ret = _lib.sqlite3_step(self.__statement._statement) - if ret != _lib.SQLITE_DONE: - self.__statement._reset() - self.__connection._in_transaction = \ - not _lib.sqlite3_get_autocommit(self.__connection._db) - raise self.__connection._get_exception(ret) - self.__statement._reset() - self.__rowcount += _lib.sqlite3_changes(self.__connection._db) - finally: - self.__locked = False - - return self + return self.__execute(True, sql, many_params) def executescript(self, sql): - self.__description = None + self.__check_cursor() self._reset = False - self.__check_cursor() - statement = c_void_p() if isinstance(sql, unicode): sql = sql.encode('utf-8') elif not isinstance(sql, str): raise ValueError("script argument must be unicode or string.") - c_sql = c_char_p(sql) + sql = c_char_p(sql) + statement = c_void_p() self.__connection.commit() while True: - rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1, byref(statement), byref(c_sql)) + rc = _lib.sqlite3_prepare(self.__connection._db, sql, -1, + byref(statement), byref(sql)) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -955,7 +931,7 @@ if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) - if not c_sql.value: + if not sql.value: break return self @@ -1029,7 +1005,7 @@ self.__con = connection if not isinstance(sql, basestring): - raise ValueError("sql must be a string") + raise Warning("SQL is of wrong type. Must be string or unicode.") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): self._kind = Statement._DML @@ -1042,24 +1018,26 @@ self._exhausted = False self._row_factory = None - self._statement = c_void_p() - next_char = c_char_p() if isinstance(sql, unicode): sql = sql.encode('utf-8') + sql = c_char_p(sql) + self._statement = c_void_p() - ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(next_char)) + ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, + byref(self._statement), byref(sql)) if ret == _lib.SQLITE_OK and self._statement.value is None: - # an empty statement, we work around that, as it's the least trouble - ret = _lib.sqlite3_prepare_v2(self.__con._db, b"select 42", -1, byref(self._statement), byref(next_char)) + # an empty statement, work around that, as it's the least trouble + sql = c_char_p(b"select 42") + ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, + byref(self._statement), byref(sql)) self._kind = Statement._DQL if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) - next_char = next_char.value.decode('utf-8') - if _check_remaining_sql(next_char): - raise Warning("One and only one statement required: %r" % - next_char) + sql = sql.value.decode('utf-8') + if _check_remaining_sql(sql): + raise Warning("You can only execute one statement at a time.") def __del__(self): if self._statement: @@ -1077,35 +1055,6 @@ self._in_use = False self._exhausted = False - def _build_row_cast_map(self): - self.__row_cast_map = [] - for i in xrange(_lib.sqlite3_column_count(self._statement)): - converter = None - - if self.__con._detect_types & PARSE_COLNAMES: - colname = _lib.sqlite3_column_name(self._statement, i) - if colname is not None: - colname = colname.decode('utf-8') - type_start = -1 - key = None - for pos in range(len(colname)): - if colname[pos] == '[': - type_start = pos + 1 - elif colname[pos] == ']' and type_start != -1: - key = colname[type_start:pos] - converter = converters[key.upper()] - - if converter is None and self.__con._detect_types & PARSE_DECLTYPES: - decltype = _lib.sqlite3_column_decltype(self._statement, i) - if decltype is not None: - decltype = decltype.decode('utf-8') - decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" - if '(' in decltype: - decltype = decltype[:decltype.index('(')] - converter = converters.get(decltype.upper(), None) - - self.__row_cast_map.append(converter) - if sys.version_info[0] < 3: def __check_decodable(self, param): if self.__con.text_factory in (unicode, OptimizedUnicode, @@ -1137,13 +1086,16 @@ rc = _lib.sqlite3_bind_double(self._statement, idx, param) elif isinstance(param, unicode): param = param.encode("utf-8") - rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, + len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, str): self.__check_decodable(param) - rc = _lib.sqlite3_bind_text(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_text(self._statement, idx, param, + len(param), _lib.SQLITE_TRANSIENT) elif isinstance(param, (buffer, bytes)): param = bytes(param) - rc = _lib.sqlite3_bind_blob(self._statement, idx, param, len(param), _lib.SQLITE_TRANSIENT) + rc = _lib.sqlite3_bind_blob(self._statement, idx, param, + len(param), _lib.SQLITE_TRANSIENT) else: rc = -1 return rc @@ -1190,6 +1142,81 @@ else: raise ValueError("parameters are of unsupported type") + def _build_row_cast_map(self): + if not self.__con._detect_types: + return + self.__row_cast_map = [] + for i in xrange(_lib.sqlite3_column_count(self._statement)): + converter = None + + if self.__con._detect_types & PARSE_COLNAMES: + colname = _lib.sqlite3_column_name(self._statement, i) + if colname is not None: + colname = colname.decode('utf-8') + type_start = -1 + key = None + for pos in range(len(colname)): + if colname[pos] == '[': + type_start = pos + 1 + elif colname[pos] == ']' and type_start != -1: + key = colname[type_start:pos] + converter = converters[key.upper()] + + if converter is None and self.__con._detect_types & PARSE_DECLTYPES: + decltype = _lib.sqlite3_column_decltype(self._statement, i) + if decltype is not None: + decltype = decltype.decode('utf-8') + # if multiple words, use first, eg. + # "INTEGER NOT NULL" => "INTEGER" + decltype = decltype.split()[0] + if '(' in decltype: + decltype = decltype[:decltype.index('(')] + converter = converters.get(decltype.upper(), None) + + self.__row_cast_map.append(converter) + + def _readahead(self, cursor): + row = [] + num_cols = _lib.sqlite3_column_count(self._statement) + for i in xrange(num_cols): + if self.__con._detect_types: + converter = self.__row_cast_map[i] + else: + converter = None + + if converter is not None: + blob = _lib.sqlite3_column_blob(self._statement, i) + if not blob: + val = None + else: + blob_len = _lib.sqlite3_column_bytes(self._statement, i) + val = bytes(string_at(blob, blob_len)) + val = converter(val) + else: + typ = _lib.sqlite3_column_type(self._statement, i) + if typ == _lib.SQLITE_NULL: + val = None + elif typ == _lib.SQLITE_INTEGER: + val = _lib.sqlite3_column_int64(self._statement, i) + val = int(val) + elif typ == _lib.SQLITE_FLOAT: + val = _lib.sqlite3_column_double(self._statement, i) + elif typ == _lib.SQLITE_TEXT: + text = _lib.sqlite3_column_text(self._statement, i) + text_len = _lib.sqlite3_column_bytes(self._statement, i) + val = string_at(text, text_len) + val = self.__con.text_factory(val) + elif typ == _lib.SQLITE_BLOB: + blob = _lib.sqlite3_column_blob(self._statement, i) + blob_len = _lib.sqlite3_column_bytes(self._statement, i) + val = _BLOB_TYPE(string_at(blob, blob_len)) + row.append(val) + + row = tuple(row) + if self._row_factory is not None: + row = self._row_factory(cursor, row) + self._item = row + def _next(self, cursor): if self._exhausted: raise StopIteration @@ -1207,45 +1234,6 @@ self._readahead(cursor) return item - def _readahead(self, cursor): - self.column_count = _lib.sqlite3_column_count(self._statement) - row = [] - for i in xrange(self.column_count): - typ = _lib.sqlite3_column_type(self._statement, i) - - converter = self.__row_cast_map[i] - if converter is None: - if typ == _lib.SQLITE_NULL: - val = None - elif typ == _lib.SQLITE_INTEGER: - val = _lib.sqlite3_column_int64(self._statement, i) - val = int(val) - elif typ == _lib.SQLITE_FLOAT: - val = _lib.sqlite3_column_double(self._statement, i) - elif typ == _lib.SQLITE_TEXT: - text = _lib.sqlite3_column_text(self._statement, i) - text_len = _lib.sqlite3_column_bytes(self._statement, i) - val = string_at(text, text_len) - val = self.__con.text_factory(val) - elif typ == _lib.SQLITE_BLOB: - blob = _lib.sqlite3_column_blob(self._statement, i) - blob_len = _lib.sqlite3_column_bytes(self._statement, i) - val = _BLOB_TYPE(string_at(blob, blob_len)) - else: - blob = _lib.sqlite3_column_blob(self._statement, i) - if not blob: - val = None - else: - blob_len = _lib.sqlite3_column_bytes(self._statement, i) - val = bytes(string_at(blob, blob_len)) - val = converter(val) - row.append(val) - - row = tuple(row) - if self._row_factory is not None: - row = self._row_factory(cursor, row) - self._item = row - def _get_description(self): if self._kind == Statement._DML: return None diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py --- a/pypy/interpreter/astcompiler/assemble.py +++ b/pypy/interpreter/astcompiler/assemble.py @@ -425,7 +425,8 @@ if instr.lineno: # compute deltas line = instr.lineno - current_line - assert line >= 0 + if line < 0: + continue addr = offset - current_off # Python assumes that lineno always increases with # increasing bytecode address (lnotab is unsigned char). diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py --- a/pypy/module/_ast/test/test_ast.py +++ b/pypy/module/_ast/test/test_ast.py @@ -306,3 +306,18 @@ ast.fix_missing_locations(m) exc = raises(TypeError, compile, m, "", "exec") + def test_hacked_lineno(self): + import _ast + stmt = '''if 1: + try: + foo + except Exception as error: + bar + except Baz as error: + bar + ''' + mod = compile(stmt, "", "exec", _ast.PyCF_ONLY_AST) + # These lineno are invalid, but should not crash the interpreter. + mod.body[0].body[0].handlers[0].lineno = 7 + mod.body[0].body[0].handlers[1].lineno = 6 + code = compile(mod, "", "exec") diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -85,6 +85,8 @@ """Base class for all cpyext tests.""" spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array', 'itertools', 'rctime', 'binascii']) + spaceconfig['std.withmethodcache'] = True + enable_leak_checking = True @staticmethod diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -285,7 +285,38 @@ class C(object): pass assert module.name_by_heaptype(C) == "C" - + + def test_type_dict(self): + foo = self.import_module("foo") + module = self.import_extension('test', [ + ("hack_tp_dict", "METH_O", + ''' + PyTypeObject *type = args->ob_type; + PyObject *a1 = PyLong_FromLong(1); + PyObject *a2 = PyLong_FromLong(2); + PyObject *value; + + if (PyDict_SetItemString(type->tp_dict, "a", + a1) < 0) + return NULL; + Py_DECREF(a1); + PyType_Modified(type); + value = PyObject_GetAttrString(type, "a"); + Py_DECREF(value); + + if (PyDict_SetItemString(type->tp_dict, "a", + a2) < 0) + return NULL; + Py_DECREF(a2); + PyType_Modified(type); + value = PyObject_GetAttrString(type, "a"); + return value; + ''' + ) + ]) + obj = foo.new() + assert module.hack_tp_dict(obj) == 2 + class TestTypes(BaseApiTest): def test_type_attributes(self, space, api): @@ -323,7 +354,7 @@ w_obj = api._PyType_Lookup(w_type, space.wrap("__invalid")) assert w_obj is None assert api.PyErr_Occurred() is None - + class AppTestSlots(AppTestCpythonExtensionBase): def test_some_slots(self): module = self.import_extension('foo', [ diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -674,6 +674,9 @@ subtypes. This function must be called after any manual modification of the attributes or base classes of the type. """ - # PyPy already takes care of direct modifications to type.__dict__ - # (which is a W_DictProxyObject). - pass + # Invalidate the type cache in case of a builtin type. + if not isinstance(w_obj, W_TypeObject): + return + if w_obj.is_cpytype(): + w_obj.mutated(None) + diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -9,7 +9,7 @@ from rpython.rlib.rfloat import ( formatd, DTSF_STR_PRECISION, isinf, isnan, copysign) from rpython.rlib import jit, rcomplex -from rpython.rlib.rarithmetic import intmask +from rpython.rlib.rarithmetic import intmask, r_ulonglong import math @@ -43,7 +43,7 @@ real = space.float_w(space.getattr(self, space.wrap("real"))) imag = space.float_w(space.getattr(self, space.wrap("imag"))) real_b = rbigint.fromrarith_int(float2longlong(real)) - imag_b = rbigint.fromrarith_int(float2longlong(imag)) + imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag))) val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag)) return space.newlong_from_rbigint(val) diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py --- a/pypy/objspace/std/dictproxyobject.py +++ b/pypy/objspace/std/dictproxyobject.py @@ -44,10 +44,11 @@ raise if not w_type.is_cpytype(): raise - # xxx obscure workaround: allow cpyext to write to type->tp_dict - # xxx even in the case of a builtin type. - # xxx like CPython, we assume that this is only done early after - # xxx the type is created, and we don't invalidate any cache. + # Allow cpyext to write to type->tp_dict even in the case + # of a builtin type. + # Like CPython, we assume that this is only done early + # after the type is created, and we don't invalidate any + # cache. User code shoud call PyType_Modified(). w_type.dict_w[key] = w_value def setdefault(self, w_dict, w_key, w_default): @@ -71,7 +72,7 @@ def length(self, w_dict): return len(self.unerase(w_dict.dstorage).dict_w) - def keys(self, w_dict): + def w_keys(self, w_dict): space = self.space return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys()) diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py --- a/pypy/objspace/std/test/test_obj.py +++ b/pypy/objspace/std/test/test_obj.py @@ -192,7 +192,9 @@ l.append(i + sys.maxsize) l.append(i - sys.maxsize) l.append(i + 1j) + l.append(i - 1j) l.append(1 + i * 1j) + l.append(1 - i * 1j) s = str(i) l.append(s) u = bytes(s, 'ascii') diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -161,7 +161,7 @@ generic mutation. """ space = w_self.space - assert w_self.is_heaptype() + assert w_self.is_heaptype() or w_self.is_cpytype() if (not space.config.objspace.std.withtypeversion and not space.config.objspace.std.getattributeshortcut and not space.config.objspace.std.withidentitydict and diff --git a/rpython/translator/sandbox/_marshal.py b/rpython/translator/sandbox/_marshal.py --- a/rpython/translator/sandbox/_marshal.py +++ b/rpython/translator/sandbox/_marshal.py @@ -4,9 +4,17 @@ This module contains functions that can read and write Python values in a binary format. The format is specific to Python, but independent of machine architecture issues (e.g., you can write a Python value to a file on a PC, transport the file to a Sun, and read it back there). Details of the format may change between Python versions. """ +# NOTE: This module is used in the Python3 interpreter, but also by +# the "sandboxed" process. It must work for Python2 as well. + import types from _codecs import utf_8_decode, utf_8_encode +try: + intern +except NameError: + from sys import intern + try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -50,7 +58,7 @@ if func: break else: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") func(self, x) def w_long64(self, x): @@ -73,7 +81,7 @@ def dump_none(self, x): self._write(TYPE_NONE) - dispatch[types.NoneType] = dump_none + dispatch[type(None)] = dump_none def dump_bool(self, x): if x: @@ -84,7 +92,7 @@ def dump_stopiter(self, x): if x is not StopIteration: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") self._write(TYPE_STOPITER) dispatch[type(StopIteration)] = dump_stopiter @@ -92,10 +100,11 @@ self._write(TYPE_ELLIPSIS) try: - dispatch[types.EllipsisType] = dump_ellipsis + dispatch[type(Ellipsis)] = dump_ellipsis except NameError: pass + # In Python3, this function is not used; see dump_long() below. def dump_int(self, x): y = x>>31 if y and y != -1: @@ -104,7 +113,7 @@ else: self._write(TYPE_INT) self.w_long(x) - dispatch[types.IntType] = dump_int + dispatch[int] = dump_int def dump_long(self, x): self._write(TYPE_LONG) @@ -119,27 +128,32 @@ self.w_long(len(digits) * sign) for d in digits: self.w_short(d) - dispatch[types.LongType] = dump_long + try: + long + except NameError: + dispatch[int] = dump_long + else: + dispatch[long] = dump_long def dump_float(self, x): write = self._write write(TYPE_FLOAT) - s = `x` + s = repr(x) write(chr(len(s))) write(s) - dispatch[types.FloatType] = dump_float + dispatch[float] = dump_float def dump_complex(self, x): write = self._write write(TYPE_COMPLEX) - s = `x.real` + s = repr(x.real) write(chr(len(s))) write(s) - s = `x.imag` + s = repr(x.imag) write(chr(len(s))) write(s) try: - dispatch[types.ComplexType] = dump_complex + dispatch[complex] = dump_complex except NameError: pass @@ -149,7 +163,7 @@ self._write(TYPE_STRING) self.w_long(len(x)) self._write(x) - dispatch[types.StringType] = dump_string + dispatch[bytes] = dump_string def dump_unicode(self, x): self._write(TYPE_UNICODE) @@ -157,21 +171,26 @@ s, len_s = utf_8_encode(x) self.w_long(len_s) self._write(s) - dispatch[types.UnicodeType] = dump_unicode + try: + unicode + except NameError: + dispatch[str] = dump_unicode + else: + dispatch[unicode] = dump_unicode def dump_tuple(self, x): self._write(TYPE_TUPLE) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.TupleType] = dump_tuple + dispatch[tuple] = dump_tuple def dump_list(self, x): self._write(TYPE_LIST) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.ListType] = dump_list + dispatch[list] = dump_list def dump_dict(self, x): self._write(TYPE_DICT) @@ -179,7 +198,7 @@ self.dump(key) self.dump(value) self._write(TYPE_NULL) - dispatch[types.DictionaryType] = dump_dict + dispatch[dict] = dump_dict def dump_code(self, x): self._write(TYPE_CODE) @@ -253,7 +272,7 @@ try: return self.dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) def r_short(self): lo = ord(self._read(1)) @@ -271,7 +290,7 @@ d = ord(s[3]) x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -281,14 +300,14 @@ b = ord(self._read(1)) c = ord(self._read(1)) d = ord(self._read(1)) - e = long(ord(self._read(1))) - f = long(ord(self._read(1))) - g = long(ord(self._read(1))) - h = long(ord(self._read(1))) + e = ord(self._read(1)) + f = ord(self._read(1)) + g = ord(self._read(1)) + h = ord(self._read(1)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x def load_null(self): @@ -325,10 +344,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = self.r_short() - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long @@ -460,7 +479,7 @@ self.bufpos += 4 x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -470,14 +489,14 @@ b = ord(_read1(self)) c = ord(_read1(self)) d = ord(_read1(self)) - e = long(ord(_read1(self))) - f = long(ord(_read1(self))) - g = long(ord(_read1(self))) - h = long(ord(_read1(self))) + e = ord(_read1(self)) + f = ord(_read1(self)) + g = ord(_read1(self)) + h = ord(_read1(self)) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x _load_dispatch = {} @@ -499,7 +518,7 @@ self.bufpos += 1 return _load_dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) except IndexError: raise EOFError @@ -541,10 +560,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = _r_short(self) - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long From noreply at buildbot.pypy.org Tue Mar 12 02:14:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Mar 2013 02:14:18 +0100 (CET) Subject: [pypy-commit] pypy default: this workaround no longer necessary Message-ID: <20130312011418.986E71C3A1B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62301:e8af23629e1f Date: 2013-03-11 21:09 -0400 http://bitbucket.org/pypy/pypy/changeset/e8af23629e1f/ Log: this workaround no longer necessary diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,15 +106,13 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def view_as_kwargs(self): - return self.strategy.view_as_kwargs(self) - def _add_indirections(): dict_methods = "setitem setitem_str getitem \ getitem_str delitem length \ clear w_keys values \ items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int".split() + popitem listview_str listview_unicode listview_int \ + view_as_kwargs".split() def make_method(method): def f(self, *args): @@ -122,9 +120,6 @@ f.func_name = method return f - def view_as_kwargs(self): - return self.strategy.view_as_kwargs(self) - for method in dict_methods: setattr(W_DictMultiObject, method, make_method(method)) From noreply at buildbot.pypy.org Tue Mar 12 02:14:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Mar 2013 02:14:19 +0100 (CET) Subject: [pypy-commit] pypy default: sqlite: only call readahead if there is another row Message-ID: <20130312011419.E47121C3A1B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62302:de53c17f0572 Date: 2013-03-11 21:13 -0400 http://bitbucket.org/pypy/pypy/changeset/de53c17f0572/ Log: sqlite: only call readahead if there is another row diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1227,11 +1227,11 @@ self._exhausted = True self._item = None elif ret != _lib.SQLITE_ROW: - exc = self.__con._get_exception(ret) _lib.sqlite3_reset(self._statement) - raise exc + raise self.__con._get_exception(ret) + else: + self._readahead(cursor) - self._readahead(cursor) return item def _get_description(self): From noreply at buildbot.pypy.org Tue Mar 12 02:43:11 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Mar 2013 02:43:11 +0100 (CET) Subject: [pypy-commit] pypy py3k: pep3131: support non-ascii identifiers. thanks amaury for most of the tokenizer Message-ID: <20130312014311.A0C0E1C3A12@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62303:78c50cd0ed82 Date: 2013-03-11 18:37 -0700 http://bitbucket.org/pypy/pypy/changeset/78c50cd0ed82/ Log: pep3131: support non-ascii identifiers. thanks amaury for most of the tokenizer work diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -6190,7 +6190,8 @@ if not w_self.initialization_state & 4: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'id') - return space.wrap(w_self.id) + id_ = w_self.id.decode('utf-8') + return space.wrap(id_) def Name_set_id(space, w_self, w_new_value): try: diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1135,6 +1135,11 @@ assert isinstance(s, ast.Str) assert space.eq_w(s.s, space.wrap(japan)) + def test_pep3131(self): + assign = self.get_first_stmt("日本 = 32").targets[0] + assert isinstance(assign, ast.Name) + assert assign.id == u"日本".encode('utf-8') + def test_issue3574(self): space = self.space source = u'# coding: Latin-1\nu = "Ç"\n' diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -90,7 +90,9 @@ self.co_flags = flags self.co_code = code self.co_consts_w = consts - self.co_names_w = [space.new_interned_str(aname) for aname in names] + self.co_names_w = [ + space.new_interned_w_str(space.wrap(aname.decode('utf-8'))) + for aname in names] self.co_varnames = varnames self.co_freevars = freevars self.co_cellvars = cellvars diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -575,9 +575,9 @@ self.pushvalue(w_build_class) def STORE_NAME(self, varindex, next_instr): - varname = self.getname_u(varindex) + w_varname = self.getname_w(varindex) w_newvalue = self.popvalue() - self.space.setitem_str(self.w_locals, varname, w_newvalue) + self.space.setitem(self.w_locals, w_varname, w_newvalue) def DELETE_NAME(self, varindex, next_instr): w_varname = self.getname_w(varindex) @@ -656,31 +656,33 @@ self.pushvalue(w_value) return # fall-back - varname = self.space.str_w(w_varname) - w_value = self._load_global(varname) + w_value = self._load_global(w_varname) if w_value is None: - message = "name '%s' is not defined" - raise operationerrfmt(self.space.w_NameError, message, varname) + message = "name '%8' is not defined" + raise operationerrfmt(self.space.w_NameError, message, + self.space.identifier_w(w_varname)) self.pushvalue(w_value) - def _load_global(self, varname): - w_value = self.space.finditem_str(self.w_globals, varname) + def _load_global(self, w_varname): + w_value = self.space.finditem(self.w_globals, w_varname) if w_value is None: # not in the globals, now look in the built-ins - w_value = self.get_builtin().getdictvalue(self.space, varname) + w_value = self.get_builtin().getdictvalue( + self.space, self.space.identifier_w(w_varname)) return w_value _load_global._always_inline_ = True - def _load_global_failed(self, varname): - message = "global name '%s' is not defined" - raise operationerrfmt(self.space.w_NameError, message, varname) + def _load_global_failed(self, w_varname): + message = "global name '%8' is not defined" + raise operationerrfmt(self.space.w_NameError, message, + self.space.identifier_w(w_varname)) _load_global_failed._dont_inline_ = True def LOAD_GLOBAL(self, nameindex, next_instr): - varname = self.getname_u(nameindex) - w_value = self._load_global(varname) + w_varname = self.getname_w(nameindex) + w_value = self._load_global(w_varname) if w_value is None: - self._load_global_failed(varname) + self._load_global_failed(w_varname) self.pushvalue(w_value) LOAD_GLOBAL._always_inline_ = True diff --git a/pypy/interpreter/pyparser/automata.py b/pypy/interpreter/pyparser/automata.py --- a/pypy/interpreter/pyparser/automata.py +++ b/pypy/interpreter/pyparser/automata.py @@ -36,6 +36,8 @@ i = pos for i in range(pos, len(inVec)): item = inVec[i] + if ord(item) > 0x80: + item = "\x80" # NON_ASCII # arcMap, accept = self.states[crntState] arcMap = self.states[crntState] accept = self.accepts[crntState] diff --git a/pypy/interpreter/pyparser/dfa_generated.py b/pypy/interpreter/pyparser/dfa_generated.py --- a/pypy/interpreter/pyparser/dfa_generated.py +++ b/pypy/interpreter/pyparser/dfa_generated.py @@ -37,7 +37,7 @@ 'q': 1, 'r': 3, 's': 1, 't': 1, 'u': 1, 'v': 1, 'w': 1, 'x': 1, 'y': 1, 'z': 1, '{': 14, '|': 13, - '}': 14, '~': 14}, + '}': 14, '~': 14, '\x80': 1}, # 1 {'0': 1, '1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, @@ -54,7 +54,7 @@ 'l': 1, 'm': 1, 'n': 1, 'o': 1, 'p': 1, 'q': 1, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 1, 'w': 1, - 'x': 1, 'y': 1, 'z': 1}, + 'x': 1, 'y': 1, 'z': 1, '\x80': 1}, # 2 {'"': 17, "'": 16, '0': 1, '1': 1, '2': 1, '3': 1, '4': 1, '5': 1, @@ -72,7 +72,7 @@ 'n': 1, 'o': 1, 'p': 1, 'q': 1, 'r': 3, 's': 1, 't': 1, 'u': 1, 'v': 1, 'w': 1, 'x': 1, 'y': 1, - 'z': 1}, + 'z': 1, '\x80': 1}, # 3 {'"': 17, "'": 16, '0': 1, '1': 1, '2': 1, '3': 1, '4': 1, '5': 1, @@ -90,7 +90,7 @@ 'n': 1, 'o': 1, 'p': 1, 'q': 1, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 1, 'w': 1, 'x': 1, 'y': 1, - 'z': 1}, + 'z': 1, '\x80': 1}, # 4 {'.': 25, '0': 23, '1': 24, '2': 24, '3': 24, '4': 24, '5': 24, '6': 24, diff --git a/pypy/interpreter/pyparser/gendfa.py b/pypy/interpreter/pyparser/gendfa.py --- a/pypy/interpreter/pyparser/gendfa.py +++ b/pypy/interpreter/pyparser/gendfa.py @@ -17,6 +17,8 @@ from pypy.interpreter.pyparser.pylexer import * from pypy.interpreter.pyparser.automata import NonGreedyDFA, DFA, DEFAULT +NON_ASCII = "\x80" + def makePyPseudoDFA (): import string states = [] @@ -50,9 +52,10 @@ # ____________________________________________________________ # Names name = chain(states, - groupStr(states, string.letters + "_"), + groupStr(states, string.letters + "_" + NON_ASCII), any(states, groupStr(states, - string.letters + string.digits + "_"))) + string.letters + string.digits + "_" + + NON_ASCII))) # ____________________________________________________________ # Digits def makeDigits (): diff --git a/pypy/interpreter/pyparser/pytokenizer.py b/pypy/interpreter/pyparser/pytokenizer.py --- a/pypy/interpreter/pyparser/pytokenizer.py +++ b/pypy/interpreter/pyparser/pytokenizer.py @@ -44,6 +44,20 @@ return None +def verify_identifier(token): + for c in token: + if ord(c) > 0x80: + break + else: + return True + try: + u = token.decode('utf-8') + except UnicodeDecodeError: + return False + from pypy.objspace.std.unicodeobject import _isidentifier + return _isidentifier(u) + + def generate_tokens(lines, flags): """ This is a rewrite of pypy.module.parser.pytokenize.generate_tokens since @@ -231,7 +245,11 @@ tok = (tokens.STRING, token, lnum, start, line) token_list.append(tok) last_comment = '' - elif initial in namechars: # ordinary name + elif (initial in namechars or # ordinary name + ord(initial) >= 0x80): # unicode identifier + if not verify_identifier(token): + raise TokenError("invalid character in identifier", + line, lnum, start + 1, token_list) token_list.append((tokens.NAME, token, lnum, start, line)) last_comment = '' elif initial == '\\': # continued stmt diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py b/pypy/interpreter/pyparser/test/test_pyparse.py --- a/pypy/interpreter/pyparser/test/test_pyparse.py +++ b/pypy/interpreter/pyparser/test/test_pyparse.py @@ -36,6 +36,10 @@ tree = self.parse("""foo = '日本'""", info=info) assert info.encoding == 'utf-8' + def test_unicode_identifier(self): + tree = self.parse("a日本 = 32") + tree = self.parse("日本 = 32") + def test_syntax_error(self): parse = self.parse exc = py.test.raises(SyntaxError, parse, "name another for").value diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py --- a/pypy/interpreter/test/test_compiler.py +++ b/pypy/interpreter/test/test_compiler.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import __future__ import py, sys from pypy.interpreter.pycompiler import PythonAstCompiler @@ -798,6 +799,29 @@ s = '\udcff' raises(UnicodeEncodeError, compile, s, 'foo', 'exec') + def test_unicode_identifier(self): + c = compile("# coding=latin-1\n\u00c6 = '\u00c6'", "dummy", "exec") + d = {} + exec(c, d) + assert d['\xc6'] == '\xc6' + c = compile("日本 = 8; 日本2 = 日本 + 1; del 日本;", "dummy", "exec") + exec(c, d) + assert '日本2' in d + assert d['日本2'] == 9 + assert '日本' not in d + + raises(SyntaxError, eval, b'\xff\x20') + raises(SyntaxError, eval, b'\xef\xbb\x20') + + def test_cpython_issue2301(self): + skip('XXX') + try: + compile(b"# coding: utf7\nprint '+XnQ-'", "dummy", "exec") + except SyntaxError as v: + assert v.text == "print '\u5e74'\n" + else: + assert False, "Expected SyntaxError" + def test_ast_equality(self): import _ast sample_code = [ diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py --- a/pypy/module/_ast/test/test_ast.py +++ b/pypy/module/_ast/test/test_ast.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import py @@ -85,6 +86,10 @@ name.id = "hi" assert name.id == "hi" + def test_unicode_identifier(self): + name = self.get_ast("日本", "eval").body + assert name.id == "日本" + @py.test.mark.skipif("py.test.config.option.runappdirect") def test_object(self): ast = self.ast diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -302,9 +302,11 @@ return space.newbool(cased) def unicode_isidentifier__Unicode(space, w_unicode): - v = w_unicode._value - if len(v) == 0: - return space.w_False + return space.newbool(_isidentifier(w_unicode._value)) + +def _isidentifier(u): + if not u: + return False # PEP 3131 says that the first character must be in XID_Start and # subsequent characters in XID_Continue, and for the ASCII range, @@ -313,14 +315,14 @@ # current definition of XID_Start and XID_Continue, it is # sufficient to check just for these, except that _ must be # allowed as starting an identifier. - first = v[0] + first = u[0] if not (unicodedb.isxidstart(ord(first)) or first == u'_'): - return space.w_False + return False - for i in range(1, len(v)): - if not unicodedb.isxidcontinue(ord(v[i])): - return space.w_False - return space.w_True + for i in range(1, len(u)): + if not unicodedb.isxidcontinue(ord(u[i])): + return False + return True def unicode_isprintable__Unicode(space, w_unicode): for uchar in w_unicode._value: From noreply at buildbot.pypy.org Tue Mar 12 02:43:12 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Mar 2013 02:43:12 +0100 (CET) Subject: [pypy-commit] pypy py3k: dictproxy works against utf-8 encoded identifiers from type's dict_w Message-ID: <20130312014312.EA55E1C3A12@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62304:c03956a6dd22 Date: 2013-03-11 18:39 -0700 http://bitbucket.org/pypy/pypy/changeset/c03956a6dd22/ Log: dictproxy works against utf-8 encoded identifiers from type's dict_w diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py --- a/pypy/objspace/std/dictproxyobject.py +++ b/pypy/objspace/std/dictproxyobject.py @@ -74,15 +74,19 @@ def w_keys(self, w_dict): space = self.space - return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys()) + w_type = self.unerase(w_dict.dstorage) + return space.newlist([_wrapkey(space, key) + for key in w_type.dict_w.iterkeys()]) def values(self, w_dict): return [unwrap_cell(self.space, w_value) for w_value in self.unerase(w_dict.dstorage).dict_w.itervalues()] def items(self, w_dict): space = self.space - return [space.newtuple([space.wrap(key), unwrap_cell(self.space, w_value)]) - for (key, w_value) in self.unerase(w_dict.dstorage).dict_w.iteritems()] + w_type = self.unerase(w_dict.dstorage) + return [space.newtuple([_wrapkey(space, key), + unwrap_cell(space, w_value)]) + for (key, w_value) in w_type.dict_w.iteritems()] def clear(self, w_dict): space = self.space @@ -100,8 +104,12 @@ def getiteritems(self, w_dict): return self.unerase(w_dict.dstorage).dict_w.iteritems() def wrapkey(space, key): - return space.wrap(key) + return _wrapkey(space, key) def wrapvalue(space, value): return unwrap_cell(space, value) +def _wrapkey(space, key): + # keys are utf-8 encoded identifiers from type's dict_w + return space.wrap(key.decode('utf-8')) + create_iterator_classes(DictProxyStrategy) From noreply at buildbot.pypy.org Tue Mar 12 02:43:14 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Mar 2013 02:43:14 +0100 (CET) Subject: [pypy-commit] pypy py3k: normalize all AST identifiers to NFKC Message-ID: <20130312014314.2E3A61C3A12@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62305:c05bd31e3342 Date: 2013-03-11 18:39 -0700 http://bitbucket.org/pypy/pypy/changeset/c05bd31e3342/ Log: normalize all AST identifiers to NFKC diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -118,6 +118,9 @@ except misc.ForbiddenNameAssignment, e: self.error("cannot assign to %s" % (e.name,), node) + def new_identifier(self, name): + return misc.new_identifier(self.space, name) + def set_context(self, expr, ctx): """Set the context of an expression to Store or Del if possible.""" try: @@ -163,9 +166,10 @@ while True: import_name_type = import_name.type if import_name_type == syms.import_as_name: - name = import_name.children[0].value + name = self.new_identifier(import_name.children[0].value) if len(import_name.children) == 3: - as_name = import_name.children[2].value + as_name = self.new_identifier( + import_name.children[2].value) self.check_forbidden_name(as_name, import_name.children[2]) else: as_name = None @@ -178,12 +182,12 @@ alias = self.alias_for_import_name(import_name.children[0], store=False) asname_node = import_name.children[2] - alias.asname = asname_node.value + alias.asname = self.new_identifier(asname_node.value) self.check_forbidden_name(alias.asname, asname_node) return alias elif import_name_type == syms.dotted_name: if len(import_name.children) == 1: - name = import_name.children[0].value + name = self.new_identifier(import_name.children[0].value) if store: self.check_forbidden_name(name, import_name.children[0]) return ast.alias(name, None) @@ -251,12 +255,12 @@ raise AssertionError("unknown import node") def handle_global_stmt(self, global_node): - names = [global_node.children[i].value + names = [self.new_identifier(global_node.children[i].value) for i in range(1, len(global_node.children), 2)] return ast.Global(names, global_node.lineno, global_node.column) def handle_nonlocal_stmt(self, nonlocal_node): - names = [nonlocal_node.children[i].value + names = [self.new_identifier(nonlocal_node.children[i].value) for i in range(1, len(nonlocal_node.children), 2)] return ast.Nonlocal(names, nonlocal_node.lineno, nonlocal_node.column) @@ -375,7 +379,7 @@ test = self.handle_expr(exc.children[1]) if child_count == 4: name_node = exc.children[3] - name = name_node.value + name = self.new_identifier(name_node.value) self.check_forbidden_name(name, name_node) return ast.ExceptHandler(test, name, suite, exc.lineno, exc.column) @@ -433,7 +437,7 @@ def handle_classdef(self, classdef_node, decorators=None): name_node = classdef_node.children[1] - name = name_node.value + name = self.new_identifier(name_node.value) self.check_forbidden_name(name, name_node) if len(classdef_node.children) == 4: # class NAME ':' suite @@ -463,7 +467,7 @@ def handle_funcdef(self, funcdef_node, decorators=None): name_node = funcdef_node.children[1] - name = name_node.value + name = self.new_identifier(name_node.value) self.check_forbidden_name(name, name_node) args = self.handle_arguments(funcdef_node.children[2]) suite = 4 @@ -503,11 +507,12 @@ return dec def handle_dotted_name(self, dotted_name_node): - base_value = dotted_name_node.children[0].value + base_value = self.new_identifier(dotted_name_node.children[0].value) name = ast.Name(base_value, ast.Load, dotted_name_node.lineno, dotted_name_node.column) for i in range(2, len(dotted_name_node.children), 2): attr = dotted_name_node.children[i].value + attr = self.new_identifier(attr) name = ast.Attribute(name, attr, ast.Load, dotted_name_node.lineno, dotted_name_node.column) return name @@ -590,6 +595,7 @@ kwdefaults) else: vararg = name_node.children[0].value + vararg = self.new_identifier(vararg) self.check_forbidden_name(vararg, name_node) if len(name_node.children) > 1: varargann = self.handle_expr(name_node.children[2]) @@ -603,6 +609,7 @@ elif arg_type == tokens.DOUBLESTAR: name_node = arguments_node.children[i + 1] kwarg = name_node.children[0].value + kwarg = self.new_identifier(kwarg) self.check_forbidden_name(kwarg, name_node) if len(name_node.children) > 1: kwargann = self.handle_expr(name_node.children[2]) @@ -633,6 +640,7 @@ ann = self.handle_expr(arg.children[2]) name_node = arg.children[0] argname = name_node.value + argname = self.new_identifier(argname) self.check_forbidden_name(argname, name_node) kwonly.append(ast.arg(argname, ann)) i += 2 @@ -642,11 +650,12 @@ def handle_arg(self, arg_node): name_node = arg_node.children[0] - self.check_forbidden_name(name_node.value, arg_node) + name = self.new_identifier(name_node.value) + self.check_forbidden_name(name, arg_node) ann = None if len(arg_node.children) == 3: ann = self.handle_expr(arg_node.children[2]) - return ast.arg(name_node.value, ann) + return ast.arg(name, ann) def handle_stmt(self, stmt): stmt_type = stmt.type @@ -972,7 +981,7 @@ else: return self.handle_call(trailer_node.children[1], left_expr) elif first_child.type == tokens.DOT: - attr = trailer_node.children[1].value + attr = self.new_identifier(trailer_node.children[1].value) return ast.Attribute(left_expr, attr, ast.Load, trailer_node.lineno, trailer_node.column) else: @@ -1119,8 +1128,9 @@ first_child = atom_node.children[0] first_child_type = first_child.type if first_child_type == tokens.NAME: - return ast.Name(first_child.value, ast.Load, - first_child.lineno, first_child.column) + name = self.new_identifier(first_child.value) + return ast.Name(name, ast.Load, first_child.lineno, + first_child.column) elif first_child_type == tokens.STRING: space = self.space encoding = self.compile_info.encoding diff --git a/pypy/interpreter/astcompiler/misc.py b/pypy/interpreter/astcompiler/misc.py --- a/pypy/interpreter/astcompiler/misc.py +++ b/pypy/interpreter/astcompiler/misc.py @@ -120,3 +120,18 @@ klass = klass[:end] return "_%s%s" % (klass, name) + + +def new_identifier(space, name): + # Check whether there are non-ASCII characters in the identifier; if + # so, normalize to NFKC + for c in name: + if ord(c) > 0x80: + break + else: + return name + + from pypy.module.unicodedata.interp_ucd import ucd + w_name = space.wrap(name.decode('utf-8')) + w_id = space.call_method(ucd, 'normalize', space.wrap('NFKC'), w_name) + return space.unicode_w(w_id).encode('utf-8') diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1135,10 +1135,29 @@ assert isinstance(s, ast.Str) assert space.eq_w(s.s, space.wrap(japan)) - def test_pep3131(self): - assign = self.get_first_stmt("日本 = 32").targets[0] - assert isinstance(assign, ast.Name) - assert assign.id == u"日本".encode('utf-8') + def test_name_pep3131(self): + assign = self.get_first_stmt("日本 = 32") + assert isinstance(assign, ast.Assign) + name = assign.targets[0] + assert isinstance(name, ast.Name) + assert name.id == u"日本".encode('utf-8') + + def test_function_pep3131(self): + fn = self.get_first_stmt("def µ(µ='foo'): pass") + assert isinstance(fn, ast.FunctionDef) + # µ normalized to NFKC + expected = u'\u03bc'.encode('utf-8') + assert fn.name == expected + assert fn.args.args[0].arg == expected + + def test_import_pep3131(self): + im = self.get_first_stmt("from packageµ import modµ as µ") + assert isinstance(im, ast.ImportFrom) + expected = u'\u03bc'.encode('utf-8') + assert im.module == 'package' + expected + alias = im.names[0] + assert alias.name == 'mod' + expected + assert alias.asname == expected def test_issue3574(self): space = self.space diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py --- a/pypy/interpreter/test/test_compiler.py +++ b/pypy/interpreter/test/test_compiler.py @@ -799,6 +799,24 @@ s = '\udcff' raises(UnicodeEncodeError, compile, s, 'foo', 'exec') + def test_pep3131(self): + r""" + # XXX: the 4th name is currently mishandled by narrow builds + class T: + ä = 1 + µ = 2 # this is a compatibility character + 蟒 = 3 + #x󠄀 = 4 + assert getattr(T, '\xe4') == 1 + assert getattr(T, '\u03bc') == 2 + assert getattr(T, '\u87d2') == 3 + #assert getattr(T, 'x\U000E0100') == 4 + expected = ("['__dict__', '__doc__', '__module__', '__weakref__', " + # "x󠄀", "'ä', 'μ', '蟒']") + "'ä', 'μ', '蟒']") + assert expected in str(sorted(T.__dict__.keys())) + """ + def test_unicode_identifier(self): c = compile("# coding=latin-1\n\u00c6 = '\u00c6'", "dummy", "exec") d = {} From noreply at buildbot.pypy.org Tue Mar 12 05:06:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Mar 2013 05:06:14 +0100 (CET) Subject: [pypy-commit] pypy default: test/fix for sqlite cursor iteration in corner cases Message-ID: <20130312040614.4EF4A1C3A1A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62306:930d2954c777 Date: 2013-03-12 00:05 -0400 http://bitbucket.org/pypy/pypy/changeset/930d2954c777/ Log: test/fix for sqlite cursor iteration in corner cases diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -876,9 +876,6 @@ if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) - else: - self.__statement._item = None - self.__statement._exhausted = True if self.__statement._kind == Statement._DML: if self.__rowcount == -1: @@ -1015,7 +1012,6 @@ self._kind = Statement._DDL self._in_use = False - self._exhausted = False self._row_factory = None if isinstance(sql, unicode): @@ -1053,7 +1049,6 @@ if self._in_use and self._statement: _lib.sqlite3_reset(self._statement) self._in_use = False - self._exhausted = False if sys.version_info[0] < 3: def __check_decodable(self, param): @@ -1218,18 +1213,17 @@ self._item = row def _next(self, cursor): - if self._exhausted: + try: + item = self._item + except AttributeError: raise StopIteration - item = self._item + del self._item ret = _lib.sqlite3_step(self._statement) - if ret == _lib.SQLITE_DONE: - self._exhausted = True - self._item = None - elif ret != _lib.SQLITE_ROW: + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): _lib.sqlite3_reset(self._statement) raise self.__con._get_exception(ret) - else: + elif ret == _lib.SQLITE_ROW: self._readahead(cursor) return item 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 @@ -57,11 +57,34 @@ cur = con.cursor() with pytest.raises(StopIteration): next(cur) - cur = con.execute('select 1') + + cur.execute('select 1') next(cur) with pytest.raises(StopIteration): next(cur) + cur.execute('select 1') + con.commit() + next(cur) + with pytest.raises(StopIteration): + next(cur) + + with pytest.raises(_sqlite3.ProgrammingError): + cur.executemany('select 1', []) + with pytest.raises(StopIteration): + next(cur) + + cur.execute('select 1') + cur.execute('create table test(ing)') + with pytest.raises(StopIteration): + next(cur) + + cur.execute('select 1') + cur.execute('insert into test values(1)') + con.commit() + with pytest.raises(StopIteration): + next(cur) + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') From noreply at buildbot.pypy.org Tue Mar 12 08:09:26 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Mar 2013 08:09:26 +0100 (CET) Subject: [pypy-commit] pypy py3k: partially revert 78c50cd0ed82: this belongs in asdl_py.py Message-ID: <20130312070926.AB6761C0EF9@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62307:96b51bbaa8eb Date: 2013-03-12 00:08 -0700 http://bitbucket.org/pypy/pypy/changeset/96b51bbaa8eb/ Log: partially revert 78c50cd0ed82: this belongs in asdl_py.py diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -6190,8 +6190,7 @@ if not w_self.initialization_state & 4: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'id') - id_ = w_self.id.decode('utf-8') - return space.wrap(id_) + return space.wrap(w_self.id) def Name_set_id(space, w_self, w_new_value): try: From noreply at buildbot.pypy.org Tue Mar 12 10:22:22 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 10:22:22 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: update details in test_gc_integration for ARM Message-ID: <20130312092222.B479B1C134E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62308:69ca2c717461 Date: 2013-03-12 10:14 +0100 http://bitbucket.org/pypy/pypy/changeset/69ca2c717461/ Log: update details in test_gc_integration for ARM 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 @@ -113,4 +113,5 @@ class CPU_ARMHF(AbstractARMCPU): """ARM v7 uses hardfp ABI, requires vfp""" use_hf_abi = True + backend_name = "armhf" supports_floats = False 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 @@ -241,16 +241,22 @@ gc_ll_descr.check_nothing_in_nursery() assert gc_ll_descr.addrs[0] == nurs_adr + 64 # slowpath never called - assert gc_ll_descr.calls == [] + assert gc_ll_descr.calls == [] def test_malloc_slowpath(self): def check(frame): - assert len(frame.jf_gcmap) == 1 + expected_size = 1 + idx = 0 + if self.cpu.backend_name.startswith('arm'): + # jitframe fixed part is larger here + expected_size = 2 + idx = 1 + assert len(frame.jf_gcmap) == expected_size if self.cpu.IS_64_BIT: - assert frame.jf_gcmap[0] == (1<<29) | (1 << 30) + assert frame.jf_gcmap[idx] == (1<<29) | (1 << 30) else: - assert frame.jf_gcmap[0] == (1<<24) | (1 << 23) - + assert frame.jf_gcmap[idx] == (1<<24) | (1 << 23) + self.cpu = self.getcpu(check) ops = ''' [i0] From noreply at buildbot.pypy.org Tue Mar 12 10:22:24 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 10:22:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move and remove some old code Message-ID: <20130312092224.392931C134E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62309:0dbd8dcb7335 Date: 2013-03-12 10:15 +0100 http://bitbucket.org/pypy/pypy/changeset/0dbd8dcb7335/ Log: move and remove some old code diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -609,7 +609,6 @@ 'e', looptoken.number) self._call_header_with_stack_check() - #sp_patch_location = self._prepare_sp_patch_position() regalloc = Regalloc(assembler=self) operations = regalloc.prepare_loop(inputargs, operations, looptoken, @@ -623,7 +622,6 @@ # size_excluding_failure_stuff = self.mc.get_relative_pos() - #self._patch_sp_offset(sp_patch_location, frame_depth) self.write_pending_failure_recoveries() rawstart = self.materialize_loop(looptoken) @@ -890,47 +888,6 @@ clt.asmmemmgr_blocks = [] return clt.asmmemmgr_blocks - def _prepare_sp_patch_position(self): - """Generate NOPs as placeholder to patch the instruction(s) to update - the sp according to the number of spilled variables""" - size = (self.mc.size_of_gen_load_int + WORD) - l = self.mc.currpos() - for _ in range(size // WORD): - self.mc.NOP() - return l - - def _patch_sp_offset(self, pos, frame_depth): - cb = OverwritingBuilder(self.mc, pos, - OverwritingBuilder.size_of_gen_load_int + WORD) - n = frame_depth * WORD - - # ensure the sp is 8 byte aligned when patching it - if n % 8 != 0: - n += WORD - assert n % 8 == 0 - - self._adjust_sp(n, cb, base_reg=r.fp) - - def _adjust_sp(self, n, cb=None, fcond=c.AL, base_reg=r.sp): - if cb is None: - cb = self.mc - if n < 0: - n = -n - rev = True - else: - rev = False - if n <= 0xFF and fcond == c.AL: - if rev: - cb.ADD_ri(r.sp.value, base_reg.value, n) - else: - cb.SUB_ri(r.sp.value, base_reg.value, n) - else: - cb.gen_load_int(r.ip.value, n, cond=fcond) - if rev: - cb.ADD_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond) - else: - cb.SUB_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond) - def _walk_operations(self, inputargs, operations, regalloc): fcond = c.AL self._regalloc = regalloc diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -392,6 +392,27 @@ self._adjust_sp(-n, fcond=fcond) assert n % 8 == 0 # sanity check + def _adjust_sp(self, n, cb=None, fcond=c.AL, base_reg=r.sp): + if cb is None: + cb = self.mc + if n < 0: + n = -n + rev = True + else: + rev = False + if n <= 0xFF and fcond == c.AL: + if rev: + cb.ADD_ri(r.sp.value, base_reg.value, n) + else: + cb.SUB_ri(r.sp.value, base_reg.value, n) + else: + cb.gen_load_int(r.ip.value, n, cond=fcond) + if rev: + cb.ADD_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond) + else: + cb.SUB_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond) + + def _collect_stack_args_sf(self, arglocs): n_args = len(arglocs) reg_args = count_reg_args(arglocs) From noreply at buildbot.pypy.org Tue Mar 12 10:22:25 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 10:22:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: partial support for malloc slow- and fast-path for ARM Message-ID: <20130312092225.B9F071C134E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62310:26cb6699b110 Date: 2013-03-12 10:18 +0100 http://bitbucket.org/pypy/pypy/changeset/26cb6699b110/ Log: partial support for malloc slow- and fast-path for ARM diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -180,7 +180,6 @@ if not self.cpu.propagate_exception_descr: return # not supported (for tests, or non-translated) # - # mc = ARMv7Builder() self._store_and_reset_exception(mc, r.r0) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') @@ -358,35 +357,60 @@ def _build_malloc_slowpath(self): mc = ARMv7Builder() - if self.cpu.supports_floats: - vfp_regs = r.all_vfp_regs - else: - vfp_regs = [] + self._push_all_regs_to_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + # store the gc pattern + mc.POP([r.r2.value]) + self.store_reg(mc, r.r2, r.fp, ofs) # We need to push two registers here because we are going to make a # call an therefore the stack needs to be 8-byte aligned mc.PUSH([r.ip.value, r.lr.value]) - with saved_registers(mc, [], vfp_regs): - # At this point we know that the values we need to compute the size - # are stored in r0 and r1. - mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value) - addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() - for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items(): - mc.STR_ri(reg.value, r.fp.value, imm=ofs) - mc.BL(addr) - for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items(): - mc.LDR_ri(reg.value, r.fp.value, imm=ofs) + # At this point we know that the values we need to compute the size + # are stored in r0 and r1. + mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value) # compute the size we want + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_rr(r.r1.value, r.fp.value) + + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() + mc.BL(addr) + + # + # If the slowpath malloc failed, we raise a MemoryError that + # always interrupts the current loop, as a "good enough" + # approximation. mc.CMP_ri(r.r0.value, 0) mc.B(self.propagate_exception_path, c=c.EQ) + # + self._reload_frame_if_necessary(mc, align_stack=True) + self._pop_all_regs_from_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) + # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() mc.gen_load_int(r.r1.value, nursery_free_adr) mc.LDR_ri(r.r1.value, r.r1.value) - # see above + # clear the gc pattern + mc.gen_load_int(r.ip.value, 0) + self.store_reg(mc, r.ip, r.fp, ofs) + # return mc.POP([r.ip.value, r.pc.value]) rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.malloc_slowpath = rawstart + def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + import pdb; pdb.set_trace() + rst = gcrootmap.get_root_stack_top_addr() + mc.MOV(ecx, heap(rst)) + mc.MOV(ebp, mem(ecx, -WORD)) + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + if gcrootmap and wbdescr: + # frame never uses card marking, so we enforce this is not + # an array + self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False, + is_frame=True)#, align_stack=align_stack) + def propagate_memoryerror_if_r0_is_null(self): # see ../x86/assembler.py:propagate_memoryerror_if_eax_is_null self.mc.CMP_ri(r.r0.value, 0) @@ -1223,7 +1247,7 @@ else: raise AssertionError('Trying to pop to an invalid location') - def malloc_cond(self, gcmap, nursery_free_adr, nursery_top_adr, size): + def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): assert size & (WORD-1) == 0 # must be correctly aligned self.mc.gen_load_int(r.r0.value, nursery_free_adr) @@ -1247,23 +1271,23 @@ # malloc_slowpath in case we called malloc_slowpath, which returns the # new value of nursery_free_adr in r1 and the adr of the new object in # r0. - XXX # push gcmap - + self.push_gcmap(self.mc, gcmap, push=True, cond=c.HI) + self.mc.BL(self.malloc_slowpath, c=c.HI) self.mc.gen_load_int(r.ip.value, nursery_free_adr) self.mc.STR_ri(r.r1.value, r.ip.value) - def push_gcmap(self, mc, gcmap, push=False, store=False): + def push_gcmap(self, mc, gcmap, push=False, store=False, cond=c.AL): ptr = rffi.cast(lltype.Signed, gcmap) if push: - mc.gen_load_int(r.ip.value, ptr) - mc.PUSH([r.ip.value]) + mc.gen_load_int(r.ip.value, ptr, cond=cond) + mc.PUSH([r.ip.value], cond=cond) else: assert store ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') - mc.gen_load_int(r.ip.value, ptr) - mc.STR_ri(r.ip.value, r.fp.value, imm=ofs) + mc.gen_load_int(r.ip.value, ptr, cond=cond) + mc.STR_ri(r.ip.value, r.fp.value, imm=ofs, cond=cond) def pop_gcmap(self, mc): ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1316,10 +1316,10 @@ gc_ll_descr = self.cpu.gc_ll_descr gcmap = regalloc.get_gcmap([r.r0, r.r1]) self.malloc_cond( - gcmap, gc_ll_descr.get_nursery_free_addr(), gc_ll_descr.get_nursery_top_addr(), - size + size, + gcmap ) self._alignment_check() return fcond From noreply at buildbot.pypy.org Tue Mar 12 10:22:27 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 10:22:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge upstream Message-ID: <20130312092227.20E961C134E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62311:6626fb24d017 Date: 2013-03-12 10:21 +0100 http://bitbucket.org/pypy/pypy/changeset/6626fb24d017/ Log: merge upstream 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 @@ -115,3 +115,4 @@ use_hf_abi = True backend_name = "armhf" supports_floats = False + supports_singlefloats = False From noreply at buildbot.pypy.org Tue Mar 12 11:13:34 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 11:13:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: call_malloc_nursery_varsize_small Message-ID: <20130312101334.584B61C1105@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62312:6ee2777242cd Date: 2013-03-12 11:09 +0100 http://bitbucket.org/pypy/pypy/changeset/6ee2777242cd/ Log: call_malloc_nursery_varsize_small diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1247,17 +1247,21 @@ else: raise AssertionError('Trying to pop to an invalid location') - def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): - assert size & (WORD-1) == 0 # must be correctly aligned + def malloc_cond(self, nursery_free_adr, nursery_top_adr, sizeloc, gcmap): + if sizeloc.is_imm(): # must be correctly aligned + assert sizeloc.value & (WORD-1) == 0 self.mc.gen_load_int(r.r0.value, nursery_free_adr) self.mc.LDR_ri(r.r0.value, r.r0.value) - if check_imm_arg(size): - self.mc.ADD_ri(r.r1.value, r.r0.value, size) + if sizeloc.is_imm(): + if check_imm_arg(sizeloc.value): + self.mc.ADD_ri(r.r1.value, r.r0.value, sizeloc.value) + else: + self.mc.gen_load_int(r.r1.value, sizeloc.value) + self.mc.ADD_rr(r.r1.value, r.r0.value, r.r1.value) else: - self.mc.gen_load_int(r.r1.value, size) - self.mc.ADD_rr(r.r1.value, r.r0.value, r.r1.value) + self.mc.ADD_rr(r.r1.value, r.r0.value, sizeloc.value) self.mc.gen_load_int(r.ip.value, nursery_top_adr) self.mc.LDR_ri(r.ip.value, r.ip.value) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1312,17 +1312,19 @@ def emit_op_call_malloc_nursery(self, op, arglocs, regalloc, fcond): # registers r0 and r1 are allocated for this call assert len(arglocs) == 1 - size = arglocs[0].value + sizeloc = arglocs[0] gc_ll_descr = self.cpu.gc_ll_descr gcmap = regalloc.get_gcmap([r.r0, r.r1]) self.malloc_cond( gc_ll_descr.get_nursery_free_addr(), gc_ll_descr.get_nursery_top_addr(), - size, + sizeloc, gcmap ) self._alignment_check() return fcond + emit_op_call_malloc_nursery_varsize_small = emit_op_call_malloc_nursery + def _alignment_check(self): if not self.debug: diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1004,7 +1004,6 @@ self.rm.force_allocate_reg(op.result, selected_reg=r.r0) t = TempInt() self.rm.force_allocate_reg(t, selected_reg=r.r1) - self.possibly_free_var(op.result) self.possibly_free_var(t) return [imm(size)] @@ -1016,9 +1015,10 @@ self.rm.force_allocate_reg(op.result, selected_reg=r.r0) t = TempInt() self.rm.force_allocate_reg(t, selected_reg=r.r1) - self.possibly_free_var(op.result) + argloc = self.make_sure_var_in_reg(size_box, + forbidden_vars=[op.result, t]) self.possibly_free_var(t) - return [imm(size)] + return [argloc] prepare_op_debug_merge_point = void prepare_op_jit_debug = void From noreply at buildbot.pypy.org Tue Mar 12 14:57:29 2013 From: noreply at buildbot.pypy.org (timfel) Date: Tue, 12 Mar 2013 14:57:29 +0100 (CET) Subject: [pypy-commit] pypy default: (cfbolz, timfel) refactor hack to find operation that is currently being annotated, into a semi-official method on bookkeeper Message-ID: <20130312135729.C77661C3A11@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r62313:6432b66e69bb Date: 2013-03-12 14:44 +0100 http://bitbucket.org/pypy/pypy/changeset/6432b66e69bb/ Log: (cfbolz, timfel) refactor hack to find operation that is currently being annotated, into a semi-official method on bookkeeper diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -143,13 +143,9 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing + op = bk._find_current_op("is_", 2) knowntypedata = {} - fn, block, i = bk.position_key - annotator = bk.annotator - op = block.operations[i] - assert op.opname == "is_" - assert len(op.args) == 2 def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): @@ -319,11 +315,7 @@ rarithmetic.signedtype(int2.knowntype)): return r knowntypedata = {} - # XXX HACK HACK HACK - fn, block, i = getbookkeeper().position_key - op = block.operations[i] - assert op.opname == opname - assert len(op.args) == 2 + op = getbookkeeper()._find_current_op(opname=opname, arity=2) def tointtype(int0): if int0.knowntype is bool: return int diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -693,6 +693,20 @@ if emulate_enter: self.leave() + def _find_current_op(self, opname=None, arity=None, pos=None, s_type=None): + """ Find operation that is currently being annotated. Do some + sanity checks to see whether the correct op was found.""" + # XXX XXX HACK HACK HACK + fn, block, i = self.position_key + op = block.operations[i] + if opname is not None: + assert op.opname == opname or op.opname in opname + if arity is not None: + assert len(op.args) == arity + if pos is not None: + assert self.annotator.binding(op.args[pos]) == s_type + return op + def build_args(self, op, args_s): space = RPythonCallsSpace() if op == "simple_call": diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -178,15 +178,9 @@ # from bool to int, notice that isinstance( , bool|int) # is quite border case for RPython r.const = False - # XXX HACK HACK HACK - # XXX HACK HACK HACK - # XXX HACK HACK HACK bk = getbookkeeper() if variables is None: - fn, block, i = bk.position_key - op = block.operations[i] - assert op.opname == "simple_call" - assert len(op.args) == 3 + op = bk._find_current_op("simple_call", 3) assert op.args[0] == Constant(isinstance) variables = [op.args[1]] for variable in variables: diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -43,12 +43,7 @@ raise Exception, 'type() called with more than one argument' r = SomeType() bk = getbookkeeper() - fn, block, i = bk.position_key - annotator = bk.annotator - op = block.operations[i] - assert op.opname == "type" - assert len(op.args) == 1 - assert annotator.binding(op.args[0]) == obj + op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=obj) r.is_type_of = [op.args[0]] return r @@ -79,10 +74,7 @@ bk = getbookkeeper() knowntypedata = {} - fn, block, i = bk.position_key - op = block.operations[i] - assert op.opname == "is_true" or op.opname == "nonzero" - assert len(op.args) == 1 + op = bk._find_current_op(opname=("is_true", "nonzero"), arity=1) arg = op.args[0] s_nonnone_obj = s_obj if s_obj.can_be_none(): From noreply at buildbot.pypy.org Tue Mar 12 14:57:31 2013 From: noreply at buildbot.pypy.org (timfel) Date: Tue, 12 Mar 2013 14:57:31 +0100 (CET) Subject: [pypy-commit] pypy default: (cfbolz, timfel) annotate strings with no_nul=True if '\0' in str is true Message-ID: <20130312135731.176F01C3A19@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r62314:391735663777 Date: 2013-03-12 14:45 +0100 http://bitbucket.org/pypy/pypy/changeset/391735663777/ Log: (cfbolz, timfel) annotate strings with no_nul=True if '\0' in str is true diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -233,6 +233,9 @@ def nonnoneify(self): return self.__class__(can_be_None=False, no_nul=self.no_nul) + def nonnulify(self): + return self.__class__(can_be_None=self.can_be_None, no_nul=True) + class SomeString(SomeStringOrUnicode): "Stands for an object which is known to be a string." knowntype = str 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 @@ -3762,6 +3762,19 @@ assert isinstance(s, annmodel.SomeString) assert not s.can_be_None + def test_contains_no_nul(self): + def f(i): + if "\0" in i: + return None + else: + return i + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeString(no_nul=False)]) + assert isinstance(s, annmodel.SomeString) + assert s.can_be_None + assert s.no_nul + def test_no___call__(self): class X(object): def __call__(self): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -512,6 +512,20 @@ result = str.basestringclass(no_nul=str.no_nul) return result + def op_contains(str, s_element): + if s_element.is_constant() and s_element.const == "\0": + r = SomeBool() + bk = getbookkeeper() + op = bk._find_current_op(opname="contains", arity=2, pos=0, s_type=str) + knowntypedata = {} + add_knowntypedata(knowntypedata, False, [op.args[0]], str.nonnulify()) + r.set_knowntypedata(knowntypedata) + return r + else: + return SomeObject.op_contains(str, s_element) + op_contains.can_only_throw = [] + + class __extend__(SomeUnicodeString): def method_encode(uni, s_enc): if not s_enc.is_constant(): From noreply at buildbot.pypy.org Tue Mar 12 15:19:44 2013 From: noreply at buildbot.pypy.org (timfel) Date: Tue, 12 Mar 2013 15:19:44 +0100 (CET) Subject: [pypy-commit] pypy default: (cfbolz, timfel) annotate no_nul on strings in result set if splitting at nul-byte Message-ID: <20130312141944.DC9121C11D1@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r62315:156750d24e38 Date: 2013-03-12 15:18 +0100 http://bitbucket.org/pypy/pypy/changeset/156750d24e38/ Log: (cfbolz, timfel) annotate no_nul on strings in result set if splitting at nul-byte 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 @@ -446,6 +446,17 @@ s_item = s.listdef.listitem.s_value assert s_item.no_nul + def test_str_split_nul(self): + def f(n): + return n.split('\0')[0] + + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeString(no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeString) + assert not s.can_be_None + assert s.no_nul + def test_str_splitlines(self): a = self.RPythonAnnotator() def f(a_str): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -496,7 +496,11 @@ def method_split(str, patt, max=-1): getbookkeeper().count("str_split", str, patt) - s_item = str.basestringclass(no_nul=str.no_nul) + if patt.is_constant() and patt.const == "\0": + no_nul = True + else: + no_nul = str.no_nul + s_item = str.basestringclass(no_nul=no_nul) return getbookkeeper().newlist(s_item) def method_rsplit(str, patt, max=-1): From alex.gaynor at gmail.com Tue Mar 12 15:35:26 2013 From: alex.gaynor at gmail.com (Alex Gaynor) Date: Tue, 12 Mar 2013 07:35:26 -0700 Subject: [pypy-commit] pypy default: (cfbolz, timfel) annotate no_nul on strings in result set if splitting at nul-byte In-Reply-To: <20130312141944.DC9121C11D1@cobra.cs.uni-duesseldorf.de> References: <20130312141944.DC9121C11D1@cobra.cs.uni-duesseldorf.de> Message-ID: I don't think this is totally correct, it's only true if `max == -1`. Otherwise you can have something like: >>> "abc\0def\0ghi\0".split("\0", 1) ['abc', 'def\x00ghi\x00'] Alex On Tue, Mar 12, 2013 at 7:19 AM, timfel wrote: > Author: Tim Felgentreff > Branch: > Changeset: r62315:156750d24e38 > Date: 2013-03-12 15:18 +0100 > http://bitbucket.org/pypy/pypy/changeset/156750d24e38/ > > Log: (cfbolz, timfel) annotate no_nul on strings in result set if > splitting at nul-byte > > 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 > @@ -446,6 +446,17 @@ > s_item = s.listdef.listitem.s_value > assert s_item.no_nul > > + def test_str_split_nul(self): > + def f(n): > + return n.split('\0')[0] > + > + a = self.RPythonAnnotator() > + a.translator.config.translation.check_str_without_nul = True > + s = a.build_types(f, [annmodel.SomeString(no_nul=False, > can_be_None=False)]) > + assert isinstance(s, annmodel.SomeString) > + assert not s.can_be_None > + assert s.no_nul > + > def test_str_splitlines(self): > a = self.RPythonAnnotator() > def f(a_str): > diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py > --- a/rpython/annotator/unaryop.py > +++ b/rpython/annotator/unaryop.py > @@ -496,7 +496,11 @@ > > def method_split(str, patt, max=-1): > getbookkeeper().count("str_split", str, patt) > - s_item = str.basestringclass(no_nul=str.no_nul) > + if patt.is_constant() and patt.const == "\0": > + no_nul = True > + else: > + no_nul = str.no_nul > + s_item = str.basestringclass(no_nul=no_nul) > return getbookkeeper().newlist(s_item) > > def method_rsplit(str, patt, max=-1): > _______________________________________________ > pypy-commit mailing list > pypy-commit at python.org > http://mail.python.org/mailman/listinfo/pypy-commit > -- "I disapprove of what you say, but I will defend to the death your right to say it." -- Evelyn Beatrice Hall (summarizing Voltaire) "The people's good is the highest law." -- Cicero -------------- next part -------------- An HTML attachment was scrubbed... URL: From noreply at buildbot.pypy.org Tue Mar 12 15:44:29 2013 From: noreply at buildbot.pypy.org (timfel) Date: Tue, 12 Mar 2013 15:44:29 +0100 (CET) Subject: [pypy-commit] pypy default: fix and test adding no_nul=True annotation to strings in result of splitting on null-byte if maxsplit argument is not -1 Message-ID: <20130312144429.E7E951C11D1@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r62316:5f5a391cfee4 Date: 2013-03-12 15:41 +0100 http://bitbucket.org/pypy/pypy/changeset/5f5a391cfee4/ Log: fix and test adding no_nul=True annotation to strings in result of splitting on null-byte if maxsplit argument is not -1 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 @@ -449,7 +449,6 @@ def test_str_split_nul(self): def f(n): return n.split('\0')[0] - a = self.RPythonAnnotator() a.translator.config.translation.check_str_without_nul = True s = a.build_types(f, [annmodel.SomeString(no_nul=False, can_be_None=False)]) @@ -457,6 +456,15 @@ assert not s.can_be_None assert s.no_nul + def g(n): + return n.split('\0', 1)[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(g, [annmodel.SomeString(no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeString) + assert not s.can_be_None + assert not s.no_nul + def test_str_splitlines(self): a = self.RPythonAnnotator() def f(a_str): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -496,7 +496,7 @@ def method_split(str, patt, max=-1): getbookkeeper().count("str_split", str, patt) - if patt.is_constant() and patt.const == "\0": + if max == -1 and patt.is_constant() and patt.const == "\0": no_nul = True else: no_nul = str.no_nul From noreply at buildbot.pypy.org Tue Mar 12 16:11:06 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 12 Mar 2013 16:11:06 +0100 (CET) Subject: [pypy-commit] pypy default: test, fix indexing with a list of slices Message-ID: <20130312151106.F00C81C0014@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r62317:6702e78d079d Date: 2013-03-11 17:37 -0500 http://bitbucket.org/pypy/pypy/changeset/6702e78d079d/ Log: test, fix indexing with a list of slices diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -136,6 +136,10 @@ def getitem_array_int(self, space, w_index): prefix, res_shape, iter_shape, indexes = \ self._prepare_array_index(space, w_index) + if iter_shape is None: + # w_index is a list of slices, return a view + chunks = self.implementation._prepare_slice_args(space, w_index) + return chunks.apply(self) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) if not res.get_size(): @@ -147,6 +151,13 @@ val_arr = convert_to_array(space, w_value) prefix, _, iter_shape, indexes = \ self._prepare_array_index(space, w_index) + if iter_shape is None: + # w_index is a list of slices + w_value = convert_to_array(space, w_value) + chunks = self.implementation._prepare_slice_args(space, w_index) + view = chunks.apply(self) + view.implementation.setslice(space, w_value) + return return loop.setitem_array_int(space, self, iter_shape, indexes, val_arr, prefix) 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 @@ -2204,6 +2204,20 @@ a[array([0, 2]), slice(0, 2)] = [[10, 11], [12, 13]] assert (a == [[10, 11], [3, 4], [12, 13]]).all() + def test_slice_vector_index(self): + from numpypy import arange + b = arange(145) + a = b[slice(25, 125, None)] + assert (a == range(25, 125)).all() + a = b[[slice(25, 125, None)]] + assert a.shape == (100,) + # a is a view into b + a[10] = 200 + assert b[35] == 200 + b[[slice(25, 30)]] = range(5) + assert all(a[:5] == range(5)) + raises(TypeError, 'b[[[slice(25, 125)]]]') + def test_cumsum(self): from numpypy import arange a = arange(6).reshape(3, 2) From noreply at buildbot.pypy.org Tue Mar 12 16:11:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 12 Mar 2013 16:11:08 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130312151108.926281C0014@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r62318:5929d5aa6cd8 Date: 2013-03-12 08:10 -0700 http://bitbucket.org/pypy/pypy/changeset/5929d5aa6cd8/ Log: merge heads diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -130,10 +130,10 @@ if hasattr(sys, 'pypy_objspaceclass'): # if 'python' is actually PyPy, e.g. in a virtualenv, then # try hard to find a real CPython - for python in ['/usr/local/bin/python', '/usr/bin/python']: - if os.path.exists(python): - break - else: + try: + python = subprocess.check_output( + 'env -i $SHELL -l -c "which python"', shell=True).strip() + except subprocess.CalledProcessError: # did not work, fall back to 'python' python = 'python' else: diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -480,8 +480,6 @@ @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): - if not isinstance(sql, basestring): - raise Warning("SQL is of wrong type. Must be string or unicode.") return self._statement_cache.get(sql, self.row_factory) def cursor(self, factory=None): @@ -878,9 +876,6 @@ if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) - else: - self.__statement._item = None - self.__statement._exhausted = True if self.__statement._kind == Statement._DML: if self.__rowcount == -1: @@ -1007,7 +1002,7 @@ self.__con = connection if not isinstance(sql, basestring): - raise ValueError("sql must be a string") + raise Warning("SQL is of wrong type. Must be string or unicode.") first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): self._kind = Statement._DML @@ -1017,7 +1012,6 @@ self._kind = Statement._DDL self._in_use = False - self._exhausted = False self._row_factory = None if isinstance(sql, unicode): @@ -1055,7 +1049,6 @@ if self._in_use and self._statement: _lib.sqlite3_reset(self._statement) self._in_use = False - self._exhausted = False if sys.version_info[0] < 3: def __check_decodable(self, param): @@ -1220,20 +1213,19 @@ self._item = row def _next(self, cursor): - if self._exhausted: + try: + item = self._item + except AttributeError: raise StopIteration - item = self._item + del self._item ret = _lib.sqlite3_step(self._statement) - if ret == _lib.SQLITE_DONE: - self._exhausted = True - self._item = None - elif ret != _lib.SQLITE_ROW: - exc = self.__con._get_exception(ret) + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): _lib.sqlite3_reset(self._statement) - raise exc + raise self.__con._get_exception(ret) + elif ret == _lib.SQLITE_ROW: + self._readahead(cursor) - self._readahead(cursor) return item def _get_description(self): diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -85,6 +85,8 @@ """Base class for all cpyext tests.""" spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array', 'itertools', 'rctime', 'binascii']) + spaceconfig['std.withmethodcache'] = True + enable_leak_checking = True @staticmethod diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -288,7 +288,38 @@ class C(object): pass assert module.name_by_heaptype(C) == "C" - + + def test_type_dict(self): + foo = self.import_module("foo") + module = self.import_extension('test', [ + ("hack_tp_dict", "METH_O", + ''' + PyTypeObject *type = args->ob_type; + PyObject *a1 = PyLong_FromLong(1); + PyObject *a2 = PyLong_FromLong(2); + PyObject *value; + + if (PyDict_SetItemString(type->tp_dict, "a", + a1) < 0) + return NULL; + Py_DECREF(a1); + PyType_Modified(type); + value = PyObject_GetAttrString(type, "a"); + Py_DECREF(value); + + if (PyDict_SetItemString(type->tp_dict, "a", + a2) < 0) + return NULL; + Py_DECREF(a2); + PyType_Modified(type); + value = PyObject_GetAttrString(type, "a"); + return value; + ''' + ) + ]) + obj = foo.new() + assert module.hack_tp_dict(obj) == 2 + class TestTypes(BaseApiTest): def test_type_attributes(self, space, api): @@ -326,7 +357,7 @@ w_obj = api._PyType_Lookup(w_type, space.wrap("__invalid")) assert w_obj is None assert api.PyErr_Occurred() is None - + class AppTestSlots(AppTestCpythonExtensionBase): def test_some_slots(self): module = self.import_extension('foo', [ diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -729,6 +729,9 @@ subtypes. This function must be called after any manual modification of the attributes or base classes of the type. """ - # PyPy already takes care of direct modifications to type.__dict__ - # (which is a W_DictProxyObject). - pass + # Invalidate the type cache in case of a builtin type. + if not isinstance(w_obj, W_TypeObject): + return + if w_obj.is_cpytype(): + w_obj.mutated(None) + 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 @@ -57,11 +57,34 @@ cur = con.cursor() with pytest.raises(StopIteration): next(cur) - cur = con.execute('select 1') + + cur.execute('select 1') next(cur) with pytest.raises(StopIteration): next(cur) + cur.execute('select 1') + con.commit() + next(cur) + with pytest.raises(StopIteration): + next(cur) + + with pytest.raises(_sqlite3.ProgrammingError): + cur.executemany('select 1', []) + with pytest.raises(StopIteration): + next(cur) + + cur.execute('select 1') + cur.execute('create table test(ing)') + with pytest.raises(StopIteration): + next(cur) + + cur.execute('select 1') + cur.execute('insert into test values(1)') + con.commit() + with pytest.raises(StopIteration): + next(cur) + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -9,7 +9,7 @@ from rpython.rlib.rfloat import ( formatd, DTSF_STR_PRECISION, isinf, isnan, copysign) from rpython.rlib import jit, rcomplex -from rpython.rlib.rarithmetic import intmask +from rpython.rlib.rarithmetic import intmask, r_ulonglong import math @@ -41,7 +41,7 @@ real = space.float_w(space.getattr(self, space.wrap("real"))) imag = space.float_w(space.getattr(self, space.wrap("imag"))) real_b = rbigint.fromrarith_int(float2longlong(real)) - imag_b = rbigint.fromrarith_int(float2longlong(imag)) + imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag))) val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag)) return space.newlong_from_rbigint(val) diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,15 +106,13 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def view_as_kwargs(self): - return self.strategy.view_as_kwargs(self) - def _add_indirections(): dict_methods = "setitem setitem_str getitem \ getitem_str delitem length \ clear w_keys values \ items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int".split() + popitem listview_str listview_unicode listview_int \ + view_as_kwargs".split() def make_method(method): def f(self, *args): @@ -122,9 +120,6 @@ f.func_name = method return f - def view_as_kwargs(self): - return self.strategy.view_as_kwargs(self) - for method in dict_methods: setattr(W_DictMultiObject, method, make_method(method)) diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py --- a/pypy/objspace/std/dictproxyobject.py +++ b/pypy/objspace/std/dictproxyobject.py @@ -54,10 +54,11 @@ raise if not w_type.is_cpytype(): raise - # xxx obscure workaround: allow cpyext to write to type->tp_dict - # xxx even in the case of a builtin type. - # xxx like CPython, we assume that this is only done early after - # xxx the type is created, and we don't invalidate any cache. + # Allow cpyext to write to type->tp_dict even in the case + # of a builtin type. + # Like CPython, we assume that this is only done early + # after the type is created, and we don't invalidate any + # cache. User code shoud call PyType_Modified(). w_type.dict_w[key] = w_value def setdefault(self, w_dict, w_key, w_default): @@ -81,7 +82,7 @@ def length(self, w_dict): return len(self.unerase(w_dict.dstorage).dict_w) - def keys(self, w_dict): + def w_keys(self, w_dict): space = self.space return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys()) diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py --- a/pypy/objspace/std/test/test_obj.py +++ b/pypy/objspace/std/test/test_obj.py @@ -203,7 +203,9 @@ l.append(i + sys.maxint) l.append(i - sys.maxint) l.append(i + 1j) + l.append(i - 1j) l.append(1 + i * 1j) + l.append(1 - i * 1j) s = str(i) l.append(s) u = unicode(s) diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -161,7 +161,7 @@ generic mutation. """ space = w_self.space - assert w_self.is_heaptype() + assert w_self.is_heaptype() or w_self.is_cpytype() if (not space.config.objspace.std.withtypeversion and not space.config.objspace.std.getattributeshortcut and not space.config.objspace.std.withidentitydict and diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -143,13 +143,9 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing + op = bk._find_current_op("is_", 2) knowntypedata = {} - fn, block, i = bk.position_key - annotator = bk.annotator - op = block.operations[i] - assert op.opname == "is_" - assert len(op.args) == 2 def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): @@ -319,11 +315,7 @@ rarithmetic.signedtype(int2.knowntype)): return r knowntypedata = {} - # XXX HACK HACK HACK - fn, block, i = getbookkeeper().position_key - op = block.operations[i] - assert op.opname == opname - assert len(op.args) == 2 + op = getbookkeeper()._find_current_op(opname=opname, arity=2) def tointtype(int0): if int0.knowntype is bool: return int diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -693,6 +693,20 @@ if emulate_enter: self.leave() + def _find_current_op(self, opname=None, arity=None, pos=None, s_type=None): + """ Find operation that is currently being annotated. Do some + sanity checks to see whether the correct op was found.""" + # XXX XXX HACK HACK HACK + fn, block, i = self.position_key + op = block.operations[i] + if opname is not None: + assert op.opname == opname or op.opname in opname + if arity is not None: + assert len(op.args) == arity + if pos is not None: + assert self.annotator.binding(op.args[pos]) == s_type + return op + def build_args(self, op, args_s): space = RPythonCallsSpace() if op == "simple_call": diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -178,15 +178,9 @@ # from bool to int, notice that isinstance( , bool|int) # is quite border case for RPython r.const = False - # XXX HACK HACK HACK - # XXX HACK HACK HACK - # XXX HACK HACK HACK bk = getbookkeeper() if variables is None: - fn, block, i = bk.position_key - op = block.operations[i] - assert op.opname == "simple_call" - assert len(op.args) == 3 + op = bk._find_current_op("simple_call", 3) assert op.args[0] == Constant(isinstance) variables = [op.args[1]] for variable in variables: diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -233,6 +233,9 @@ def nonnoneify(self): return self.__class__(can_be_None=False, no_nul=self.no_nul) + def nonnulify(self): + return self.__class__(can_be_None=self.can_be_None, no_nul=True) + class SomeString(SomeStringOrUnicode): "Stands for an object which is known to be a string." knowntype = str 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 @@ -446,6 +446,25 @@ s_item = s.listdef.listitem.s_value assert s_item.no_nul + def test_str_split_nul(self): + def f(n): + return n.split('\0')[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeString(no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeString) + assert not s.can_be_None + assert s.no_nul + + def g(n): + return n.split('\0', 1)[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(g, [annmodel.SomeString(no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeString) + assert not s.can_be_None + assert not s.no_nul + def test_str_splitlines(self): a = self.RPythonAnnotator() def f(a_str): @@ -3762,6 +3781,19 @@ assert isinstance(s, annmodel.SomeString) assert not s.can_be_None + def test_contains_no_nul(self): + def f(i): + if "\0" in i: + return None + else: + return i + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeString(no_nul=False)]) + assert isinstance(s, annmodel.SomeString) + assert s.can_be_None + assert s.no_nul + def test_no___call__(self): class X(object): def __call__(self): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -43,12 +43,7 @@ raise Exception, 'type() called with more than one argument' r = SomeType() bk = getbookkeeper() - fn, block, i = bk.position_key - annotator = bk.annotator - op = block.operations[i] - assert op.opname == "type" - assert len(op.args) == 1 - assert annotator.binding(op.args[0]) == obj + op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=obj) r.is_type_of = [op.args[0]] return r @@ -79,10 +74,7 @@ bk = getbookkeeper() knowntypedata = {} - fn, block, i = bk.position_key - op = block.operations[i] - assert op.opname == "is_true" or op.opname == "nonzero" - assert len(op.args) == 1 + op = bk._find_current_op(opname=("is_true", "nonzero"), arity=1) arg = op.args[0] s_nonnone_obj = s_obj if s_obj.can_be_none(): @@ -504,7 +496,11 @@ def method_split(str, patt, max=-1): getbookkeeper().count("str_split", str, patt) - s_item = str.basestringclass(no_nul=str.no_nul) + if max == -1 and patt.is_constant() and patt.const == "\0": + no_nul = True + else: + no_nul = str.no_nul + s_item = str.basestringclass(no_nul=no_nul) return getbookkeeper().newlist(s_item) def method_rsplit(str, patt, max=-1): @@ -520,6 +516,20 @@ result = str.basestringclass(no_nul=str.no_nul) return result + def op_contains(str, s_element): + if s_element.is_constant() and s_element.const == "\0": + r = SomeBool() + bk = getbookkeeper() + op = bk._find_current_op(opname="contains", arity=2, pos=0, s_type=str) + knowntypedata = {} + add_knowntypedata(knowntypedata, False, [op.args[0]], str.nonnulify()) + r.set_knowntypedata(knowntypedata) + return r + else: + return SomeObject.op_contains(str, s_element) + op_contains.can_only_throw = [] + + class __extend__(SomeUnicodeString): def method_encode(uni, s_enc): if not s_enc.is_constant(): From noreply at buildbot.pypy.org Tue Mar 12 17:45:59 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 17:45:59 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the tests Message-ID: <20130312164559.114FB1C13DD@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62319:c1c13193ef64 Date: 2013-03-12 17:36 +0100 http://bitbucket.org/pypy/pypy/changeset/c1c13193ef64/ Log: fix the tests 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 @@ -15,6 +15,7 @@ from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.codewriter import longlong from rpython.rlib.objectmodel import invoke_around_extcall CPU = getcpuclass() @@ -510,6 +511,8 @@ val = 0 for i in range(len(frame.jf_gcmap)): item = frame.jf_gcmap[i] + if item == 0: + val += WORD * 8 while item != 0: if item & 1: res.append(val) @@ -623,9 +626,11 @@ cpu.gc_ll_descr.init_nursery(20) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) - frame = cpu.execute_token(token, 2.3) + arg = longlong.getfloatstorage(2.3) + frame = cpu.execute_token(token, arg) ofs = cpu.get_baseofs_of_frame_field() f = cpu.read_float_at_mem(frame, ofs) + f = longlong.getrealfloat(f) assert f == 2.3 + 1.2 def test_malloc_1(self): From noreply at buildbot.pypy.org Tue Mar 12 17:46:00 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 12 Mar 2013 17:46:00 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: pass test_shadowstack_call and test_shadowstack_collecting_call_float Message-ID: <20130312164600.878761C3A31@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r62320:5c95268a7e45 Date: 2013-03-12 17:42 +0100 http://bitbucket.org/pypy/pypy/changeset/5c95268a7e45/ Log: pass test_shadowstack_call and test_shadowstack_collecting_call_float diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -52,7 +52,7 @@ self._exit_code_addr = 0 self.current_clt = None self.malloc_slowpath = 0 - self.wb_slowpath = [0, 0, 0, 0] + self.wb_slowpath = [0, 0, 0, 0, 0] self._regalloc = None self.datablockwrapper = None self.propagate_exception_path = 0 @@ -400,10 +400,10 @@ def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0): gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: - import pdb; pdb.set_trace() rst = gcrootmap.get_root_stack_top_addr() - mc.MOV(ecx, heap(rst)) - mc.MOV(ebp, mem(ecx, -WORD)) + mc.gen_load_int(r.ip.value, rst) + self.load_reg(mc, r.ip, r.ip) + self.load_reg(mc, r.fp, r.ip, ofs=-WORD) wbdescr = self.cpu.gc_ll_descr.write_barrier_descr if gcrootmap and wbdescr: # frame never uses card marking, so we enforce this is not @@ -558,25 +558,24 @@ def gen_shadowstack_header(self, gcrootmap): # we need to put two words into the shadowstack: the MARKER_FRAME # and the address of the frame (fp, actually) + # lr = rst addr + # ip = *lr rst = gcrootmap.get_root_stack_top_addr() - self.mc.gen_load_int(r.ip.value, rst) - self.mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop] + self.mc.gen_load_int(r.lr.value, rst) + self.load_reg(self.mc, r.ip, r.lr) + # *ip = r.fp + self.store_reg(self.mc, r.fp, r.ip) # - MARKER = gcrootmap.MARKER_FRAME - self.mc.ADD_ri(r.r5.value, r.r4.value, - imm=2 * WORD) # ADD r5, r4 [2*WORD] - self.mc.gen_load_int(r.r6.value, MARKER) - self.mc.STR_ri(r.r6.value, r.r4.value, WORD) # STR MARKER, r4 [WORD] - self.mc.STR_ri(r.fp.value, r.r4.value) # STR fp, r4 - # - self.mc.STR_ri(r.r5.value, r.ip.value) # STR r5 [rootstacktop] + self.mc.ADD_ri(r.ip.value, r.ip.value, WORD) + # *lr = ip + WORD + self.store_reg(self.mc, r.ip, r.lr) def gen_footer_shadowstack(self, gcrootmap, mc): rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip.value, rst) - mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop] - mc.SUB_ri(r.r5.value, r.r4.value, imm=2 * WORD) # ADD r5, r4 [2*WORD] - mc.STR_ri(r.r5.value, r.ip.value) + self.load_reg(mc, r.r4, r.ip) + mc.SUB_ri(r.r4.value, r.r4.value, WORD) + self.store_reg(mc, r.r4, r.ip) def _dump(self, ops, type='loop'): debug_start('jit-backend-ops') @@ -854,8 +853,8 @@ def _load_shadowstack_top(self, mc, reg, gcrootmap): rst = gcrootmap.get_root_stack_top_addr() - self.mc.gen_load_int(reg.value, rst) - self.mc.gen_load_int(reg.value, reg.value) + mc.gen_load_int(reg.value, rst) + mc.gen_load_int(reg.value, reg.value) return rst def fixup_target_tokens(self, rawstart): @@ -1012,7 +1011,7 @@ mc.VLDR(target.value, helper.value, cond=cond) def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): - if check_imm_arg(ofs): + if check_imm_arg(abs(ofs)): mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) else: mc.gen_load_int(helper.value, ofs, cond=cond) @@ -1295,7 +1294,9 @@ def pop_gcmap(self, mc): ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') - mc.MOV_bi(ofs, 0) + assert check_imm_arg(ofs) + mc.gen_load_int(r.ip.value, 0) + self.store_reg(mc, r.ip, r.fp, ofs) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -349,14 +349,19 @@ return cond def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, - result_info=(-1, -1)): + result_info=(-1, -1), + can_collect=1): if self.cpu.use_hf_abi: - stack_args, adr = self._setup_call_hf(adr, - arglocs, fcond, resloc, result_info) + stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, + resloc, result_info) else: - stack_args, adr = self._setup_call_sf(adr, - arglocs, fcond, resloc, result_info) + stack_args, adr = self._setup_call_sf(adr, arglocs, fcond, + resloc, result_info) + if can_collect: + noregs = self.cpu.gc_ll_descr.is_shadow_stack() + gcmap = self._regalloc.get_gcmap([r.r0], noregs=noregs) + self.push_gcmap(self.mc, gcmap, store=True) #the actual call #self.mc.BKPT() if adr.is_imm(): @@ -378,6 +383,9 @@ elif resloc.is_reg() and result_info != (-1, -1): self._ensure_result_bit_extension(resloc, result_info[0], result_info[1]) + if can_collect: + self._reload_frame_if_necessary(self.mc, can_collect=can_collect) + self.pop_gcmap(self.mc) return fcond def _restore_sp(self, stack_args, fcond): @@ -573,7 +581,7 @@ self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, fcond, array=True) - def _write_barrier_fastpath(self, mc, descr, arglocs, fcond, array=False, + def _write_barrier_fastpath(self, mc, descr, arglocs, fcond=c.AL, array=False, is_frame=False): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a @@ -596,22 +604,21 @@ loc_base = arglocs[0] if is_frame: assert loc_base is r.fp - else: - self.mc.LDRB_ri(r.ip.value, loc_base.value, - imm=descr.jit_wb_if_flag_byteofs) + mc.LDRB_ri(r.ip.value, loc_base.value, + imm=descr.jit_wb_if_flag_byteofs) mask &= 0xFF - self.mc.TST_ri(r.ip.value, imm=mask) - jz_location = self.mc.currpos() - self.mc.BKPT() + mc.TST_ri(r.ip.value, imm=mask) + jz_location = mc.currpos() + mc.BKPT() # for cond_call_gc_wb_array, also add another fast path: # if GCFLAG_CARDS_SET, then we can just set one bit and be done if card_marking: # GCFLAG_CARDS_SET is in this byte at 0x80 - self.mc.TST_ri(r.ip.value, imm=0x80) + mc.TST_ri(r.ip.value, imm=0x80) - js_location = self.mc.currpos() - self.mc.BKPT() + js_location = mc.currpos() + mc.BKPT() else: js_location = 0 @@ -619,7 +626,7 @@ # argument the address of the structure we are writing into # (the first argument to COND_CALL_GC_WB). helper_num = card_marking - if self._regalloc.vfprm.reg_bindings: + if self._regalloc is not None and self._regalloc.vfprm.reg_bindings: helper_num += 2 if self.wb_slowpath[helper_num] == 0: # tests only assert not we_are_translated() @@ -628,24 +635,24 @@ bool(self._regalloc.vfprm.reg_bindings)) assert self.wb_slowpath[helper_num] != 0 # - if loc_base is not r.r0: + if not is_frame and loc_base is not r.r0: # push two registers to keep stack aligned - self.mc.PUSH([r.r0.value, loc_base.value]) + mc.PUSH([r.r0.value, loc_base.value]) remap_frame_layout(self, [loc_base], [r.r0], r.ip) - self.mc.BL(self.wb_slowpath[helper_num]) - if loc_base is not r.r0: - self.mc.POP([r.r0.value, loc_base.value]) + mc.BL(self.wb_slowpath[helper_num]) + if not is_frame and loc_base is not r.r0: + mc.POP([r.r0.value, loc_base.value]) if card_marking: # The helper ends again with a check of the flag in the object. So # here, we can simply write again a conditional jump, which will be # taken if GCFLAG_CARDS_SET is still not set. - jns_location = self.mc.currpos() - self.mc.BKPT() + jns_location = mc.currpos() + mc.BKPT() # # patch the JS above - offset = self.mc.currpos() - pmc = OverwritingBuilder(self.mc, js_location, WORD) + offset = mc.currpos() + pmc = OverwritingBuilder(mc, js_location, WORD) pmc.B_offs(offset, c.NE) # We want to jump if the z flag isn't set # # case GCFLAG_CARDS_SET: emit a few instructions to do @@ -653,36 +660,36 @@ loc_index = arglocs[1] assert loc_index.is_reg() # must save the register loc_index before it is mutated - self.mc.PUSH([loc_index.value]) + mc.PUSH([loc_index.value]) tmp1 = loc_index tmp2 = arglocs[-1] # the last item is a preallocated tmp # lr = byteofs s = 3 + descr.jit_wb_card_page_shift - self.mc.MVN_rr(r.lr.value, loc_index.value, + mc.MVN_rr(r.lr.value, loc_index.value, imm=s, shifttype=shift.LSR) # tmp1 = byte_index - self.mc.MOV_ri(r.ip.value, imm=7) - self.mc.AND_rr(tmp1.value, r.ip.value, loc_index.value, + mc.MOV_ri(r.ip.value, imm=7) + mc.AND_rr(tmp1.value, r.ip.value, loc_index.value, imm=descr.jit_wb_card_page_shift, shifttype=shift.LSR) # set the bit - self.mc.MOV_ri(tmp2.value, imm=1) - self.mc.LDRB_rr(r.ip.value, loc_base.value, r.lr.value) - self.mc.ORR_rr_sr(r.ip.value, r.ip.value, tmp2.value, + mc.MOV_ri(tmp2.value, imm=1) + mc.LDRB_rr(r.ip.value, loc_base.value, r.lr.value) + mc.ORR_rr_sr(r.ip.value, r.ip.value, tmp2.value, tmp1.value, shifttype=shift.LSL) - self.mc.STRB_rr(r.ip.value, loc_base.value, r.lr.value) + mc.STRB_rr(r.ip.value, loc_base.value, r.lr.value) # done - self.mc.POP([loc_index.value]) + mc.POP([loc_index.value]) # # # patch the JNS above - offset = self.mc.currpos() - pmc = OverwritingBuilder(self.mc, jns_location, WORD) + offset = mc.currpos() + pmc = OverwritingBuilder(mc, jns_location, WORD) pmc.B_offs(offset, c.EQ) # We want to jump if the z flag is set - offset = self.mc.currpos() - pmc = OverwritingBuilder(self.mc, jz_location, WORD) + offset = mc.currpos() + pmc = OverwritingBuilder(mc, jz_location, WORD) pmc.B_offs(offset, c.EQ) return fcond @@ -1044,7 +1051,8 @@ # call memcpy() regalloc.before_call() self._emit_call(imm(self.memcpy_addr), - [dstaddr_loc, srcaddr_loc, length_loc]) + [dstaddr_loc, srcaddr_loc, length_loc], + can_collect=False) regalloc.possibly_free_var(length_box) regalloc.possibly_free_var(dstaddr_box) diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -349,7 +349,7 @@ for box, loc in self.fm.bindings.iteritems(): if box.type == REF and self.rm.is_still_alive(box): assert loc.is_stack() - val = loc.value // WORD + val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) return gcmap 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 @@ -552,6 +552,9 @@ gcmap = unpack_gcmap(frame) if self.cpu.IS_64_BIT: assert gcmap == [28, 29, 30] + elif self.cpu.backend_name.startswith('arm'): + assert gcmap == [44, 45, 46] + pass else: assert gcmap == [22, 23, 24] for item, s in zip(gcmap, new_items): From noreply at buildbot.pypy.org Tue Mar 12 18:17:16 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 12 Mar 2013 18:17:16 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: patched the MethodDictShadow to save compiledmethod shadows instead of w_compiled methods Message-ID: <20130312171716.E445F1C13DD@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r166:03270ab317f2 Date: 2013-03-12 18:16 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/03270ab317f2/ Log: patched the MethodDictShadow to save compiledmethod shadows instead of w_compiled methods diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -273,8 +273,7 @@ jit.promote(self) version = self.version jit.promote(version) - w_method = self.safe_lookup(w_selector, version) - return w_method.as_compiledmethod_get_shadow(self.space) + return self.safe_lookup(w_selector, version) @jit.elidable def safe_lookup(self, w_selector, version): @@ -282,9 +281,9 @@ look_in_shadow = self jit.promote(w_selector) while look_in_shadow is not None: - w_method = look_in_shadow.s_methoddict().find_selector(w_selector) - if w_method is not None: - return w_method + s_method = look_in_shadow.s_methoddict().find_selector(w_selector) + if s_method is not None: + return s_method look_in_shadow = look_in_shadow._s_superclass raise MethodNotFound(self, w_selector) @@ -314,10 +313,10 @@ "NOT_RPYTHON" # this is only for testing. assert not isinstance(w_selector, str) self.initialize_methoddict() - self.s_methoddict().methoddict[w_selector] = w_method + s_method = w_method.as_compiledmethod_get_shadow(self.space) + self.s_methoddict().methoddict[w_selector] = s_method if isinstance(w_method, model.W_CompiledMethod): - method = w_method.as_compiledmethod_get_shadow(self.space) - method.w_compiledin = self.w_self() + s_method.w_compiledin = self.w_self() class MethodDictionaryShadow(AbstractShadow): @@ -366,7 +365,7 @@ "CompiledMethods only, for now. " "If the value observed is nil, our " "invalidating mechanism may be broken.") - self.methoddict[w_selector] = w_compiledmethod + self.methoddict[w_selector] = w_compiledmethod.as_compiledmethod_get_shadow(self.space) selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector if self.s_class: diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -58,7 +58,7 @@ image = create_testimage(space) interp = interpreter.Interpreter(space, image) - w_selector = interp.perform(space.wrap_string('loopTest3'), "asSymbol") + w_selector = interp.perform(space.wrap_string('loopTest2'), "asSymbol") assert isinstance(w_selector, model.W_BytesObject) def interp_w(): interp.perform(model.W_SmallInteger(1000), w_selector) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -428,7 +428,7 @@ assert s_active_context.w_sender() == w_frame assert s_active_context.stack() == [] assert w_active_context.as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) - assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) + assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo].w_self()) assert s_frame.stack() == [] step_in_interp(s_active_context) w_active_context = step_in_interp(s_active_context) @@ -599,7 +599,7 @@ s_frame.push(space.w_one) w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) - assert w_active_context.as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] + assert w_active_context.as_methodcontext_get_shadow(space).s_method() == shadow.s_methoddict().methoddict[w_symbol] assert s_active_context.w_receiver() is w_object assert w_active_context.as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) assert s_active_context.stack() == [] @@ -660,7 +660,7 @@ assert s_active_context.stack() == [] assert w_active_context.as_methodcontext_get_shadow(space).w_receiver() == w_object meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict[foo] - assert s_active_context.w_method() == meth + assert s_active_context.w_method() == meth.w_self() assert s_caller_context.stack() == [] def test_secondExtendedSendBytecode(): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -298,9 +298,6 @@ perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) assert perform(w(10), "fib").is_same_object(w(89)) -def test_get_env(): - import pdb; pdb.set_trace() - def test_step_run_something(): from spyvm.test import test_miniimage setup_module(test_miniimage, filename='running-something-mini.image') diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -73,7 +73,7 @@ methoddict = classshadow.s_methoddict().methoddict assert len(methods) == len(methoddict) for w_key, value in methoddict.items(): - assert methods[w_key.as_string()] is value + assert methods[w_key.as_string()].as_compiledmethod_get_shadow(space) is value def method(tempsize=3,argsize=2, bytes="abcde"): w_m = model.W_CompiledMethod() From noreply at buildbot.pypy.org Tue Mar 12 19:08:08 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Tue, 12 Mar 2013 19:08:08 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: make frame size computation version-constant Message-ID: <20130312180808.17A8C1C3A30@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r168:4228d5ed7193 Date: 2013-03-12 19:07 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4228d5ed7193/ Log: make frame size computation version-constant diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -800,12 +800,8 @@ @jit.unroll_safe def make_context(space, s_method, w_receiver, arguments, s_sender=None, closure=None, pc=0): - # From blue book: normal mc have place for 12 temps+maxstack - # mc for methods with islarge flag turned on 32 - size = (12 + s_method.islarge * 20 + s_method.argsize - + space.w_MethodContext.as_class_get_shadow(space).instsize()) - # The last summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self. - + # The summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self. + size = s_method.compute_frame_size() + space.w_MethodContext.as_class_get_shadow(space).instsize() s_new_context = MethodContextShadow(space, None) s_new_context._w_self_size = size s_new_context_non_fresh = s_new_context # XXX: find a better solution to translation err @@ -956,6 +952,12 @@ def getliteral(self, index): return self.literals[index] + @make_elidable_after_versioning + def compute_frame_size(self): + # From blue book: normal mc have place for 12 temps+maxstack + # mc for methods with islarge flag turned on 32 + return 12 + self.islarge * 20 + self.argsize + def getliteralsymbol(self, index): w_literal = self.getliteral(index) assert isinstance(w_literal, model.W_BytesObject) From noreply at buildbot.pypy.org Tue Mar 12 19:08:06 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Tue, 12 Mar 2013 19:08:06 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: make more attributes on shadows immutable per version. invent a decorator to Message-ID: <20130312180806.F05B41C13DD@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r167:500374918ff4 Date: 2013-03-12 18:43 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/500374918ff4/ Log: make more attributes on shadows immutable per version. invent a decorator to automate this. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -290,9 +290,9 @@ s_method = receiverclassshadow.lookup(w_selector) # XXX catch MethodNotFound here and send doesNotUnderstand: # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. - if s_method.primitive: + code = s_method.primitive() + if code: # the primitive pushes the result (if any) onto the stack itself - code = s_method.primitive if interp.should_trace(): print "%sActually calling primitive %d" % (interp._last_indent, code,) func = primitives.prim_holder.prim_table[code] diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -299,7 +299,7 @@ s._s_superclass = None s.store_w_superclass(w_superclass) s.name = name - s.instance_size = instsize + s._instance_size = instsize s.instance_kind = format s._s_methoddict = None s.instance_varsized = varsized or format != shadow.POINTERS diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -3,6 +3,16 @@ from rpython.tool.pairtype import extendabletype from rpython.rlib import rarithmetic, jit +def make_elidable_after_versioning(func): + @jit.elidable + def elidable_func(self, version, *args): + return func(self, *args) + def meth(self, *args): + jit.promote(self) + version = jit.promote(self.version) + return elidable_func(self, version, *args) + return meth + class AbstractShadow(object): """A shadow is an optional extra bit of information that can be attached at run-time to any Smalltalk object. @@ -74,7 +84,7 @@ (i.e. used as the class of another Smalltalk object). """ - _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", + _attr_ = ["name", "_instance_size", "instance_varsized", "instance_kind", "_s_methoddict", "_s_superclass", "subclass_s"] def __init__(self, space, w_self): @@ -109,7 +119,7 @@ # compute the instance size (really the size, not the number of bytes) instsize_lo = (classformat >> 1) & 0x3F instsize_hi = (classformat >> (9 + 1)) & 0xC0 - self.instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr + self._instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr # decode the instSpec format = (classformat >> 7) & 15 self.instance_varsized = format >= 2 @@ -119,12 +129,12 @@ self.instance_kind = WEAK_POINTERS elif format == 6: self.instance_kind = WORDS - if self.instance_size != 0: + if self.instsize() != 0: raise ClassShadowError("can't have both words and a non-zero " "base instance size") elif 8 <= format <= 11: self.instance_kind = BYTES - if self.instance_size != 0: + if self.instsize() != 0: raise ClassShadowError("can't have both bytes and a non-zero " "base instance size") elif 12 <= format <= 15: @@ -184,7 +194,7 @@ def new(self, extrasize=0): w_cls = self.w_self() if self.instance_kind == POINTERS: - w_new = model.W_PointersObject(w_cls, self.instance_size+extrasize) + w_new = model.W_PointersObject(w_cls, self.instsize()+extrasize) elif self.instance_kind == WORDS: w_new = model.W_WordsObject(w_cls, extrasize) elif self.instance_kind == BYTES: @@ -226,13 +236,15 @@ " True if instances of this class have data stored as numerical bytes " return self.format == BYTES + @make_elidable_after_versioning def isvariable(self): " True if instances of this class have indexed inst variables " return self.instance_varsized + @make_elidable_after_versioning def instsize(self): " Number of named instance variables for each instance of this class " - return self.instance_size + return self._instance_size def store_w_superclass(self, w_class): if w_class is None: @@ -269,17 +281,9 @@ def __repr__(self): return "" % (self.name or '?',) + @make_elidable_after_versioning def lookup(self, w_selector): - jit.promote(self) - version = self.version - jit.promote(version) - return self.safe_lookup(w_selector, version) - - @jit.elidable - def safe_lookup(self, w_selector, version): - assert version is self.version look_in_shadow = self - jit.promote(w_selector) while look_in_shadow is not None: s_method = look_in_shadow.s_methoddict().find_selector(w_selector) if s_method is not None: @@ -573,7 +577,7 @@ def getbytecode(self): jit.promote(self._pc) assert self._pc >= 0 - bytecode = self.s_method().bytecode[self._pc] + bytecode = self.s_method().getbytecode(self._pc) currentBytecode = ord(bytecode) self._pc += 1 return currentBytecode @@ -667,7 +671,7 @@ if self._w_self is not None: return self._w_self else: - size = self.size() - self.space.w_MethodContext.as_class_get_shadow(self.space).instance_size + size = self.size() - self.space.w_MethodContext.as_class_get_shadow(self.space).instsize() space = self.space w_self = space.w_MethodContext.as_class_get_shadow(space).new(size) w_self.store_shadow(self) @@ -799,7 +803,7 @@ # From blue book: normal mc have place for 12 temps+maxstack # mc for methods with islarge flag turned on 32 size = (12 + s_method.islarge * 20 + s_method.argsize - + space.w_MethodContext.as_class_get_shadow(space).instance_size) + + space.w_MethodContext.as_class_get_shadow(space).instsize()) # The last summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self. s_new_context = MethodContextShadow(space, None) @@ -862,7 +866,7 @@ def tempsize(self): if not self.is_closure_context(): - return self.s_method().tempsize + return self.s_method().tempsize() else: return wrapper.BlockClosureWrapper(self.space, self.w_closure_or_nil).tempsize() @@ -948,15 +952,8 @@ def w_self(self): return self._w_self + @make_elidable_after_versioning def getliteral(self, index): - jit.promote(self) - version = self.version - jit.promote(version) - return self.safe_getliteral(index, version) - - @jit.elidable - def safe_getliteral(self, index, version): - assert version is self.version return self.literals[index] def getliteralsymbol(self, index): @@ -971,8 +968,8 @@ self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() self.literalsize = w_compiledmethod.getliteralsize() - self.tempsize = w_compiledmethod.gettempsize() - self.primitive = w_compiledmethod.primitive + self._tempsize = w_compiledmethod.gettempsize() + self._primitive = w_compiledmethod.primitive self.argsize = w_compiledmethod.argsize self.islarge = w_compiledmethod.islarge @@ -989,12 +986,24 @@ association = wrapper.AssociationWrapper(None, w_association) self.w_compiledin = association.value() + @make_elidable_after_versioning + def tempsize(self): + return self._tempsize + + @make_elidable_after_versioning + def primitive(self): + return self._primitive + def create_frame(self, space, receiver, arguments, sender = None): assert len(arguments) == self.argsize s_new = MethodContextShadow.make_context( space, self, receiver, arguments, sender) return s_new + @make_elidable_after_versioning + def getbytecode(self, pc): + return self.bytecode[pc] + class CachedObjectShadow(AbstractCachingShadow): def fetch(self, n0): diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -186,7 +186,7 @@ assert shadow.bytecode == "abc" assert shadow.bytecodeoffset == 12 assert shadow.literalsize == 8 # 12 - 4byte header - assert shadow.tempsize == 1 + assert shadow.tempsize() == 1 w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) From noreply at buildbot.pypy.org Tue Mar 12 19:33:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Mar 2013 19:33:23 +0100 (CET) Subject: [pypy-commit] pypy default: setitem shouldn't return anything, separate for clarity Message-ID: <20130312183323.8BA461C0014@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62321:6a6f67992369 Date: 2013-03-12 14:25 -0400 http://bitbucket.org/pypy/pypy/changeset/6a6f67992369/ Log: setitem shouldn't return anything, separate for clarity diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -158,8 +158,8 @@ view = chunks.apply(self) view.implementation.setslice(space, w_value) return - return loop.setitem_array_int(space, self, iter_shape, indexes, val_arr, - prefix) + loop.setitem_array_int(space, self, iter_shape, indexes, val_arr, + prefix) def descr_getitem(self, space, w_idx): if (isinstance(w_idx, W_NDimArray) and @@ -180,9 +180,9 @@ def descr_setitem(self, space, w_idx, w_value): if (isinstance(w_idx, W_NDimArray) and - w_idx.get_dtype().is_bool_type()): - return self.setitem_filter(space, w_idx, - convert_to_array(space, w_value)) + w_idx.get_dtype().is_bool_type()): + self.setitem_filter(space, w_idx, convert_to_array(space, w_value)) + return try: self.implementation.descr_setitem(space, self, w_idx, w_value) except ArrayArgumentException: From noreply at buildbot.pypy.org Tue Mar 12 20:01:24 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 12 Mar 2013 20:01:24 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added s_class cache to w_AbstractObjectWithClassReference Message-ID: <20130312190124.AF06C1C3A30@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r169:dcc5162f3ac8 Date: 2013-03-12 20:01 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/dcc5162f3ac8/ Log: added s_class cache to w_AbstractObjectWithClassReference diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -221,11 +221,14 @@ class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash): """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" - _attrs_ = ['w_class'] + _attrs_ = ['w_class', 's_class'] + s_class = None def __init__(self, w_class): if w_class is not None: # it's None only for testing and space generation assert isinstance(w_class, W_PointersObject) + if w_class.has_shadow(): + self.s_class = w_class.as_class_get_shadow(w_class._shadow.space) self.w_class = w_class def getclass(self, space): @@ -250,11 +253,16 @@ def _become(self, w_other): self.w_class, w_other.w_class = w_other.w_class, self.w_class + self.s_class, w_other.s_class = w_other.s_class, self.s_class W_AbstractObjectWithIdentityHash._become(self, w_other) def has_class(self): return self.w_class is not None - + + def shadow_of_my_class(self, space): + if self.s_class is None: + self.s_class = self.w_class.as_class_get_shadow(space) + return self.s_class class W_PointersObject(W_AbstractObjectWithClassReference): """Common object.""" diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -644,6 +644,7 @@ raise PrimitiveFailedError() w_rcvr.w_class = w_arg.w_class + w_rcvr.s_class = w_arg.s_class # ___________________________________________________________________________ # Miscellaneous Primitives (120-127) diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -523,6 +523,7 @@ w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) w_pointersobject.w_class = w_class + w_pointersobject.s_class = None w_pointersobject.hash = self.chunk.hash12 def fillin_wordsobject(self, w_wordsobject): From noreply at buildbot.pypy.org Tue Mar 12 22:48:33 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 12 Mar 2013 22:48:33 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: Don't pass unnecessary params to public extregistry functions Message-ID: <20130312214833.55ECE1C13DD@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62322:c87052ea1606 Date: 2013-03-11 20:37 +0000 http://bitbucket.org/pypy/pypy/changeset/c87052ea1606/ Log: Don't pass unnecessary params to public extregistry functions diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -426,8 +426,8 @@ elif ishashable(x) and x in BUILTIN_ANALYZERS: _module = getattr(x,"__module__","unknown") result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__)) - elif extregistry.is_registered(x, self.policy): - entry = extregistry.lookup(x, self.policy) + elif extregistry.is_registered(x): + entry = extregistry.lookup(x) result = entry.compute_annotation_bk(self) elif isinstance(x, lltype._ptr): result = SomePtr(lltype.typeOf(x)) diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -82,8 +82,8 @@ return SomeUnicodeString() elif t is types.NoneType: return s_None - elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): - entry = extregistry.lookup_type(t, bookkeeper.policy) + elif bookkeeper and extregistry.is_registered_type(t): + entry = extregistry.lookup_type(t) return entry.compute_annotation_bk(bookkeeper) elif t is type: return SomeType() @@ -97,7 +97,7 @@ def __init__(self, *argtypes): self.argtypes = argtypes - + def __call__(self, funcdesc, inputcells): from rpython.rtyper.lltypesystem import lltype args_s = [] diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -131,11 +131,11 @@ except (KeyError, TypeError): return EXT_REGISTRY_BY_METATYPE[type(tp)] -def lookup_type(tp, _ignored=None): +def lookup_type(tp): Entry = _lookup_type_cls(tp) return Entry(tp) -def is_registered_type(tp, _ignored=None): +def is_registered_type(tp): try: _lookup_type_cls(tp) except KeyError: @@ -148,11 +148,11 @@ except (KeyError, TypeError): return _lookup_type_cls(type(instance)) -def lookup(instance, _ignored=None): +def lookup(instance): Entry = _lookup_cls(instance) return Entry(type(instance), instance) -def is_registered(instance, _ignored=None): +def is_registered(instance): try: _lookup_cls(instance) except KeyError: From noreply at buildbot.pypy.org Wed Mar 13 00:04:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Mar 2013 00:04:13 +0100 (CET) Subject: [pypy-commit] pypy py3k: properly decode *all* AST identifiers Message-ID: <20130312230413.CC1BD1C3A32@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62323:80061bd0e2b6 Date: 2013-03-12 16:03 -0700 http://bitbucket.org/pypy/pypy/changeset/80061bd0e2b6/ Log: properly decode *all* AST identifiers diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -3105,7 +3105,9 @@ if not w_self.initialization_state & 4: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name') - return space.wrap(w_self.name) + if w_self.name is None: + return space.w_None + return space.wrap(w_self.name.decode('utf-8')) def FunctionDef_set_name(space, w_self, w_new_value): try: @@ -3237,7 +3239,9 @@ if not w_self.initialization_state & 4: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name') - return space.wrap(w_self.name) + if w_self.name is None: + return space.w_None + return space.wrap(w_self.name.decode('utf-8')) def ClassDef_set_name(space, w_self, w_new_value): try: @@ -4368,7 +4372,9 @@ if not w_self.initialization_state & 4: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'module') - return space.wrap(w_self.module) + if w_self.module is None: + return space.w_None + return space.wrap(w_self.module.decode('utf-8')) def ImportFrom_set_module(space, w_self, w_new_value): try: @@ -5947,7 +5953,9 @@ if not w_self.initialization_state & 8: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'attr') - return space.wrap(w_self.attr) + if w_self.attr is None: + return space.w_None + return space.wrap(w_self.attr.decode('utf-8')) def Attribute_set_attr(space, w_self, w_new_value): try: @@ -6190,7 +6198,9 @@ if not w_self.initialization_state & 4: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'id') - return space.wrap(w_self.id) + if w_self.id is None: + return space.w_None + return space.wrap(w_self.id.decode('utf-8')) def Name_set_id(space, w_self, w_new_value): try: @@ -7078,7 +7088,9 @@ if not w_self.initialization_state & 8: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name') - return space.wrap(w_self.name) + if w_self.name is None: + return space.w_None + return space.wrap(w_self.name.decode('utf-8')) def ExceptHandler_set_name(space, w_self, w_new_value): try: @@ -7164,7 +7176,9 @@ if not w_self.initialization_state & 2: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'vararg') - return space.wrap(w_self.vararg) + if w_self.vararg is None: + return space.w_None + return space.wrap(w_self.vararg.decode('utf-8')) def arguments_set_vararg(space, w_self, w_new_value): try: @@ -7230,7 +7244,9 @@ if not w_self.initialization_state & 16: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'kwarg') - return space.wrap(w_self.kwarg) + if w_self.kwarg is None: + return space.w_None + return space.wrap(w_self.kwarg.decode('utf-8')) def arguments_set_kwarg(space, w_self, w_new_value): try: @@ -7348,7 +7364,9 @@ if not w_self.initialization_state & 1: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'arg') - return space.wrap(w_self.arg) + if w_self.arg is None: + return space.w_None + return space.wrap(w_self.arg.decode('utf-8')) def arg_set_arg(space, w_self, w_new_value): try: @@ -7419,7 +7437,9 @@ if not w_self.initialization_state & 1: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'arg') - return space.wrap(w_self.arg) + if w_self.arg is None: + return space.w_None + return space.wrap(w_self.arg.decode('utf-8')) def keyword_set_arg(space, w_self, w_new_value): try: @@ -7490,7 +7510,9 @@ if not w_self.initialization_state & 1: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name') - return space.wrap(w_self.name) + if w_self.name is None: + return space.w_None + return space.wrap(w_self.name.decode('utf-8')) def alias_set_name(space, w_self, w_new_value): try: @@ -7512,7 +7534,9 @@ if not w_self.initialization_state & 2: typename = space.type(w_self).getname(space) raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'asname') - return space.wrap(w_self.asname) + if w_self.asname is None: + return space.w_None + return space.wrap(w_self.asname.decode('utf-8')) def alias_set_asname(space, w_self, w_new_value): try: diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -438,6 +438,10 @@ self.emit("return %s_to_class[w_self.%s - 1]()" % config, 1) elif field.type.value in ("object", "string"): self.emit("return w_self.%s" % (field.name,), 1) + elif field.type.value == 'identifier': + self.emit("if w_self.%s is None:" % (field.name,), 1) + self.emit("return space.w_None", 2) + self.emit("return space.wrap(w_self.%s.decode('utf-8'))" % (field.name,), 1) else: self.emit("return space.wrap(w_self.%s)" % (field.name,), 1) self.emit("") diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py --- a/pypy/module/_ast/test/test_ast.py +++ b/pypy/module/_ast/test/test_ast.py @@ -86,10 +86,29 @@ name.id = "hi" assert name.id == "hi" - def test_unicode_identifier(self): + def test_name_pep3131(self): name = self.get_ast("日本", "eval").body + assert isinstance(name, self.ast.Name) assert name.id == "日本" + def test_function_pep3131(self): + fn = self.get_ast("def µ(µ='foo'): pass").body[0] + assert isinstance(fn, self.ast.FunctionDef) + # µ normalized to NFKC + expected = '\u03bc' + assert fn.name == expected + assert fn.args.args[0].arg == expected + + def test_import_pep3131(self): + ast = self.ast + im = self.get_ast("from packageµ import modµ as µ").body[0] + assert isinstance(im, ast.ImportFrom) + expected = '\u03bc' + assert im.module == 'package' + expected + alias = im.names[0] + assert alias.name == 'mod' + expected + assert alias.asname == expected + @py.test.mark.skipif("py.test.config.option.runappdirect") def test_object(self): ast = self.ast From noreply at buildbot.pypy.org Wed Mar 13 00:05:03 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Mar 2013 00:05:03 +0100 (CET) Subject: [pypy-commit] pypy py3k: have lock acquire retry on interrupts Message-ID: <20130312230503.741541C3A31@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62324:a66a94873880 Date: 2013-03-12 16:03 -0700 http://bitbucket.org/pypy/pypy/changeset/a66a94873880/ Log: have lock acquire retry on interrupts diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -2,6 +2,7 @@ Python locks, based on true threading locks provided by the OS. """ +import time from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.baseobjspace import Wrappable @@ -16,6 +17,7 @@ LONGLONG_MAX = r_longlong(2 ** (r_longlong.BITS-1) - 1) TIMEOUT_MAX = LONGLONG_MAX +RPY_LOCK_FAILURE, RPY_LOCK_ACQUIRED, RPY_LOCK_INTR = range(3) ##import sys ##def debug(msg, n): @@ -51,6 +53,23 @@ return microseconds +def acquire_timed(lock, microseconds): + """Helper to acquire an interruptible lock with a timeout.""" + endtime = (time.time() * 1000000) + microseconds + while True: + result = lock.acquire_timed(microseconds) + if result == RPY_LOCK_INTR: + if microseconds >= 0: + microseconds = r_longlong(endtime - (time.time() * 1000000)) + # Check for negative values, since those mean block + # forever + if microseconds <= 0: + result = RPY_LOCK_FAILURE + if result != RPY_LOCK_INTR: + break + return result + + class Lock(Wrappable): "A wrappable box around an interp-level lock object." @@ -70,10 +89,8 @@ and the return value reflects whether the lock is acquired. The blocking operation is interruptible.""" microseconds = parse_acquire_args(space, blocking, timeout) - mylock = self.lock - result = mylock.acquire_timed(microseconds) - result = (result == 1) # XXX handle RPY_LOCK_INTR (see e80549fefb75) - return space.newbool(result) + result = acquire_timed(self.lock, microseconds) + return space.newbool(result == RPY_LOCK_ACQUIRED) def descr_lock_release(self, space): """Release the lock, allowing another thread that is blocked waiting for @@ -184,8 +201,8 @@ if self.rlock_count > 0 or not self.lock.acquire(False): if not blocking: return space.w_False - r = self.lock.acquire_timed(microseconds) - r = (r == 1) # XXX handle RPY_LOCK_INTR (see e80549fefb75) + r = acquire_timed(self.lock, microseconds) + r = (r == RPY_LOCK_ACQUIRED) if r: assert self.rlock_count == 0 self.rlock_owner = tid 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 @@ -145,3 +145,44 @@ assert lock.acquire() is True assert lock.acquire(False) is True assert lock.acquire(True, timeout=.1) is True + + +class AppTestLockSignals(GenericTestThread): + + def w_acquire_retries_on_intr(self, lock): + import _thread, os, signal, time + self.sig_recvd = False + def my_handler(signal, frame): + self.sig_recvd = True + old_handler = signal.signal(signal.SIGUSR1, my_handler) + try: + def other_thread(): + # Acquire the lock in a non-main thread, so this test works for + # RLocks. + lock.acquire() + # Wait until the main thread is blocked in the lock acquire, and + # then wake it up with this. + time.sleep(0.5) + os.kill(os.getpid(), signal.SIGUSR1) + # Let the main thread take the interrupt, handle it, and retry + # the lock acquisition. Then we'll let it run. + time.sleep(0.5) + lock.release() + _thread.start_new_thread(other_thread, ()) + # Wait until we can't acquire it without blocking... + while lock.acquire(blocking=False): + lock.release() + time.sleep(0.01) + result = lock.acquire() # Block while we receive a signal. + assert self.sig_recvd + assert result + finally: + signal.signal(signal.SIGUSR1, old_handler) + + def test_lock_acquire_retries_on_intr(self): + import _thread + self.acquire_retries_on_intr(_thread.allocate_lock()) + + def test_rlock_acquire_retries_on_intr(self): + import _thread + self.acquire_retries_on_intr(_thread.RLock()) From noreply at buildbot.pypy.org Wed Mar 13 03:02:32 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Mar 2013 03:02:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: cleanup Message-ID: <20130313020232.D970C1C13DD@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62325:8c7f79ebe9ad Date: 2013-03-12 19:02 -0700 http://bitbucket.org/pypy/pypy/changeset/8c7f79ebe9ad/ Log: cleanup diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -55,12 +55,12 @@ def acquire_timed(lock, microseconds): """Helper to acquire an interruptible lock with a timeout.""" - endtime = (time.time() * 1000000) + microseconds + endtime = (time.time() * 1e6) + microseconds while True: result = lock.acquire_timed(microseconds) if result == RPY_LOCK_INTR: if microseconds >= 0: - microseconds = r_longlong(endtime - (time.time() * 1000000)) + microseconds = r_longlong(endtime - (time.time() * 1e6)) # Check for negative values, since those mean block # forever if microseconds <= 0: From noreply at buildbot.pypy.org Wed Mar 13 03:10:33 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 13 Mar 2013 03:10:33 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: kill genericcallable Message-ID: <20130313021033.7C8641C13DD@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: extregistry-refactor Changeset: r62326:f5464a2d44dd Date: 2013-03-13 02:10 +0000 http://bitbucket.org/pypy/pypy/changeset/f5464a2d44dd/ Log: kill genericcallable diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -18,7 +18,6 @@ from rpython.annotator.model import TLS from rpython.annotator.model import read_can_only_throw from rpython.annotator.model import add_knowntypedata, merge_knowntypedata -from rpython.annotator.model import SomeGenericCallable from rpython.annotator.bookkeeper import getbookkeeper from rpython.flowspace.model import Variable, Constant from rpython.rlib import rarithmetic @@ -812,20 +811,6 @@ s.const = False # no common desc in the two sets return s -class __extend__(pairtype(SomeGenericCallable, SomePBC)): - def union((gencall, pbc)): - for desc in pbc.descriptions: - unique_key = desc - bk = desc.bookkeeper - s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unionof(s_result, gencall.s_result) - assert gencall.s_result.contains(s_result) - return gencall - -class __extend__(pairtype(SomePBC, SomeGenericCallable)): - def union((pbc, gencall)): - return pair(gencall, pbc).union() - class __extend__(pairtype(SomeImpossibleValue, SomeObject)): def union((imp1, obj2)): return obj2 diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -449,16 +449,6 @@ else: return kt.__name__ -class SomeGenericCallable(SomeObject): - """ Stands for external callable with known signature - """ - def __init__(self, args, result): - self.args_s = args - self.s_result = result - - def can_be_None(self): - return True - class SomeBuiltin(SomeObject): "Stands for a built-in function or method with special-cased analysis." knowntype = BuiltinFunctionType # == BuiltinMethodType 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 @@ -3014,33 +3014,6 @@ s = a.build_types(fun, []) assert s.const == 0 - def test_some_generic_function_call(self): - def h(x): - return int(x) - - def c(x): - return int(x) - - def g(a, x): - if x == -1: - a = None - if x < 0: - if x == -1: - a = h - else: - a = c - x = x + .01 - return a(x) - - #def fun(x): - - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) - s = a.build_types(g, [annmodel.SomeGenericCallable( - args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), - annmodel.SomeFloat()]) - assert isinstance(s, annmodel.SomeInteger) - assert not hasattr(s, 'const') - def test_compare_int_bool(self): def fun(x): return 50 < x diff --git a/rpython/annotator/test/test_signature.py b/rpython/annotator/test/test_signature.py --- a/rpython/annotator/test/test_signature.py +++ b/rpython/annotator/test/test_signature.py @@ -6,10 +6,3 @@ assert _annotation_key({str:(str, [str])}) == ('dict', (str, (str, ('list', str)))) for i in ([[str]], [str], (int, int, {str: [str]})): assert hash(_annotation_key(i)) - -def test_genericcallable(): - py.test.skip("this two annotations should be equal - fix!") - from rpython.rtyper.extfunc import genericcallable - s1 = annotation([genericcallable([str], int)]) - s2 = annotation([genericcallable([str], int)]) - assert s1 == s2 diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -12,7 +12,7 @@ SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ - SomeGenericCallable, SomeWeakRef, SomeUnicodeString + SomeWeakRef, SomeUnicodeString from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import builtin from rpython.annotator.binaryop import _clone ## XXX where to put this? @@ -741,14 +741,6 @@ else: return SomeObject() # len() on a pbc? no chance -class __extend__(SomeGenericCallable): - def call(self, args): - bookkeeper = getbookkeeper() - for arg, expected in zip(args.unpack()[0], self.args_s): - assert expected.contains(arg) - - return self.s_result - # annotation of low-level types from rpython.annotator.model import SomePtr, SomeLLADTMeth from rpython.annotator.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py --- a/rpython/rtyper/extfunc.py +++ b/rpython/rtyper/extfunc.py @@ -125,23 +125,6 @@ def _freeze_(self): return True -class genericcallable(object): - """ A way to specify the callable annotation, but deferred until - we have bookkeeper - """ - def __init__(self, args, result=None): - self.args = args - self.result = result - -class _ext_callable(ExtRegistryEntry): - _type_ = genericcallable - # we defer a bit annotation here - - def compute_result_annotation(self): - return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper) - for i in self.instance.args], - annotation(self.instance.result, self.bookkeeper)) - class ExtFuncEntry(ExtRegistryEntry): safe_not_sandboxed = False @@ -249,7 +232,7 @@ llfakeimpl, oofakeimpl: optional; if provided, they are called by the llinterpreter sandboxsafe: use True if the function performs no I/O (safe for --sandbox) """ - + if export_name is None: export_name = function.__name__ diff --git a/rpython/rtyper/lltypesystem/rgeneric.py b/rpython/rtyper/lltypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/lltypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.lltypesystem.lltype import Ptr, FuncType - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return Ptr(FuncType(l_args, l_retval)) diff --git a/rpython/rtyper/ootypesystem/rgeneric.py b/rpython/rtyper/ootypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/ootypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.ootypesystem import ootype - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return ootype.StaticMethod(l_args, l_retval) diff --git a/rpython/rtyper/rgeneric.py b/rpython/rtyper/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/rgeneric.py +++ /dev/null @@ -1,56 +0,0 @@ -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.rmodel import Repr -from rpython.rtyper.rpbc import AbstractFunctionsPBCRepr -from rpython.tool.pairtype import pairtype - - -class AbstractGenericCallableRepr(Repr): - def __init__(self, rtyper, s_generic): - self.rtyper = rtyper - self.s_generic = s_generic - self.args_r = [self.rtyper.getrepr(arg) for arg in s_generic.args_s] - self.r_result = self.rtyper.getrepr(s_generic.s_result) - self.lowleveltype = self.create_low_leveltype() - - def rtype_simple_call(self, hop): - return self.call('simple_call', hop) - - def rtype_call_args(self, hop): - return self.call('call_args', hop) - - def call(self, opname, hop): - vlist = hop.inputargs(self, *self.args_r) + [hop.inputconst(lltype.Void, None)] - hop.exception_is_here() - v_result = hop.genop('indirect_call', vlist, resulttype=self.r_result) - return v_result - - def convert_const(self, value): - bookkeeper = self.rtyper.annotator.bookkeeper - if value is None: - return self.rtyper.type_system.null_callable(self.lowleveltype) - r_func = self.rtyper.getrepr(bookkeeper.immutablevalue(value)) - return r_func.get_unique_llfn().value - - def _setup_repr(self): - for r in self.args_r: - r.setup() - self.r_result.setup() - -class __extend__(annmodel.SomeGenericCallable): - def rtyper_makerepr(self, rtyper): - return rtyper.type_system.rgeneric.GenericCallableRepr(rtyper, self) - - def rtyper_makekey(self): - return self.__class__, tuple([i.rtyper_makekey() for i in self.args_s]),\ - self.s_result.rtyper_makekey() - -class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractGenericCallableRepr)): - def convert_from_to((pbcrepr, gencallrepr), v, llops): - if pbcrepr.lowleveltype is lltype.Void: - r = gencallrepr.convert_const(pbcrepr.s_pbc.const) - r.setup() - return r - if pbcrepr.lowleveltype == gencallrepr.lowleveltype: - return v - return NotImplemented diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -1013,7 +1013,6 @@ from rpython.rtyper import rstr, rdict, rlist, rbytearray from rpython.rtyper import rclass, rbuiltin, rpbc from rpython.rtyper import rptr -from rpython.rtyper import rgeneric from rpython.rtyper import rweakref from rpython.rtyper import raddress # memory addresses from rpython.rtyper.ootypesystem import rootype diff --git a/rpython/rtyper/test/test_extfunc.py b/rpython/rtyper/test/test_extfunc.py --- a/rpython/rtyper/test/test_extfunc.py +++ b/rpython/rtyper/test/test_extfunc.py @@ -58,32 +58,6 @@ res = interpret(f, []) assert res == 7 - def test_callback(self): - """ - Verify annotation when a callback function is in the arguments list. - """ - def d(y): - return eval("y()") - - class DTestFuncEntry(ExtFuncEntry): - _about_ = d - name = 'd' - signature_args = [annmodel.SomeGenericCallable(args=[], result= - annmodel.SomeFloat())] - signature_result = annmodel.SomeFloat() - - def callback(): - return 2.5 - - def f(): - return d(callback) - - policy = AnnotatorPolicy() - a = RPythonAnnotator(policy=policy) - s = a.build_types(f, []) - assert isinstance(s, annmodel.SomeFloat) - assert a.translator._graphof(callback) - def test_register_external_signature(self): """ Test the standard interface for external functions. @@ -198,5 +172,5 @@ return os_execve(l) py.test.raises(Exception, a.build_types, g, [[str]]) a.build_types(g, [[str0]]) # Does not raise - + diff --git a/rpython/rtyper/test/test_rgeneric.py b/rpython/rtyper/test/test_rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/test/test_rgeneric.py +++ /dev/null @@ -1,47 +0,0 @@ -from rpython.rtyper.rtyper import RPythonTyper -from rpython.annotator import model as annmodel -from rpython.annotator.annrpython import RPythonAnnotator -from rpython.annotator import policy -from rpython.rtyper.test.test_llinterp import interpret, interpret_raises - -import py -from rpython.rtyper.test.tool import LLRtypeMixin, OORtypeMixin - -class BaseRGenericTest: - def test_some_generic_function_call(self): - def h(x): - return int(x) - - def c(x): - return int(x) + 1 - - def default(x): - return int(x) + 3 - - def g(a, x): - if x == -1: - a = None - if x > 0: - if x == 1: - a = h - else: - a = c - x = x + 0.01 - return a(x) - - def f(x): - return g(default, x) - - g._annenforceargs_ = policy.Sig(annmodel.SomeGenericCallable( - args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), - float) - - assert interpret(f, [1.]) == 1 - assert interpret(f, [10.]) == 11 - assert interpret(f, [-3.]) == 0 - -class TestLLRgeneric(BaseRGenericTest, LLRtypeMixin): - pass - -class TestOORgeneric(BaseRGenericTest, OORtypeMixin): - pass diff --git a/rpython/rtyper/typesystem.py b/rpython/rtyper/typesystem.py --- a/rpython/rtyper/typesystem.py +++ b/rpython/rtyper/typesystem.py @@ -21,7 +21,7 @@ except ImportError: return None if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist', - 'rslice', 'rdict', 'rrange', 'rstr', 'rgeneric', + 'rslice', 'rdict', 'rrange', 'rstr', 'll_str', 'rbuilder', 'rvirtualizable2', 'rbytearray', 'exceptiondata'): mod = load(name) @@ -50,7 +50,7 @@ def getcallabletype(self, ARGS, RESTYPE): cls = self.callable_trait[0] return cls(ARGS, RESTYPE) - + def getcallable(self, graph, getconcretetype=None): """Return callable given a Python function.""" if getconcretetype is None: @@ -59,7 +59,7 @@ lloutput = getconcretetype(graph.getreturnvar()) typ, constr = self.callable_trait - + FT = typ(llinputs, lloutput) name = graph.name if hasattr(graph, 'func') and callable(graph.func): @@ -138,7 +138,7 @@ if robj1.lowleveltype != robj2.lowleveltype: raise TyperError('is of instances of different pointer types: %r, %r' % ( roriginal1, roriginal2)) - + v_list = hop.inputargs(robj1, robj2) return hop.genop('ptr_eq', v_list, resulttype=lltype.Bool) @@ -177,7 +177,7 @@ robj2.lowleveltype is not ootype.Class): raise TyperError('is of instances of the non-instances: %r, %r' % ( roriginal1, roriginal2)) - + v_list = hop.inputargs(robj1, robj2) return hop.genop('oois', v_list, resulttype=lltype.Bool) From noreply at buildbot.pypy.org Wed Mar 13 03:21:27 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Mar 2013 03:21:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: explicitly run the signal handlers on RPY_LOCK_INTR in acquire_timed Message-ID: <20130313022127.A74561C13DD@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62327:e60b56f3fc81 Date: 2013-03-12 19:19 -0700 http://bitbucket.org/pypy/pypy/changeset/e60b56f3fc81/ Log: explicitly run the signal handlers on RPY_LOCK_INTR in acquire_timed diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -53,12 +53,14 @@ return microseconds -def acquire_timed(lock, microseconds): +def acquire_timed(space, lock, microseconds): """Helper to acquire an interruptible lock with a timeout.""" endtime = (time.time() * 1e6) + microseconds while True: result = lock.acquire_timed(microseconds) if result == RPY_LOCK_INTR: + # Run signal handlers if we were interrupted + space.getexecutioncontext().checksignals() if microseconds >= 0: microseconds = r_longlong(endtime - (time.time() * 1e6)) # Check for negative values, since those mean block @@ -89,7 +91,7 @@ and the return value reflects whether the lock is acquired. The blocking operation is interruptible.""" microseconds = parse_acquire_args(space, blocking, timeout) - result = acquire_timed(self.lock, microseconds) + result = acquire_timed(space, self.lock, microseconds) return space.newbool(result == RPY_LOCK_ACQUIRED) def descr_lock_release(self, space): @@ -201,7 +203,7 @@ if self.rlock_count > 0 or not self.lock.acquire(False): if not blocking: return space.w_False - r = acquire_timed(self.lock, microseconds) + r = acquire_timed(space, self.lock, microseconds) r = (r == RPY_LOCK_ACQUIRED) if r: assert self.rlock_count == 0 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 @@ -1,4 +1,5 @@ from __future__ import with_statement +import sys from pypy.module.thread.test.support import GenericTestThread from rpython.translator.c.test.test_genc import compile @@ -149,6 +150,9 @@ class AppTestLockSignals(GenericTestThread): + 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 @@ -186,3 +190,73 @@ def test_rlock_acquire_retries_on_intr(self): import _thread self.acquire_retries_on_intr(_thread.RLock()) + + def w_alarm_interrupt(self, sig, frame): + 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. + # XXX this test can fail when the legacy (non-semaphore) implementation + # of locks is used in thread_pthread.h, see issue #11223. + oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt) + try: + lock = _thread.allocate_lock() + lock.acquire() + signal.alarm(1) + t1 = time.time() + # XXX: raises doesn't work here? + #raises(KeyboardInterrupt, lock.acquire, timeout=5) + try: + lock.acquire(timeout=5) + except KeyboardInterrupt: + pass + else: + assert False, 'Expected KeyboardInterrupt' + dt = time.time() - t1 + # Checking that KeyboardInterrupt was raised is not sufficient. + # We want to assert that lock.acquire() was interrupted because + # of the signal, not that the signal handler was called immediately + # after timeout return of lock.acquire() (which can fool assertRaises). + assert dt < 3.0 + finally: + signal.signal(signal.SIGALRM, oldalrm) + + def test_rlock_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. + # XXX this test can fail when the legacy (non-semaphore) implementation + # of locks is used in thread_pthread.h, see issue #11223. + oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt) + try: + rlock = _thread.RLock() + # For reentrant locks, the initial acquisition must be in another + # thread. + def other_thread(): + rlock.acquire() + _thread.start_new_thread(other_thread, ()) + # Wait until we can't acquire it without blocking... + while rlock.acquire(blocking=False): + rlock.release() + time.sleep(0.01) + signal.alarm(1) + t1 = time.time() + #raises(KeyboardInterrupt, rlock.acquire, timeout=5) + try: + rlock.acquire(timeout=5) + except KeyboardInterrupt: + pass + else: + assert False, 'Expected KeyboardInterrupt' + dt = time.time() - t1 + # See rationale above in test_lock_acquire_interruption + assert dt < 3.0 + finally: + signal.signal(signal.SIGALRM, oldalrm) + From noreply at buildbot.pypy.org Wed Mar 13 16:19:31 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 16:19:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: fix typo Message-ID: <20130313151931.E1A8B1C0DC1@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r171:6a5caef9bb98 Date: 2013-03-13 16:18 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/6a5caef9bb98/ Log: fix typo diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -1014,7 +1014,7 @@ if self.sx + self.w > self.source_form.width: self.w = self.w - (self.sx + self.w - self.source_form.width) if self.sy < 0: - self.dy = self.dy - self.su + self.dy = self.dy - self.sy self.h = self.h + self.sy self.sy = 0 if self.sy + self.h > self.source_form.height: From noreply at buildbot.pypy.org Wed Mar 13 16:19:30 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 16:19:30 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Apply fixes from Smalltalk Message-ID: <20130313151930.BF94A1C0014@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r170:5c391af99cfc Date: 2013-03-13 15:29 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/5c391af99cfc/ Log: Apply fixes from Smalltalk diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -932,7 +932,7 @@ class BitBltShadow(AbstractCachingShadow): _attrs_ = [# From BitBlt - "dest_form", "source_form", "halftone_bits", + "dest_form", "source_form", "halftone_form", "combination_rule", "dest_x", "dest_y", "width", "height", "source_x", "source_y", "clip_x", "clip_y", "clip_width", "clip_height", "color_map", @@ -943,26 +943,36 @@ "n_words", "h_dir", "v_dir", "preload", "source_index", "dest_index", "source_delta", "dest_delta"] - RightMasks = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, - 1023, 2047, 4095, 8191, 16383, 32767, 65535] - AllOnes = 65535 + WordSize = 32 + RightMasks = [0] + for i in xrange(WordSize): + RightMasks.append((2 ** (i + 1)) - 1) + AllOnes = (2 ** WordSize) - 1 def sync_cache(self): - self.dest_form = self.fetch(0).as_form_get_shadow(self.space) + try: + self.dest_form = self.fetch(0).as_form_get_shadow(self.space) + except error.PrimitiveFailedError, e: + self.detach_shadow() + raise e w_source_form = self.fetch(1) if w_source_form is self.space.w_nil: - self.source_form = None + self.source_form = self.dest_form else: - self.source_form = w_source_form.as_form_get_shadow(self.space) + try: + self.source_form = w_source_form.as_form_get_shadow(self.space) + except error.PrimitiveFailedError, e: + self.detach_shadow() + raise e w_halftone_form = self.fetch(2) - if w_halftone_form is self.space.w_nil: + if w_halftone_form is not self.space.w_nil: + if isinstance(w_halftone_form, model.W_WordsObject): + # Already a bitmap + self.halftone_bits = w_halftone_form.words + else: + self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits + else: self.halftone_bits = None - elif isinstance(w_halftone_form, model.W_PointersObject): - self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits - elif isinstance(w_halftone_form, model.W_WordsObject): - self.halftone_bits = w_halftone_form.words - elif isinstance(w_halftone_form, model.W_BytesObject): - self.halftone_bits = [ord(byte) for byte in w_halftone_form.bytes] self.combination_rule = self.space.unwrap_int(self.fetch(3)) self.dest_x = self.space.unwrap_int(self.fetch(4)) self.dest_y = self.space.unwrap_int(self.fetch(5)) @@ -1001,36 +1011,35 @@ self.dx = self.dx - self.sx self.w = self.w + self.sx self.sx = 0 - if self.source_form and self.sx + self.w > self.source_form.width: + if self.sx + self.w > self.source_form.width: self.w = self.w - (self.sx + self.w - self.source_form.width) if self.sy < 0: self.dy = self.dy - self.su self.h = self.h + self.sy self.sy = 0 - if self.source_form and self.sy + self.h > self.source_form.height: + if self.sy + self.h > self.source_form.height: self.h = self.h - (self.sy + self.h - self.source_form.height) def compute_masks(self): self.dest_bits = self.dest_form.bits - self.dest_raster = (self.dest_form.width - 1) / 16 + 1 - if self.source_form: - self.source_bits = self.source_form.bits - self.source_raster = (self.source_form.width - 1) / 16 + 1 - self.skew = (self.sx - self.dx) & 15 - start_bits = 16 - (self.dx & 15) + self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize + 1 + self.source_bits = self.source_form.bits + self.source_raster = (self.source_form.width - 1) / BitBltShadow.WordSize + 1 + self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1) + start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize - 1)) self.mask1 = BitBltShadow.RightMasks[start_bits] - end_bits = 15 - ((self.dx + self.w - 1) & 15) + end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) & (BitBltShadow.WordSize - 1)) self.mask2 = ~BitBltShadow.RightMasks[end_bits] if self.skew == 0: self.skew_mask = 0 else: - self.skew_mask = BitBltShadow.RightMasks[16 - self.skew] + self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize - self.skew] if self.w < start_bits: self.mask1 = self.mask1 & self.mask2 self.mask2 = 0 self.n_words = 1 else: - self.n_words = (self.w - start_bits - 1) / 16 + 2 + self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize + 2 def check_overlap(self): self.h_dir = 1 @@ -1049,11 +1058,12 @@ self.mask1, self.mask2 = self.mask2, self.mask1 def calculate_offsets(self): - self.preload = self.source_form and self.skew_mask != 0 and self.skew <= (self.sx & 15) + self.preload = (self.skew_mask != 0 and + self.skew <= (self.sx & (BitBltShadow.WordSize - 1))) if self.h_dir < 0: self.preload = not self.preload - self.source_index = self.sy * self.source_raster + self.sx / 16 - self.dest_index = self.dy * self.dest_raster + self.dx / 16 + self.source_index = self.sy * self.source_raster + self.sx / BitBltShadow.WordSize + self.dest_index = self.dy * self.dest_raster + self.dx / BitBltShadow.WordSize self.source_delta = ((self.source_raster * self.v_dir - (self.n_words + (1 if self.preload else 0))) * @@ -1061,9 +1071,9 @@ self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir def copy_loop(self): - for i in xrange(self.h): + for i in xrange(self.h - 1): if self.halftone_bits: - halftone_word = self.halftone_bits[self.dy & 15] + halftone_word = self.halftone_bits[(self.dy & (BitBltShadow.WordSize - 1)) % len(self.halftone_bits)] self.dy = self.dy + self.v_dir else: halftone_word = BitBltShadow.AllOnes @@ -1074,14 +1084,13 @@ else: prev_word = 0 merge_mask = self.mask1 - for word in xrange(self.n_words): - if self.source_form: - prev_word = prev_word & self.skew_mask - this_word = self.source_bits[self.source_index] - skew_word = prev_word | (this_word & ~self.skew_mask) - prev_word = this_word - skew_word = (self.bit_shift(skew_word, self.skew) | - self.bit_shift(skew_word, self.skew - 16)) + for word in xrange(self.n_words - 1): + prev_word = prev_word & self.skew_mask + this_word = self.source_bits[self.source_index] + skew_word = prev_word | (this_word & ~self.skew_mask) + prev_word = this_word + skew_word = (self.bit_shift(skew_word, self.skew) | + self.bit_shift(skew_word, self.skew - 16)) merge_word = self.merge( skew_word & halftone_word, self.dest_bits[self.dest_index] @@ -1145,11 +1154,12 @@ _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] def sync_cache(self): - w_bits = self.fetch(0) - if isinstance(w_bits, model.W_WordsObject): - self.bits = w_bits.words + self.w_bits = self.fetch(0) + if isinstance(self.w_bits, model.W_WordsObject): + self.bits = self.w_bits.words else: - self.bits = [ord(byte) for byte in w_bits.bytes] + self.detach_shadow() + raise error.PrimitiveFailedError self.width = self.space.unwrap_int(self.fetch(1)) self.height = self.space.unwrap_int(self.fetch(2)) self.depth = self.space.unwrap_int(self.fetch(3)) @@ -1159,8 +1169,8 @@ self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) def replace_bits(self, bits): - w_bits = self.fetch(0) - if isinstance(bits, model.W_WordsObject): - w_bits.words[:] = bits + if isinstance(self.w_bits, model.W_WordsObject): + self.w_bits.words[:] = bits else: - w_bits.bytes[:] = [chr(byte) for byte in bits] + self.detach_shadow() + raise error.PrimitiveFailedError From noreply at buildbot.pypy.org Wed Mar 13 16:24:26 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 16:24:26 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: add primitive SMALLINT_AS_FLOAT Message-ID: <20130313152426.481B51C0498@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r172:140b20cc771d Date: 2013-03-13 16:23 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/140b20cc771d/ Log: add primitive SMALLINT_AS_FLOAT diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -249,6 +249,10 @@ FLOAT_LOG_N = 58 FLOAT_EXP = 59 + at expose_primitive(SMALLINT_AS_FLOAT, unwrap_spec=[int]) +def func(interp, s_frame, i): + return interp.space.wrap_float(float(i)) + math_ops = { FLOAT_ADD: operator.add, FLOAT_SUBTRACT: operator.sub, diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -167,6 +167,9 @@ prim_fails(primitives.BIT_SHIFT, [4, 29]) prim_fails(primitives.BIT_SHIFT, [4, 28]) +def test_smallint_as_float(): + assert prim(primitives.SMALLINT_AS_FLOAT, [12]).value == 12.0 + def test_float_add(): assert prim(primitives.FLOAT_ADD, [1.0,2.0]).value == 3.0 assert prim(primitives.FLOAT_ADD, [3.0,4.5]).value == 7.5 From noreply at buildbot.pypy.org Wed Mar 13 17:47:38 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 17:47:38 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) Floats are word objects, implement at: and at:put: Message-ID: <20130313164738.618B51C1045@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r173:fe9b2f9cab9e Date: 2013-03-13 17:09 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/fe9b2f9cab9e/ Log: (cfbolz, timfel) Floats are word objects, implement at: and at:put: diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -192,6 +192,35 @@ def clone(self, space): return self + def at0(self, space, index0): + return self.fetch(space, index0) + + def atput0(self, space, index0, w_value): + self.store(space, index0, w_value) + + def fetch(self, space, n0): + from rpython.rlib.rstruct.ieee import float_pack + r = float_pack(self.value, 8) # C double + if n0 == 0: + return space.wrap_uint(r_uint(intmask(r >> 32))) + else: + assert n0 == 1 + return space.wrap_uint(r_uint(intmask(r))) + + def store(self, space, n0, w_obj): + from rpython.rlib.rstruct.ieee import float_unpack, float_pack + from rpython.rlib.rarithmetic import r_ulonglong + + uint = r_ulonglong(space.unwrap_uint(w_obj)) + r = float_pack(self.value, 8) + if n0 == 0: + r = ((r << 32) >> 32) | (uint << 32) + else: + assert n0 == 1 + r = ((r >> 32) << 32) | uint + self.value = float_unpack(r, 8) + + class W_AbstractObjectWithIdentityHash(W_Object): """Object with explicit hash (ie all except small ints and floats).""" diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -178,7 +178,7 @@ return self.wrap_int(intmask(val)) except WrappingError: pass - # XXX is math allowed here? + # XXX this code sucks import math bytes_len = int(math.log(val) / math.log(0xff)) + 1 bytes_len = 4 if 4 > bytes_len else bytes_len diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -238,3 +238,21 @@ r = b.at0(space, 0) assert isinstance(r, model.W_BytesObject) assert r.size() == 4 + +def test_float_at(): + b = model.W_Float(64.0) + r = b.fetch(space, 0) + assert isinstance(r, model.W_BytesObject) + assert r.size() == 4 + assert r.bytes == [chr(0), chr(0), chr(80), chr(64)] + r = b.fetch(space, 1) + assert isinstance(r, model.W_SmallInteger) + assert r.value == 0 + +def test_float_at_put(): + target = model.W_Float(1.0) + for f in [1.0, -1.0, 1.1, 64.4, -0.0]: + source = model.W_Float(f) + target.store(space, 0, source.fetch(space, 0)) + target.store(space, 1, source.fetch(space, 1)) + assert target.value == f From noreply at buildbot.pypy.org Wed Mar 13 17:47:39 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 17:47:39 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) also test inf and nan Message-ID: <20130313164739.712201C1045@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r174:a82377298595 Date: 2013-03-13 17:11 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a82377298595/ Log: (cfbolz, timfel) also test inf and nan diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -1,4 +1,5 @@ import py +import math from spyvm import model, shadow from spyvm.shadow import MethodNotFound from spyvm import objspace, error @@ -251,8 +252,11 @@ def test_float_at_put(): target = model.W_Float(1.0) - for f in [1.0, -1.0, 1.1, 64.4, -0.0]: + for f in [1.0, -1.0, 1.1, 64.4, -0.0, float('nan'), float('inf')]: source = model.W_Float(f) target.store(space, 0, source.fetch(space, 0)) target.store(space, 1, source.fetch(space, 1)) - assert target.value == f + if math.isnan(f): + assert math.isnan(target.value) + else: + assert target.value == f From noreply at buildbot.pypy.org Wed Mar 13 17:47:40 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 17:47:40 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) read wordobjects that are floats into W_Float instances Message-ID: <20130313164740.8EDE91C1045@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r175:7354f483ac32 Date: 2013-03-13 17:42 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/7354f483ac32/ Log: (cfbolz, timfel) read wordobjects that are floats into W_Float instances diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -156,6 +156,12 @@ """Boxed float value.""" _attrs_ = ['value'] + def fillin_fromwords(self, space, high, low): + from rpython.rlib.rstruct.ieee import float_unpack + from rpython.rlib.rarithmetic import r_ulonglong + r = (r_ulonglong(high) << 32) | low + self.value = float_unpack(r, 8) + def __init__(self, value): self.value = value diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -461,9 +461,15 @@ def iswords(self): return self.format == 6 + def isfloat(self): + return self.iswords() and self.space.w_Float.is_same_object(self.g_class.w_object) + def ispointers(self): return self.format < 5 #TODO, what about compiled methods? + def iscompiledmethod(self): + return 12 <= self.format <= 15 + def init_w_object(self): """ 0 no fields 1 fixed fields only (all containing pointers) @@ -483,18 +489,20 @@ if self.w_object is None: # the instantiate call circumvents the constructors # and makes empty objects - if self.format < 5: + if self.ispointers(): # XXX self.format == 4 is weak self.w_object = objectmodel.instantiate(model.W_PointersObject) elif self.format == 5: raise CorruptImageError("Unknown format 5") - elif self.format == 6: + elif self.isfloat(): + self.w_object = objectmodel.instantiate(model.W_Float) + elif self.iswords(): self.w_object = objectmodel.instantiate(model.W_WordsObject) elif self.format == 7: raise CorruptImageError("Unknown format 7, no 64-bit support yet :-)") - elif 8 <= self.format <= 11: + elif self.isbytes(): self.w_object = objectmodel.instantiate(model.W_BytesObject) - elif 12 <= self.format <= 15: + elif self.iscompiledmethod(): self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" @@ -506,6 +514,8 @@ casted = self.w_object if isinstance(casted, model.W_PointersObject): self.fillin_pointersobject(casted) + elif isinstance(casted, model.W_Float): + self.fillin_floatobject(casted) elif isinstance(casted, model.W_WordsObject): self.fillin_wordsobject(casted) elif isinstance(casted, model.W_BytesObject): @@ -526,6 +536,15 @@ w_pointersobject.s_class = None w_pointersobject.hash = self.chunk.hash12 + def fillin_floatobject(self, w_floatobject): + from rpython.rlib.rarithmetic import r_uint + words = [r_uint(x) for x in self.chunk.data] + if len(words) != 2: + raise CorruptImageError("Expected 2 words in Float, got %d" % len(words)) + w_class = self.g_class.w_object + assert isinstance(w_class, model.W_PointersObject) + w_floatobject.fillin_fromwords(self.space, words[0], words[1]) + def fillin_wordsobject(self, w_wordsobject): from rpython.rlib.rarithmetic import r_uint w_wordsobject.words = [r_uint(x) for x in self.chunk.data] From noreply at buildbot.pypy.org Wed Mar 13 17:47:41 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 17:47:41 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: blackbox test that wrapping image floats in W_Float works Message-ID: <20130313164741.A05A81C1045@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r176:ecdc6623d046 Date: 2013-03-13 17:47 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ecdc6623d046/ Log: blackbox test that wrapping image floats in W_Float works diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -322,3 +322,10 @@ w_result = perform(w("someString"), "asSymbol") assert w_result is not None assert w_result.as_string() == "someString" + +def test_pi_as_w_float(): + import math + w_result = perform(interp.space.w_Float, "pi") + assert w_result is not None + assert isinstance(w_result, model.W_Float) + assert w_result.value == math.pi From noreply at buildbot.pypy.org Wed Mar 13 19:20:51 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 19:20:51 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: HACK this Message-ID: <20130313182051.1EA451C0DC1@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r178:0c991259daa1 Date: 2013-03-13 19:20 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0c991259daa1/ Log: HACK this diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -1075,7 +1075,7 @@ try: self.dest_form = self.fetch(0).as_form_get_shadow(self.space) except error.PrimitiveFailedError, e: - self.detach_shadow() + self.w_self()._shadow = None raise e w_source_form = self.fetch(1) if w_source_form is self.space.w_nil: @@ -1084,7 +1084,7 @@ try: self.source_form = w_source_form.as_form_get_shadow(self.space) except error.PrimitiveFailedError, e: - self.detach_shadow() + self.w_self()._shadow = None raise e w_halftone_form = self.fetch(2) if w_halftone_form is not self.space.w_nil: @@ -1280,7 +1280,7 @@ if isinstance(self.w_bits, model.W_WordsObject): self.bits = self.w_bits.words else: - self.detach_shadow() + self.w_self()._shadow = None raise error.PrimitiveFailedError self.width = self.space.unwrap_int(self.fetch(1)) self.height = self.space.unwrap_int(self.fetch(2)) @@ -1294,5 +1294,5 @@ if isinstance(self.w_bits, model.W_WordsObject): self.w_bits.words[:] = bits else: - self.detach_shadow() + self.w_self()._shadow = None raise error.PrimitiveFailedError From noreply at buildbot.pypy.org Wed Mar 13 19:20:49 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 13 Mar 2013 19:20:49 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: merge default Message-ID: <20130313182049.E1A4C1C0014@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r177:7a70b58eb720 Date: 2013-03-13 17:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/7a70b58eb720/ Log: merge default diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -290,12 +290,12 @@ s_method = receiverclassshadow.lookup(w_selector) # XXX catch MethodNotFound here and send doesNotUnderstand: # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. - if s_method.primitive: + code = s_method.primitive() + if code: # the primitive pushes the result (if any) onto the stack itself - code = s_method.primitive if interp.should_trace(): print "%sActually calling primitive %d" % (interp._last_indent, code,) - func = primitives.prim_table[code] + func = primitives.prim_holder.prim_table[code] try: # note: argcount does not include rcvr return func(interp, self, argcount) diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -156,6 +156,12 @@ """Boxed float value.""" _attrs_ = ['value'] + def fillin_fromwords(self, space, high, low): + from rpython.rlib.rstruct.ieee import float_unpack + from rpython.rlib.rarithmetic import r_ulonglong + r = (r_ulonglong(high) << 32) | low + self.value = float_unpack(r, 8) + def __init__(self, value): self.value = value @@ -192,6 +198,35 @@ def clone(self, space): return self + def at0(self, space, index0): + return self.fetch(space, index0) + + def atput0(self, space, index0, w_value): + self.store(space, index0, w_value) + + def fetch(self, space, n0): + from rpython.rlib.rstruct.ieee import float_pack + r = float_pack(self.value, 8) # C double + if n0 == 0: + return space.wrap_uint(r_uint(intmask(r >> 32))) + else: + assert n0 == 1 + return space.wrap_uint(r_uint(intmask(r))) + + def store(self, space, n0, w_obj): + from rpython.rlib.rstruct.ieee import float_unpack, float_pack + from rpython.rlib.rarithmetic import r_ulonglong + + uint = r_ulonglong(space.unwrap_uint(w_obj)) + r = float_pack(self.value, 8) + if n0 == 0: + r = ((r << 32) >> 32) | (uint << 32) + else: + assert n0 == 1 + r = ((r >> 32) << 32) | uint + self.value = float_unpack(r, 8) + + class W_AbstractObjectWithIdentityHash(W_Object): """Object with explicit hash (ie all except small ints and floats).""" @@ -221,11 +256,14 @@ class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash): """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" - _attrs_ = ['w_class'] + _attrs_ = ['w_class', 's_class'] + s_class = None def __init__(self, w_class): if w_class is not None: # it's None only for testing and space generation assert isinstance(w_class, W_PointersObject) + if w_class.has_shadow(): + self.s_class = w_class.as_class_get_shadow(w_class._shadow.space) self.w_class = w_class def getclass(self, space): @@ -236,11 +274,11 @@ return "<%s %s>" % (self.__class__.__name__, self) def __str__(self): - if isinstance(self, W_PointersObject) and self._shadow is not None: + if isinstance(self, W_PointersObject) and self.has_shadow(): return self._shadow.getname() else: name = None - if self.w_class._shadow is not None: + if self.w_class.has_shadow(): name = self.w_class._shadow.name return "a %s" % (name or '?',) @@ -250,18 +288,23 @@ def _become(self, w_other): self.w_class, w_other.w_class = w_other.w_class, self.w_class + self.s_class, w_other.s_class = w_other.s_class, self.s_class W_AbstractObjectWithIdentityHash._become(self, w_other) def has_class(self): return self.w_class is not None - + + def shadow_of_my_class(self, space): + if self.s_class is None: + self.s_class = self.w_class.as_class_get_shadow(space) + return self.s_class class W_PointersObject(W_AbstractObjectWithClassReference): """Common object.""" _attrs_ = ['_shadow', '_vars'] + + _shadow = None # Default value - _shadow = None # Default value - @jit.unroll_safe def __init__(self, w_class, size): """Create new object with size = fixed + variable size.""" @@ -269,6 +312,7 @@ vars = self._vars = [None] * size for i in range(size): # do it by hand for the JIT's sake vars[i] = w_nil + self._shadow = None # Default value def at0(self, space, index0): # To test, at0 = in varsize part @@ -279,7 +323,7 @@ self.store(space, index0 + self.instsize(space), w_value) def fetch(self, space, n0): - if self._shadow is not None: + if self.has_shadow(): return self._shadow.fetch(n0) return self._fetch(n0) @@ -287,7 +331,7 @@ return self._vars[n0] def store(self, space, n0, w_value): - if self._shadow is not None: + if self.has_shadow(): return self._shadow.store(n0, w_value) return self._store(n0, w_value) @@ -305,7 +349,7 @@ return self.varsize(space) def size(self): - if self._shadow is not None: + if self.has_shadow(): return self._shadow.size() return self._size() @@ -317,12 +361,13 @@ isinstance(self._vars, list)) def store_shadow(self, shadow): + assert self._shadow is None or self._shadow is shadow self._shadow = shadow @objectmodel.specialize.arg(2) def attach_shadow_of_class(self, space, TheClass): shadow = TheClass(space, self) - self._shadow = shadow + self.store_shadow(shadow) shadow.attach_shadow() return shadow @@ -331,9 +376,9 @@ shadow = self._shadow if not isinstance(shadow, TheClass): if shadow is not None: - shadow.detach_shadow() + raise DetachingShadowError(shadow, TheClass) shadow = self.attach_shadow_of_class(space, TheClass) - shadow.sync_shadow() + shadow.update() return shadow def get_shadow(self, space): @@ -369,6 +414,13 @@ from spyvm.shadow import CachedObjectShadow return self.as_special_get_shadow(space, CachedObjectShadow) + def as_observed_get_shadow(self, space): + from spyvm.shadow import ObserveeShadow + return self.as_special_get_shadow(space, ObserveeShadow) + + def has_shadow(self): + return self._shadow is not None + def as_bitblt_get_shadow(self, space): from spyvm.shadow import BitBltShadow return self.as_special_get_shadow(space, BitBltShadow) @@ -377,11 +429,16 @@ from spyvm.shadow import FormShadow return self.as_special_get_shadow(space, FormShadow) + def become(self, w_other): if not isinstance(w_other, W_PointersObject): return False self._vars, w_other._vars = w_other._vars, self._vars + # switching means also switching shadows self._shadow, w_other._shadow = w_other._shadow, self._shadow + # shadow links are in both directions -> also update shadows + if self.has_shadow(): self._shadow._w_self = self + if w_other.has_shadow(): w_other._shadow._w_self = w_other W_AbstractObjectWithClassReference._become(self, w_other) return True @@ -498,10 +555,11 @@ ### variables. The number of bytes used for this purpose is the value of ### the last byte in the method. - _shadow = None + _shadow = None # Default value _likely_methodname = "" def __init__(self, bytecount=0, header=0): + self._shadow = None self.setheader(header) self.bytes = ["\x00"] * bytecount @@ -516,7 +574,7 @@ self.header, w_other.header = w_other.header, self.header self.literalsize, w_other.literalsize = w_other.literalsize, self.literalsize self.islarge, w_other.islarge = w_other.islarge, self.islarge - self._shadow = w_other._shadow = None + self._shadow, w_other._shadow = w_other._shadow, self._shadow W_AbstractObjectWithIdentityHash._become(self, w_other) return True @@ -602,12 +660,13 @@ """NOT RPYTHON Only for testing""" self.literals = literals - self._shadow = None + if self.has_shadow(): + self._shadow.update() def setbytes(self, bytes): self.bytes = bytes - def as_compiledmethod_get_shadow(self, space): + def as_compiledmethod_get_shadow(self, space=None): from shadow import CompiledMethodShadow if self._shadow is None: self._shadow = CompiledMethodShadow(self) @@ -625,7 +684,8 @@ self.setheader(header) else: self.literals[index0-1] = w_value - self._shadow = None + if self.has_shadow(): + self._shadow.update() def store(self, space, index0, w_v): self.atput0(space, index0, w_v) @@ -658,7 +718,16 @@ def setchar(self, index0, character): assert index0 >= 0 self.bytes[index0] = character - self._shadow = None + if self.has_shadow(): + self._shadow.update() + + def has_shadow(self): + return self._shadow is not None + +class DetachingShadowError(Exception): + def __init__(self, old_shadow, new_shadow_class): + self.old_shadow = old_shadow + self.new_shadow_class = new_shadow_class # Use black magic to create w_nil without running the constructor, # thus allowing it to be used even in the constructor of its own diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -53,11 +53,8 @@ w_Class = self.classtable["w_Class"] w_Metaclass = self.classtable["w_Metaclass"] # XXX - proto_shadow = instantiate(shadow.ClassShadow) - proto_shadow.space = self - proto_shadow.invalid = False - proto_shadow.w_superclass = w_Class - w_ProtoObjectClass.store_shadow(proto_shadow) + proto_shadow = w_ProtoObjectClass._shadow + proto_shadow.store_w_superclass(w_Class) # at this point, all classes that still lack a w_class are themselves # metaclasses for nm, w_cls_obj in self.classtable.items(): @@ -181,7 +178,7 @@ return self.wrap_int(intmask(val)) except WrappingError: pass - # XXX is math allowed here? + # XXX this code sucks import math bytes_len = int(math.log(val) / math.log(0xff)) + 1 bytes_len = 4 if 4 > bytes_len else bytes_len @@ -296,13 +293,15 @@ # XXX s = instantiate(shadow.ClassShadow) s.space = space + s.version = shadow.Version() s._w_self = w_class - s.w_superclass = w_superclass + s.subclass_s = {} + s._s_superclass = None + s.store_w_superclass(w_superclass) s.name = name - s.instance_size = instsize + s._instance_size = instsize s.instance_kind = format - s.w_methoddict = None + s._s_methoddict = None s.instance_varsized = varsized or format != shadow.POINTERS - s.invalid = False w_class.store_shadow(s) return w_class diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -35,6 +35,12 @@ # Squeak has primitives all the way up to 575 # So all optional primitives will default to the bytecode implementation prim_table = [make_failing(i) for i in range(576)] + +class PrimitiveHolder(object): + _immutable_fields_ = ["prim_table[*]"] + +prim_holder = PrimitiveHolder() +prim_holder.prim_table = prim_table # clean up namespace: del i prim_table_implemented_only = [] @@ -243,6 +249,10 @@ FLOAT_LOG_N = 58 FLOAT_EXP = 59 + at expose_primitive(SMALLINT_AS_FLOAT, unwrap_spec=[int]) +def func(interp, s_frame, i): + return interp.space.wrap_float(float(i)) + math_ops = { FLOAT_ADD: operator.add, FLOAT_SUBTRACT: operator.sub, @@ -653,6 +663,7 @@ raise PrimitiveFailedError() w_rcvr.w_class = w_arg.w_class + w_rcvr.s_class = w_arg.s_class # ___________________________________________________________________________ # Miscellaneous Primitives (120-127) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -3,6 +3,16 @@ from rpython.tool.pairtype import extendabletype from rpython.rlib import rarithmetic, jit +def make_elidable_after_versioning(func): + @jit.elidable + def elidable_func(self, version, *args): + return func(self, *args) + def meth(self, *args): + jit.promote(self) + version = jit.promote(self.version) + return elidable_func(self, version, *args) + return meth + class AbstractShadow(object): """A shadow is an optional extra bit of information that can be attached at run-time to any Smalltalk object. @@ -23,40 +33,37 @@ def getname(self): return repr(self) def attach_shadow(self): pass - def detach_shadow(self): pass - def sync_shadow(self): pass - + def update(self): pass + class AbstractCachingShadow(AbstractShadow): + _immutable_fields_ = ['version?'] _attr_ = [] def __init__(self, space, w_self): AbstractShadow.__init__(self, space, w_self) + self.version = Version() - def detach_shadow(self): - self.invalidate_shadow() + def attach_shadow(self): + self.w_self().store_shadow(self) + self.update() - def invalidate_shadow(self): + def update(self): """This should get called whenever the base Smalltalk object changes.""" - self._w_self.store_shadow(None) - - def attach_shadow(self): - self.update_shadow() - - def sync_shadow(self): - pass - - def update_shadow(self): - self.w_self().store_shadow(self) self.sync_cache() def sync_cache(self): raise NotImplementedError() def store(self, n0, w_value): - self.invalidate_shadow() AbstractShadow.store(self, n0, w_value) + self.update() + def change(self): + self.version = Version() + +class Version: + pass # ____________________________________________________________ POINTERS = 0 @@ -77,71 +84,87 @@ (i.e. used as the class of another Smalltalk object). """ - _immutable_fields_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"] + _attr_ = ["name", "_instance_size", "instance_varsized", "instance_kind", + "_s_methoddict", "_s_superclass", "subclass_s"] - name = None def __init__(self, space, w_self): - self.name = "" + # fields added here should also be in objspace.py:56ff, 300ff + self.name = '' + self._s_superclass = None + self.subclass_s = {} AbstractCachingShadow.__init__(self, space, w_self) def getname(self): return "%s class" % (self.name or '?',) def sync_cache(self): + from spyvm.objspace import UnwrappingError "Update the ClassShadow with data from the w_self class." w_self = self.w_self() + if w_self.size() == 0: + return + # read and painfully decode the format - classformat = self.space.unwrap_int( - w_self._fetch(constants.CLASS_FORMAT_INDEX)) - # The classformat in Squeak, as an integer value, is: - # <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec> - # <6 bits=instSize\\64><1 bit=0> - # In Slang the value is read directly as a boxed integer, so that - # the code gets a "pointer" whose bits are set as above, but - # shifted one bit to the left and with the lowest bit set to 1. + try: + classformat = self.space.unwrap_int( + w_self._fetch(constants.CLASS_FORMAT_INDEX)) + # The classformat in Squeak, as an integer value, is: + # <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec> + # <6 bits=instSize\\64><1 bit=0> + # In Slang the value is read directly as a boxed integer, so that + # the code gets a "pointer" whose bits are set as above, but + # shifted one bit to the left and with the lowest bit set to 1. - # compute the instance size (really the size, not the number of bytes) - instsize_lo = (classformat >> 1) & 0x3F - instsize_hi = (classformat >> (9 + 1)) & 0xC0 - self.instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr - # decode the instSpec - format = (classformat >> 7) & 15 - self.instance_varsized = format >= 2 - if format < 4: - self.instance_kind = POINTERS - elif format == 4: - self.instance_kind = WEAK_POINTERS - elif format == 6: - self.instance_kind = WORDS - if self.instance_size != 0: - raise ClassShadowError("can't have both words and a non-zero " - "base instance size") - elif 8 <= format <= 11: - self.instance_kind = BYTES - if self.instance_size != 0: - raise ClassShadowError("can't have both bytes and a non-zero " - "base instance size") - elif 12 <= format <= 15: - self.instance_kind = COMPILED_METHOD - else: - raise ClassShadowError("unknown format %d" % (format,)) + # compute the instance size (really the size, not the number of bytes) + instsize_lo = (classformat >> 1) & 0x3F + instsize_hi = (classformat >> (9 + 1)) & 0xC0 + self._instance_size = (instsize_lo | instsize_hi) - 1 # subtract hdr + # decode the instSpec + format = (classformat >> 7) & 15 + self.instance_varsized = format >= 2 + if format < 4: + self.instance_kind = POINTERS + elif format == 4: + self.instance_kind = WEAK_POINTERS + elif format == 6: + self.instance_kind = WORDS + if self.instsize() != 0: + raise ClassShadowError("can't have both words and a non-zero " + "base instance size") + elif 8 <= format <= 11: + self.instance_kind = BYTES + if self.instsize() != 0: + raise ClassShadowError("can't have both bytes and a non-zero " + "base instance size") + elif 12 <= format <= 15: + self.instance_kind = COMPILED_METHOD + else: + raise ClassShadowError("unknown format %d" % (format,)) + except UnwrappingError: + assert w_self._fetch(constants.CLASS_FORMAT_INDEX) is self.space.w_nil + pass # not enough information stored in w_self, yet self.guess_class_name() # read the methoddict w_methoddict = w_self._fetch(constants.CLASS_METHODDICT_INDEX) assert isinstance(w_methoddict, model.W_PointersObject) - self.w_methoddict = w_methoddict + if not w_methoddict.is_same_object(self.space.w_nil): + self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space) + self._s_methoddict.s_class = self w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX) if w_superclass.is_same_object(self.space.w_nil): - self.w_superclass = None + self._s_superclass = None else: assert isinstance(w_superclass, model.W_PointersObject) - self.w_superclass = w_superclass + self.store_w_superclass(w_superclass) + self.changed() def guess_class_name(self): + if self.name != '': + return self.name w_self = self.w_self() w_name = None @@ -164,11 +187,14 @@ if isinstance(w_name, model.W_BytesObject): self.name = w_name.as_string() + else: + self.name = None + self.changed() def new(self, extrasize=0): w_cls = self.w_self() if self.instance_kind == POINTERS: - w_new = model.W_PointersObject(w_cls, self.instance_size+extrasize) + w_new = model.W_PointersObject(w_cls, self.instsize()+extrasize) elif self.instance_kind == WORDS: w_new = model.W_WordsObject(w_cls, extrasize) elif self.instance_kind == BYTES: @@ -179,13 +205,16 @@ raise NotImplementedError(self.instance_kind) return w_new + def w_methoddict(self): + return self.w_self()._fetch(constants.CLASS_METHODDICT_INDEX) + def s_methoddict(self): - return jit.promote(self.w_methoddict.as_methoddict_get_shadow(self.space)) + return self._s_methoddict def s_superclass(self): - if self.w_superclass is None: + if self._s_superclass is None: return None - return self.w_superclass.as_class_get_shadow(self.space) + return self._s_superclass # _______________________________________________________________ # Methods for querying the format word, taken from the blue book: @@ -207,13 +236,64 @@ " True if instances of this class have data stored as numerical bytes " return self.format == BYTES + @make_elidable_after_versioning def isvariable(self): " True if instances of this class have indexed inst variables " return self.instance_varsized + @make_elidable_after_versioning def instsize(self): " Number of named instance variables for each instance of this class " - return self.instance_size + return self._instance_size + + def store_w_superclass(self, w_class): + if w_class is None: + self._s_superclass = None + else: + s_scls = w_class.as_class_get_shadow(self.space) + if self._s_superclass is s_scls: + return + elif (self._s_superclass is not None + and self._s_superclass is not s_scls): + self._s_superclass.detach_s_class(self) + self._s_superclass = s_scls + self._s_superclass.attach_s_class(self) + + def attach_s_class(self, s_other): + self.subclass_s[s_other] = None + + def detach_s_class(self, s_other): + del self.subclass_s[s_other] + + def changed(self): + self.superclass_changed(Version()) + + # this is done, because the class-hierarchy contains cycles + def superclass_changed(self, version): + if self.version is not version: + self.version = version + for s_class in self.subclass_s: + s_class.superclass_changed(version) + + # _______________________________________________________________ + # Methods for querying the format word, taken from the blue book: + + def __repr__(self): + return "" % (self.name or '?',) + + @make_elidable_after_versioning + def lookup(self, w_selector): + look_in_shadow = self + while look_in_shadow is not None: + s_method = look_in_shadow.s_methoddict().find_selector(w_selector) + if s_method is not None: + return s_method + look_in_shadow = look_in_shadow._s_superclass + raise MethodNotFound(self, w_selector) + + + # _______________________________________________________________ + # Methods used only in testing def inherits_from(self, s_superclass): classshadow = self @@ -224,51 +304,58 @@ else: return False - # _______________________________________________________________ - # Methods for querying the format word, taken from the blue book: - - def __repr__(self): - return "" % (self.name or '?',) - - @jit.unroll_safe - def lookup(self, w_selector): - look_in_shadow = self - jit.promote(w_selector) - while look_in_shadow is not None: - w_method = look_in_shadow.s_methoddict().find_selector(w_selector) - if w_method is not None: - return w_method.as_compiledmethod_get_shadow(self.space) - look_in_shadow = look_in_shadow.s_superclass() - raise MethodNotFound(self, w_selector) - def initialize_methoddict(self): "NOT_RPYTHON" # this is only for testing. - if self.w_methoddict is None: - self.w_methoddict = model.W_PointersObject(None, 2) - self.w_methoddict._store(1, model.W_PointersObject(None, 0)) - self.s_methoddict().invalid = False + if self._s_methoddict is None: + w_methoddict = model.W_PointersObject(None, 2) + w_methoddict._store(1, model.W_PointersObject(None, 0)) + self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space) + self.s_methoddict().sync_cache() + self.s_methoddict().invalid = False def installmethod(self, w_selector, w_method): "NOT_RPYTHON" # this is only for testing. assert not isinstance(w_selector, str) self.initialize_methoddict() - self.s_methoddict().methoddict[w_selector] = w_method + s_method = w_method.as_compiledmethod_get_shadow(self.space) + self.s_methoddict().methoddict[w_selector] = s_method if isinstance(w_method, model.W_CompiledMethod): - method = w_method.as_compiledmethod_get_shadow(self.space) - method.w_compiledin = self.w_self() + s_method.w_compiledin = self.w_self() -class MethodDictionaryShadow(AbstractCachingShadow): +class MethodDictionaryShadow(AbstractShadow): - @jit.elidable + _immutable_fields_ = ['invalid?', 's_class'] + _attr_ = ['methoddict'] + + def __init__(self, space, w_self): + self.invalid = True + self.s_class = None + self.methoddict = {} + AbstractShadow.__init__(self, space, w_self) + def find_selector(self, w_selector): + assert not self.invalid return self.methoddict.get(w_selector, None) + def update(self): return self.sync_cache() + + # Remove update call for changes to ourselves: + # Whenever a method is added, it's keyword is added to w_self, then the + # w_compiled_method is added to our observee. + # Sync_cache at this point would not have the desired effect, because in + # the Smalltalk Implementation, the dictionary changes first. Afterwards + # its contents array is filled with the value belonging to the new key. + def store(self, n0, w_value): + AbstractShadow.store(self, n0, w_value) + self.invalid = True + def sync_cache(self): + if self.w_self().size() == 0: + return w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX) assert isinstance(w_values, model.W_PointersObject) - s_values = w_values.get_shadow(self.space) - # XXX Should add! - # s_values.notifyinvalid(self) + s_values = w_values.as_observed_get_shadow(self.space) + s_values.notify(self) size = self.w_self().size() - constants.METHODDICT_NAMES_INDEX self.methoddict = {} for i in range(size): @@ -278,11 +365,16 @@ raise ClassShadowError("bogus selector in method dict") w_compiledmethod = w_values._fetch(i) if not isinstance(w_compiledmethod, model.W_CompiledMethod): - raise ClassShadowError("the methoddict must contain " - "CompiledMethods only for now") - self.methoddict[w_selector] = w_compiledmethod + raise ClassShadowError("The methoddict must contain " + "CompiledMethods only, for now. " + "If the value observed is nil, our " + "invalidating mechanism may be broken.") + self.methoddict[w_selector] = w_compiledmethod.as_compiledmethod_get_shadow(self.space) selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector + if self.s_class: + self.s_class.changed() + self.invalid = False class AbstractRedirectingShadow(AbstractShadow): @@ -310,12 +402,12 @@ self.copy_from_w_self(i) w_self._vars = None - def detach_shadow(self): - w_self = self.w_self() - assert isinstance(w_self, model.W_PointersObject) - w_self._vars = [self.space.w_nil] * self._w_self_size - for i in range(self._w_self_size): - self.copy_to_w_self(i) + # def detach_shadow(self): + # w_self = self.w_self() + # assert isinstance(w_self, model.W_PointersObject) + # w_self._vars = [self.space.w_nil] * self._w_self_size + # for i in range(self._w_self_size): + # self.copy_to_w_self(i) def copy_from_w_self(self, n0): self.store(n0, self.w_self()._fetch(n0)) @@ -485,7 +577,7 @@ def getbytecode(self): jit.promote(self._pc) assert self._pc >= 0 - bytecode = self.s_method().bytecode[self._pc] + bytecode = self.s_method().getbytecode(self._pc) currentBytecode = ord(bytecode) self._pc += 1 return currentBytecode @@ -579,7 +671,7 @@ if self._w_self is not None: return self._w_self else: - size = self.size() - self.space.w_MethodContext.as_class_get_shadow(self.space).instance_size + size = self.size() - self.space.w_MethodContext.as_class_get_shadow(self.space).instsize() space = self.space w_self = space.w_MethodContext.as_class_get_shadow(space).new(size) w_self.store_shadow(self) @@ -711,12 +803,8 @@ @jit.unroll_safe def make_context(space, s_method, w_receiver, arguments, s_sender=None, closure=None, pc=0): - # From blue book: normal mc have place for 12 temps+maxstack - # mc for methods with islarge flag turned on 32 - size = (12 + s_method.islarge * 20 + s_method.argsize - + space.w_MethodContext.as_class_get_shadow(space).instance_size) - # The last summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self. - + # The summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self. + size = s_method.compute_frame_size() + space.w_MethodContext.as_class_get_shadow(space).instsize() s_new_context = MethodContextShadow(space, None) s_new_context._w_self_size = size s_new_context_non_fresh = s_new_context # XXX: find a better solution to translation err @@ -777,7 +865,7 @@ def tempsize(self): if not self.is_closure_context(): - return self.s_method().tempsize + return self.s_method().tempsize() else: return wrapper.BlockClosureWrapper(self.space, self.w_closure_or_nil).tempsize() @@ -854,20 +942,44 @@ ) class CompiledMethodShadow(object): - _immutable_fields_ = ["_w_self", "bytecode", - "literals[*]", "bytecodeoffset", - "literalsize", "tempsize", "primitive", - "argsize", "islarge", - "w_compiledin"] + _attr_ = ["_w_self", "bytecode", + "literals[*]", "bytecodeoffset", + "literalsize", "tempsize", "primitive", + "argsize", "islarge", + "w_compiledin"] + _immutable_fields_ = ["version?", "_w_self"] def __init__(self, w_compiledmethod): self._w_self = w_compiledmethod + self.update() + + def w_self(self): + return self._w_self + + @make_elidable_after_versioning + def getliteral(self, index): + return self.literals[index] + + @make_elidable_after_versioning + def compute_frame_size(self): + # From blue book: normal mc have place for 12 temps+maxstack + # mc for methods with islarge flag turned on 32 + return 12 + self.islarge * 20 + self.argsize + + def getliteralsymbol(self, index): + w_literal = self.getliteral(index) + assert isinstance(w_literal, model.W_BytesObject) + return w_literal.as_string() # XXX performance issue here + + def update(self): + w_compiledmethod = self._w_self + self.version = Version() self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() self.literalsize = w_compiledmethod.getliteralsize() - self.tempsize = w_compiledmethod.gettempsize() - self.primitive = w_compiledmethod.primitive + self._tempsize = w_compiledmethod.gettempsize() + self._primitive = w_compiledmethod.primitive self.argsize = w_compiledmethod.argsize self.islarge = w_compiledmethod.islarge @@ -884,16 +996,13 @@ association = wrapper.AssociationWrapper(None, w_association) self.w_compiledin = association.value() - def w_self(self): - return self._w_self + @make_elidable_after_versioning + def tempsize(self): + return self._tempsize - def getliteral(self, index): - return self.literals[index] - - def getliteralsymbol(self, index): - w_literal = self.getliteral(index) - assert isinstance(w_literal, model.W_BytesObject) - return w_literal.as_string() # XXX performance issue here + @make_elidable_after_versioning + def primitive(self): + return self._primitive def create_frame(self, space, receiver, arguments, sender = None): assert len(arguments) == self.argsize @@ -901,15 +1010,11 @@ space, self, receiver, arguments, sender) return s_new -class Version: - pass + @make_elidable_after_versioning + def getbytecode(self, pc): + return self.bytecode[pc] class CachedObjectShadow(AbstractCachingShadow): - _immutable_fields_ = ['version?'] - - def __init__(self, space, w_self): - AbstractCachingShadow.__init__(self, space, w_self) - self.version = Version() def fetch(self, n0): jit.promote(self) @@ -926,8 +1031,25 @@ self.version = Version() return self._w_self._store(n0, w_value) - def update_shadow(self): - self.version = Version() + def update(self): pass + + +class ObserveeShadow(AbstractShadow): + _attr_ = ['dependent'] + def __init__(self, space, w_self): + AbstractShadow.__init__(self, space, w_self) + self.dependent = None + + def store(self, n0, w_value): + AbstractShadow.store(self, n0, w_value) + self.dependent.update() + + def notify(self, dependent): + if self.dependent is not None and dependent is not self.dependent: + raise RuntimeError('Meant to be observed by only one value, so far') + self.dependent = dependent + + def update(self): pass class BitBltShadow(AbstractCachingShadow): diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -227,6 +227,7 @@ self.init_g_objects() self.init_w_objects() self.fillin_w_objects() + self.synchronize_shadows() def read_version(self): # 1 word version @@ -300,6 +301,12 @@ for chunk in self.chunks.itervalues(): chunk.g_object.fillin_w_object() + def synchronize_shadows(self): + for chunk in self.chunks.itervalues(): + casted = chunk.g_object.w_object + if isinstance(casted, model.W_PointersObject) and casted.has_shadow(): + casted._shadow.update() + def init_compactclassesarray(self): """ from the blue book (CompiledMethod Symbol Array PseudoContext LargePositiveInteger nil MethodDictionary Association Point Rectangle nil TranslatedMethod BlockContext MethodContext nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) """ special = self.chunks[self.specialobjectspointer] @@ -454,9 +461,15 @@ def iswords(self): return self.format == 6 + def isfloat(self): + return self.iswords() and self.space.w_Float.is_same_object(self.g_class.w_object) + def ispointers(self): return self.format < 5 #TODO, what about compiled methods? + def iscompiledmethod(self): + return 12 <= self.format <= 15 + def init_w_object(self): """ 0 no fields 1 fixed fields only (all containing pointers) @@ -476,24 +489,23 @@ if self.w_object is None: # the instantiate call circumvents the constructors # and makes empty objects - if self.format < 5: + if self.ispointers(): # XXX self.format == 4 is weak self.w_object = objectmodel.instantiate(model.W_PointersObject) elif self.format == 5: raise CorruptImageError("Unknown format 5") - elif self.format == 6: + elif self.isfloat(): + self.w_object = objectmodel.instantiate(model.W_Float) + elif self.iswords(): self.w_object = objectmodel.instantiate(model.W_WordsObject) elif self.format == 7: raise CorruptImageError("Unknown format 7, no 64-bit support yet :-)") - elif 8 <= self.format <= 11: + elif self.isbytes(): self.w_object = objectmodel.instantiate(model.W_BytesObject) - elif 12 <= self.format <= 15: + elif self.iscompiledmethod(): self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" - else: - #XXX invalidate shadow here - pass return self.w_object def fillin_w_object(self): @@ -502,6 +514,8 @@ casted = self.w_object if isinstance(casted, model.W_PointersObject): self.fillin_pointersobject(casted) + elif isinstance(casted, model.W_Float): + self.fillin_floatobject(casted) elif isinstance(casted, model.W_WordsObject): self.fillin_wordsobject(casted) elif isinstance(casted, model.W_BytesObject): @@ -515,15 +529,22 @@ def fillin_pointersobject(self, w_pointersobject): assert self.pointers is not None - # XXX is the following needed? - if w_pointersobject._shadow is not None: - w_pointersobject._shadow.detach_shadow() w_pointersobject._vars = [g_object.w_object for g_object in self.pointers] w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) w_pointersobject.w_class = w_class + w_pointersobject.s_class = None w_pointersobject.hash = self.chunk.hash12 + def fillin_floatobject(self, w_floatobject): + from rpython.rlib.rarithmetic import r_uint + words = [r_uint(x) for x in self.chunk.data] + if len(words) != 2: + raise CorruptImageError("Expected 2 words in Float, got %d" % len(words)) + w_class = self.g_class.w_object + assert isinstance(w_class, model.W_PointersObject) + w_floatobject.fillin_fromwords(self.space, words[0], words[1]) + def fillin_wordsobject(self, w_wordsobject): from rpython.rlib.rarithmetic import r_uint w_wordsobject.words = [r_uint(x) for x in self.chunk.data] diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -58,7 +58,7 @@ image = create_testimage(space) interp = interpreter.Interpreter(space, image) - w_selector = interp.perform(space.wrap_string('loopTest3'), "asSymbol") + w_selector = interp.perform(space.wrap_string('loopTest2'), "asSymbol") assert isinstance(w_selector, model.W_BytesObject) def interp_w(): interp.perform(model.W_SmallInteger(1000), w_selector) diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -7,7 +7,9 @@ tools.setup_module(tools, filename='bootstrapped.image') def find_symbol_in_methoddict_of(string, s_class): - methoddict_w = s_class.s_methoddict().methoddict + s_methoddict = s_class.s_methoddict() + s_methoddict.sync_cache() + methoddict_w = s_methoddict.methoddict for each in methoddict_w.keys(): if each.as_string() == string: return each @@ -55,4 +57,4 @@ sends = perform(w(5), 'benchFib') t1 = time.time() t = t1 - t0 - print str(tools.space.unwrap_int(sends)/t) + " sends per second" \ No newline at end of file + print str(tools.space.unwrap_int(sends)/t) + " sends per second" diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -62,7 +62,8 @@ assert space.w_nil._shadow is None for (w_class, _, _, methname) in methods: s_class = w_class.as_class_get_shadow(space) - del s_class.s_methoddict().methoddict[fakesymbol(methname)] + s_class.update() + s_class.s_methoddict().update() def fakesymbol(s, _cache={}): try: @@ -427,7 +428,7 @@ assert s_active_context.w_sender() == w_frame assert s_active_context.stack() == [] assert w_active_context.as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) - assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) + assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo].w_self()) assert s_frame.stack() == [] step_in_interp(s_active_context) w_active_context = step_in_interp(s_active_context) @@ -598,7 +599,7 @@ s_frame.push(space.w_one) w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) - assert w_active_context.as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] + assert w_active_context.as_methodcontext_get_shadow(space).s_method() == shadow.s_methoddict().methoddict[w_symbol] assert s_active_context.w_receiver() is w_object assert w_active_context.as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) assert s_active_context.stack() == [] @@ -659,7 +660,7 @@ assert s_active_context.stack() == [] assert w_active_context.as_methodcontext_get_shadow(space).w_receiver() == w_object meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict[foo] - assert s_active_context.w_method() == meth + assert s_active_context.w_method() == meth.w_self() assert s_caller_context.stack() == [] def test_secondExtendedSendBytecode(): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -270,7 +270,7 @@ perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) w_result = perform(w(10), "testBecome") assert space.unwrap_int(w_result) == 42 - + def perform(w_receiver, selector, *arguments_w): return interp.perform(w_receiver, selector, *arguments_w) @@ -282,6 +282,22 @@ assert isinstance(s_ctx, shadow.MethodContextShadow) assert s_ctx.top().is_same_object(space.w_true) +def test_cached_methoddict(): + py.test.skip('Should test the same as test_shadow.test_cached_methoddict, as long ' + 'as the implementation of MethodDictionary>>#at:put does not change.') + sourcecode = """fib + ^self < 2 + ifTrue: [ 1 ] + ifFalse: [ ((self - 1) fib + (self - 2) fib) + 1 ]""" + perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) + assert perform(w(5), "fib").is_same_object(w(15)) + sourcecode = """fib + ^self < 2 + ifTrue: [ 1 ] + ifFalse: [ (self - 1) fib + (self - 2) fib ]""" + perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) + assert perform(w(10), "fib").is_same_object(w(89)) + def test_step_run_something(): from spyvm.test import test_miniimage setup_module(test_miniimage, filename='running-something-mini.image') @@ -306,3 +322,10 @@ w_result = perform(w("someString"), "asSymbol") assert w_result is not None assert w_result.as_string() == "someString" + +def test_pi_as_w_float(): + import math + w_result = perform(interp.space.w_Float, "pi") + assert w_result is not None + assert isinstance(w_result, model.W_Float) + assert w_result.value == math.pi diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -1,4 +1,5 @@ import py +import math from spyvm import model, shadow from spyvm.shadow import MethodNotFound from spyvm import objspace, error @@ -213,7 +214,9 @@ res = w_clsa.become(w_clsb) assert res assert w_clsa.as_class_get_shadow(space) is s_clsb + assert s_clsa._w_self is w_clsb assert w_clsb.as_class_get_shadow(space) is s_clsa + assert s_clsb._w_self is w_clsa def test_word_atput(): i = model.W_SmallInteger(100) @@ -236,3 +239,24 @@ r = b.at0(space, 0) assert isinstance(r, model.W_BytesObject) assert r.size() == 4 + +def test_float_at(): + b = model.W_Float(64.0) + r = b.fetch(space, 0) + assert isinstance(r, model.W_BytesObject) + assert r.size() == 4 + assert r.bytes == [chr(0), chr(0), chr(80), chr(64)] + r = b.fetch(space, 1) + assert isinstance(r, model.W_SmallInteger) + assert r.value == 0 + +def test_float_at_put(): + target = model.W_Float(1.0) + for f in [1.0, -1.0, 1.1, 64.4, -0.0, float('nan'), float('inf')]: + source = model.W_Float(f) + target.store(space, 0, source.fetch(space, 0)) + target.store(space, 1, source.fetch(space, 1)) + if math.isnan(f): + assert math.isnan(target.value) + else: + assert target.value == f diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -167,6 +167,9 @@ prim_fails(primitives.BIT_SHIFT, [4, 29]) prim_fails(primitives.BIT_SHIFT, [4, 28]) +def test_smallint_as_float(): + assert prim(primitives.SMALLINT_AS_FLOAT, [12]).value == 12.0 + def test_float_add(): assert prim(primitives.FLOAT_ADD, [1.0,2.0]).value == 3.0 assert prim(primitives.FLOAT_ADD, [3.0,4.5]).value == 7.5 diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -1,5 +1,5 @@ import random -from spyvm import model, shadow, constants +from spyvm import model, shadow, constants, interpreter from spyvm import objspace space = objspace.ObjSpace() @@ -42,6 +42,7 @@ w_class.store(space, constants.CLASS_FORMAT_INDEX, space.wrap_int(format)) if name is not None: w_class.store(space, constants.CLASS_NAME_INDEX, space.wrap_string(name)) + w_class.as_class_get_shadow(space).s_methoddict().sync_cache() return w_class def basicshape(name, format, kind, varsized, instsize): @@ -72,7 +73,7 @@ methoddict = classshadow.s_methoddict().methoddict assert len(methods) == len(methoddict) for w_key, value in methoddict.items(): - assert methods[w_key.as_string()] is value + assert methods[w_key.as_string()].as_compiledmethod_get_shadow(space) is value def method(tempsize=3,argsize=2, bytes="abcde"): w_m = model.W_CompiledMethod() @@ -152,32 +153,24 @@ assert s_object.getbytecode() == 101 assert s_object.s_home() == s_object -def test_attach_detach_mc(): +def test_attach_mc(): w_m = method() w_object = methodcontext(pc=13, method=w_m) old_vars = w_object._vars s_object = w_object.as_methodcontext_get_shadow(space) assert w_object._vars is None - s_object.detach_shadow() - assert w_object._vars == old_vars - assert w_object._vars is not old_vars -def test_attach_detach_bc(): +def test_attach_bc(): w_object = blockcontext(pc=13) old_vars = w_object._vars s_object = w_object.as_blockcontext_get_shadow(space) assert w_object._vars is None - s_object.detach_shadow() - assert w_object._vars == old_vars - assert w_object._vars is not old_vars def test_replace_to_bc(): w_object = blockcontext(pc=13) old_vars = w_object._vars s_object = w_object.as_blockcontext_get_shadow(space) - s_object.detach_shadow() - s_classshadow = shadow.ClassShadow(space, w_object) - w_object._shadow = s_classshadow + s_object._shadow = None s_newobject = w_object.as_blockcontext_get_shadow(space) assert ([s_newobject.fetch(i) for i in range(s_newobject.size())] == [s_object.fetch(i) for i in range(s_newobject.size())]) @@ -193,20 +186,17 @@ assert shadow.bytecode == "abc" assert shadow.bytecodeoffset == 12 assert shadow.literalsize == 8 # 12 - 4byte header - assert shadow.tempsize == 1 + assert shadow.tempsize() == 1 w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) - assert w_compiledmethod._shadow is None - - shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) + assert w_compiledmethod._shadow is not None assert shadow.literals == [17, 41] w_compiledmethod.atput0(space, 14, space.wrap_int(ord("x"))) - assert w_compiledmethod._shadow is None - shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abx" + assert shadow is w_compiledmethod.as_compiledmethod_get_shadow(space) def test_cached_object_shadow(): w_o = space.wrap_list([0, 1, 2, 3, 4, 5, 6, 7]) @@ -216,4 +206,71 @@ assert w_o.at0(space, i) == i w_o.atput0(space, 0, 8) assert version is not s_o.version - assert w_o.at0(space, 0) == 8 \ No newline at end of file + assert w_o.at0(space, 0) == 8 + +def test_observee_shadow(): + notified = False + class Observer(): + def __init__(self): self.notified = False + def update(self): self.notified = True + o = Observer() + w_o = w_Array.as_class_get_shadow(space).new(1) + w_o.as_observed_get_shadow(space).notify(o) + assert not o.notified + w_o.store(space, 0, 1) + assert o.notified + assert w_o.fetch(space, 0) == 1 + try: + w_o._shadow.notify(Observer()) + except RuntimeError: + pass + else: + assert False + +def test_cached_methoddict(): + # create a methoddict + foo = model.W_CompiledMethod(0) + bar = model.W_CompiledMethod(0) + baz = model.W_CompiledMethod(0) + methods = {'foo': foo, + 'bar': bar} + w_class = build_smalltalk_class("Demo", 0x90, methods=methods) + s_class = w_class.as_class_get_shadow(space) + s_methoddict = s_class.s_methoddict() + s_methoddict.sync_cache() + i = 0 + key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) + while key is space.w_nil: + key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) + i = i + 1 + + assert (s_class.lookup(key) is foo.as_compiledmethod_get_shadow(space) + or s_class.lookup(key) is bar.as_compiledmethod_get_shadow(space)) + # change that entry + w_array = s_class.w_methoddict()._fetch(constants.METHODDICT_VALUES_INDEX) + version = s_class.version + w_array.atput0(space, i, baz) + + assert s_class.lookup(key) is baz.as_compiledmethod_get_shadow(space) + assert version is not s_class.version + +def test_updating_class_changes_subclasses(): + w_parent = build_smalltalk_class("Demo", 0x90, + methods={'bar': model.W_CompiledMethod(0)}) + w_class = build_smalltalk_class("Demo", 0x90, + methods={'foo': model.W_CompiledMethod(0)}, w_superclass=w_parent) + s_class = w_class.as_class_get_shadow(space) + version = s_class.version + + w_method = model.W_CompiledMethod(0) + key = space.wrap_string('foo') + + s_md = w_parent.as_class_get_shadow(space).s_methoddict() + s_md.sync_cache() + w_ary = s_md._w_self._fetch(constants.METHODDICT_VALUES_INDEX) + s_md._w_self.atput0(space, 0, key) + w_ary.atput0(space, 0, w_method) + + assert s_class.lookup(key) is w_method.as_compiledmethod_get_shadow(space) + assert s_class.version is not version + assert s_class.version is w_parent.as_class_get_shadow(space).version diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -53,9 +53,3 @@ return model.W_SmallInteger(rerased.erase_int(val)) except OverflowError: raise WrappingError("integer too large to fit into a tagged pointer") - -make classes - - -Unclarities: -[ ] should image loading invalidate the shadows of the precreated objects? \ No newline at end of file From noreply at buildbot.pypy.org Wed Mar 13 19:22:29 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Mar 2013 19:22:29 +0100 (CET) Subject: [pypy-commit] pypy py3k: bring over another skip from the default branch Message-ID: <20130313182229.5E8821C0014@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62328:bdd3b8dbd909 Date: 2013-03-13 11:21 -0700 http://bitbucket.org/pypy/pypy/changeset/bdd3b8dbd909/ Log: bring over another skip from the default branch diff --git a/lib-python/3/test/test_pyexpat.py b/lib-python/3/test/test_pyexpat.py --- a/lib-python/3/test/test_pyexpat.py +++ b/lib-python/3/test/test_pyexpat.py @@ -2,6 +2,7 @@ # handler, are obscure and unhelpful. from io import BytesIO +import sys import unittest from xml.parsers import expat @@ -584,6 +585,9 @@ self.assertEqual(self.n, 4) class MalformedInputTest(unittest.TestCase): + # CPython seems to ship its own version of expat, they fixed it on this commit : + # http://svn.python.org/view?revision=74429&view=revision + @unittest.skipIf(sys.platform == "darwin", "Expat is broken on Mac OS X 10.6.6") def test1(self): xml = "\0\r\n" parser = expat.ParserCreate() @@ -593,6 +597,7 @@ except expat.ExpatError as e: self.assertEqual(str(e), 'unclosed token: line 2, column 0') + @unittest.skipIf(sys.platform == "darwin", "Expat is broken on Mac OS X 10.6.6") def test2(self): xml = "\r\n" parser = expat.ParserCreate() From noreply at buildbot.pypy.org Wed Mar 13 22:51:51 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Mar 2013 22:51:51 +0100 (CET) Subject: [pypy-commit] pypy stm-gc-2: Major collections Message-ID: <20130313215151.A323B1C0DC1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-gc-2 Changeset: r62329:91ac440ae883 Date: 2013-03-11 11:16 -0700 http://bitbucket.org/pypy/pypy/changeset/91ac440ae883/ Log: Major collections From noreply at buildbot.pypy.org Wed Mar 13 22:51:53 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Mar 2013 22:51:53 +0100 (CET) Subject: [pypy-commit] pypy stm-gc-2: Start Message-ID: <20130313215153.182391C1045@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-gc-2 Changeset: r62330:0346dc75e7e5 Date: 2013-03-11 11:21 -0700 http://bitbucket.org/pypy/pypy/changeset/0346dc75e7e5/ Log: Start diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -3,10 +3,6 @@ ------------------------------------------------------------ -after an abort, keep old global_to_local and access it using special code - ------------------------------------------------------------- - GC: major collections; call __del__() ------------------------------------------------------------ diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py --- a/rpython/memory/gc/stmgc.py +++ b/rpython/memory/gc/stmgc.py @@ -184,7 +184,7 @@ from rpython.memory.gc import stmshared self.stm_operations = stm_operations self.nursery_size = nursery_size - self.maximum_extra_threshold = 0 + #self.maximum_extra_threshold = 0 self.sharedarea = stmshared.StmGCSharedArea(self) # def _stm_duplicate(obj): # indirection to hide 'self' @@ -351,11 +351,11 @@ # ---------- # set_extra_threshold support - def set_extra_threshold(self, reserved_size): - if reserved_size > self.maximum_extra_threshold: - self.maximum_extra_threshold = reserved_size - stmtls = self.get_tls() - stmtls.set_extra_threshold(reserved_size) +## def set_extra_threshold(self, reserved_size): +## if reserved_size > self.maximum_extra_threshold: +## self.maximum_extra_threshold = reserved_size +## stmtls = self.get_tls() +## stmtls.set_extra_threshold(reserved_size) # ---------- # id() and identityhash() support diff --git a/rpython/memory/gc/stmtls.py b/rpython/memory/gc/stmtls.py --- a/rpython/memory/gc/stmtls.py +++ b/rpython/memory/gc/stmtls.py @@ -37,17 +37,21 @@ self.AddressStack = self.gc.AddressStack self.AddressDict = self.gc.AddressDict # - # --- current position and end of nursery, or NULL when - # mallocs are forbidden + # --- current position, or NULL when mallocs are forbidden self.nursery_free = NULL - self.nursery_top = NULL self.nursery_pending_clear = 0 # --- the start and size of the nursery belonging to this thread. # never changes. - self.nursery_size = self.gc.nursery_size - self.nursery_start = self._alloc_nursery(self.nursery_size) - self.extra_threshold = 0 - self.set_extra_threshold(self.gc.maximum_extra_threshold) + self.nursery_size = self.gc.nursery_size # fixed + self.nursery_start = self._alloc_nursery(self.nursery_size) # fixed + self.nursery_stop = self.nursery_start + self.nursery_size # fixed + #self.extra_threshold = 0 + #self.set_extra_threshold(self.gc.maximum_extra_threshold) + # + # --- current nursery top: usually equal to nursery_stop, except + # when doing a major collection, when the thread that initiates + # it changes all nursery_top of other threads + self.nursery_top = self.nursery_stop # # --- a thread-local allocator for the shared area from rpython.memory.gc.stmshared import StmGCThreadLocalAllocator @@ -111,19 +115,18 @@ ll_assert(bool(self.nursery_free), "disable_mallocs: already disabled") self.nursery_pending_clear = self.nursery_free - self.nursery_start self.nursery_free = NULL - self.nursery_top = NULL # ---------- # set_extra_threshold support - def set_extra_threshold(self, reserved_size): - diff = reserved_size - self.extra_threshold - if self.nursery_top != NULL: - if diff > 0 and self.nursery_free + diff > self.nursery_top: - self.local_collection() - self.nursery_top -= diff - self.nursery_size -= diff - self.extra_threshold += diff +## def set_extra_threshold(self, reserved_size): +## diff = reserved_size - self.extra_threshold +## if self.nursery_top != NULL: +## if diff > 0 and self.nursery_free + diff > self.nursery_top: +## self.local_collection() +## self.nursery_top -= diff +## self.nursery_size -= diff +## self.extra_threshold += diff # ------------------------------------------------------------ @@ -144,7 +147,6 @@ if clear_size > 0: llarena.arena_reset(self.nursery_start, clear_size, 2) self.nursery_free = self.nursery_start - self.nursery_top = self.nursery_start + self.nursery_size # At this point, all visible objects are GLOBAL, but newly # malloced objects will be LOCAL. if self.gc.DEBUG: @@ -275,7 +277,7 @@ def is_in_nursery(self, addr): ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0, "odd-valued (i.e. tagged) pointer unexpected here") - return self.nursery_start <= addr < self.nursery_top + return self.nursery_start <= addr < self.nursery_stop def fresh_new_weakref(self, obj): self.local_weakrefs.append(obj) @@ -621,7 +623,7 @@ ll_assert(bool(pointing_to), "weakref to NULL in local_weakrefs") cat = self.categorize_object(pointing_to, can_be_in_nursery=True) if cat == 0: - # the weakref points to a dying object; no need to rememeber it + # the weakref points to a dying object; no need to remember it (obj + offset).address[0] = llmemory.NULL else: # the weakref points to an object that stays alive diff --git a/rpython/translator/stm/test/targetdemo2.py b/rpython/translator/stm/test/targetdemo2.py --- a/rpython/translator/stm/test/targetdemo2.py +++ b/rpython/translator/stm/test/targetdemo2.py @@ -219,8 +219,15 @@ # run! try: args.run() - finally: - rthread.gc_thread_die() + except Exception, e: + # argh + try: + print "Got an exception from bootstrap()" + if not we_are_translated(): + print e.__class__.__name__, e + except Exception: + pass + rthread.gc_thread_die() @staticmethod def acquire(args): From noreply at buildbot.pypy.org Wed Mar 13 22:51:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Mar 2013 22:51:54 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the stack wasting (does not fix the stack issue I believe) Message-ID: <20130313215154.4EDEC1C13DD@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62331:3b3c923bd6f6 Date: 2013-03-13 14:50 -0700 http://bitbucket.org/pypy/pypy/changeset/3b3c923bd6f6/ Log: fix the stack wasting (does not fix the stack issue I believe) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1118,11 +1118,6 @@ n = len(arglocs) for i in range(start, n): loc = arglocs[i] - if isinstance(loc, RegLoc): - if loc.is_xmm: - stack_depth += 2 - else: - stack_depth += 1 stack_depth += loc.get_width() // WORD if stack_depth > stack_max: align = align_stack_words(stack_depth - stack_max) From noreply at buildbot.pypy.org Wed Mar 13 23:43:04 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 13 Mar 2013 23:43:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed the problem of performing methods which are primitives with PERFORM_WITH_ARGS Message-ID: <20130313224304.88EAE1C0498@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r179:603a4040803a Date: 2013-03-13 21:17 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/603a4040803a/ Log: fixed the problem of performing methods which are primitives with PERFORM_WITH_ARGS diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -990,18 +990,19 @@ raise PrimitiveFailedError() @expose_primitive(PERFORM_WITH_ARGS, - unwrap_spec=[object, object, object], - result_is_new_frame=True) -def func(interp, s_frame, w_rcvr, w_sel, w_args): - s_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) - assert s_method + unwrap_spec=[object, object, list], + no_result=True) +def func(interp, s_frame, w_rcvr, w_selector, args_w): + stackvalues = s_frame.pop_and_return_n(3) + argcount = len(args_w) + s_frame.push(w_rcvr) + s_frame.push_all(args_w) + try: + s_frame._sendSelector(w_selector, argcount, interp, + w_rcvr, w_rcvr.shadow_of_my_class(interp.space)) + finally: + s_frame.push_all(stackvalues) - s_new_frame = s_method.create_frame( - interp.space, w_rcvr, - [w_args.fetch(interp.space, i) for i in range(w_args.size())]) - - s_new_frame.store_w_sender(s_frame.w_self()) - return s_new_frame @expose_primitive(SIGNAL, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -298,6 +298,20 @@ perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) assert perform(w(10), "fib").is_same_object(w(89)) +def test_primitive_perform_with_args(): + from spyvm.test.test_primitives import prim + from spyvm import primitives + w_o = space.wrap_list([1, 2, 3]) + w_methoddict = w_o.shadow_of_my_class(space)._s_superclass._s_superclass.w_methoddict() + w_methoddict.as_methoddict_get_shadow(space).sync_cache() + selectors_w = w_methoddict._shadow.methoddict.keys() + w_sel = None + for sel in selectors_w: + if sel.as_string() == 'size': + w_sel = sel + size = prim(primitives.PERFORM_WITH_ARGS, [w_o, w_sel, []]) + assert size.value == 3 + def test_step_run_something(): from spyvm.test import test_miniimage setup_module(test_miniimage, filename='running-something-mini.image') diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -13,7 +13,7 @@ class MockFrame(model.W_PointersObject): def __init__(self, stack): - self._vars = [None] * 6 + stack + self._vars = [None] * 6 + stack + [space.w_nil] * 6 s_self = self.as_blockcontext_get_shadow() s_self.init_stack_and_temps() s_self.reset_stack() From noreply at buildbot.pypy.org Wed Mar 13 23:43:05 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 13 Mar 2013 23:43:05 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: merge with default Message-ID: <20130313224305.B97AA1C0498@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: bitblt Changeset: r180:dc3227c288ed Date: 2013-03-13 21:28 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/dc3227c288ed/ Log: merge with default diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -1006,18 +1006,19 @@ raise PrimitiveFailedError() @expose_primitive(PERFORM_WITH_ARGS, - unwrap_spec=[object, object, object], - result_is_new_frame=True) -def func(interp, s_frame, w_rcvr, w_sel, w_args): - s_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) - assert s_method + unwrap_spec=[object, object, list], + no_result=True) +def func(interp, s_frame, w_rcvr, w_selector, args_w): + stackvalues = s_frame.pop_and_return_n(3) + argcount = len(args_w) + s_frame.push(w_rcvr) + s_frame.push_all(args_w) + try: + s_frame._sendSelector(w_selector, argcount, interp, + w_rcvr, w_rcvr.shadow_of_my_class(interp.space)) + finally: + s_frame.push_all(stackvalues) - s_new_frame = s_method.create_frame( - interp.space, w_rcvr, - [w_args.fetch(interp.space, i) for i in range(w_args.size())]) - - s_new_frame.store_w_sender(s_frame.w_self()) - return s_new_frame @expose_primitive(SIGNAL, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -298,6 +298,20 @@ perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None)) assert perform(w(10), "fib").is_same_object(w(89)) +def test_primitive_perform_with_args(): + from spyvm.test.test_primitives import prim + from spyvm import primitives + w_o = space.wrap_list([1, 2, 3]) + w_methoddict = w_o.shadow_of_my_class(space)._s_superclass._s_superclass.w_methoddict() + w_methoddict.as_methoddict_get_shadow(space).sync_cache() + selectors_w = w_methoddict._shadow.methoddict.keys() + w_sel = None + for sel in selectors_w: + if sel.as_string() == 'size': + w_sel = sel + size = prim(primitives.PERFORM_WITH_ARGS, [w_o, w_sel, []]) + assert size.value == 3 + def test_step_run_something(): from spyvm.test import test_miniimage setup_module(test_miniimage, filename='running-something-mini.image') diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -13,7 +13,7 @@ class MockFrame(model.W_PointersObject): def __init__(self, stack): - self._vars = [None] * 6 + stack + self._vars = [None] * 6 + stack + [space.w_nil] * 6 s_self = self.as_blockcontext_get_shadow() s_self.init_stack_and_temps() s_self.reset_stack() From noreply at buildbot.pypy.org Wed Mar 13 23:58:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Mar 2013 23:58:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: apply another obscure workaround from default (c1a2ac377ca4) Message-ID: <20130313225858.083391C0014@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62332:8510cb5ffeb9 Date: 2013-03-13 15:57 -0700 http://bitbucket.org/pypy/pypy/changeset/8510cb5ffeb9/ Log: apply another obscure workaround from default (c1a2ac377ca4) diff --git a/lib-python/3/test/test_io.py b/lib-python/3/test/test_io.py --- a/lib-python/3/test/test_io.py +++ b/lib-python/3/test/test_io.py @@ -2844,6 +2844,31 @@ """Check that a partial write, when it gets interrupted, properly invokes the signal handler, and bubbles up the exception raised in the latter.""" + + # XXX This test has three flaws that appear when objects are + # XXX not reference counted. + + # - if wio.write() happens to trigger a garbage collection, + # the signal exception may be raised when some __del__ + # method is running; it will not reach the assertRaises() + # call. + + # - more subtle, if the wio object is not destroyed at once + # and survives this function, the next opened file is likely + # to have the same fileno (since the file descriptor was + # actively closed). When wio.__del__ is finally called, it + # will close the other's test file... To trigger this with + # CPython, try adding "global wio" in this function. + + # - This happens only for streams created by the _pyio module, + # because a wio.close() that fails still consider that the + # file needs to be closed again. You can try adding an + # "assert wio.closed" at the end of the function. + + # Fortunately, a little gc.gollect() seems to be enough to + # work around all these issues. + support.gc_collect() + read_results = [] def _read(): s = os.read(r, 1) From noreply at buildbot.pypy.org Thu Mar 14 01:42:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 14 Mar 2013 01:42:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: (arigo, alex, fijal) try to fix the alignment (how this could have worked) Message-ID: <20130314004231.B767D1C0498@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r62333:d736ec9b08e9 Date: 2013-03-13 17:42 -0700 http://bitbucket.org/pypy/pypy/changeset/d736ec9b08e9/ Log: (arigo, alex, fijal) try to fix the alignment (how this could have worked) diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -30,9 +30,9 @@ # start of every frame: the saved value of some registers if WORD == 4: - # ebp + ebx + esi + edi + 12 extra words + return address = 17 words - FRAME_FIXED_SIZE = 17 - PASS_ON_MY_FRAME = 12 + # ebp + ebx + esi + edi + 14 extra words + return address = 19 words + FRAME_FIXED_SIZE = 19 + PASS_ON_MY_FRAME = 14 JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float else: # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19 From noreply at buildbot.pypy.org Thu Mar 14 02:14:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Mar 2013 02:14:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: (fijal, alex, hodgestar, arigo) Message-ID: <20130314011425.D10B61C0498@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r62334:b8d923271ff2 Date: 2013-03-14 02:13 +0100 http://bitbucket.org/pypy/pypy/changeset/b8d923271ff2/ Log: (fijal, alex, hodgestar, arigo) A test for alignment of x86 stack across a CALL operation. diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -19,7 +19,8 @@ class FakeStats(object): pass -class TestCallingConv(Runner): + +class CallingConvTests(Runner): type_system = 'lltype' Ptr = lltype.Ptr FuncType = lltype.FuncType @@ -371,3 +372,57 @@ 'float', descr=calldescr) expected = func(*argvalues) assert abs(res.getfloat() - expected) < 0.0001 + + + def make_function_returning_stack_pointer(self): + raise NotImplementedError + + def get_alignment_requirements(self): + raise NotImplementedError + + def test_call_aligned_explicit_check(self): + cpu = self.cpu + if not cpu.supports_floats: + py.test.skip('requires floats') + + func_addr = self.make_function_returning_stack_pointer() + + F = lltype.Float + I = lltype.Signed + floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] + ints = [7, 11, 23, 13, -42, 1111, 95, 1] + for case in range(256): + args = [] + funcargs = [] + float_count = 0 + int_count = 0 + for i in range(8): + if case & (1< Author: Armin Rigo Branch: jitframe-on-heap Changeset: r62335:d55895010d2f Date: 2013-03-14 02:13 +0100 http://bitbucket.org/pypy/pypy/changeset/d55895010d2f/ Log: merge heads diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -30,9 +30,9 @@ # start of every frame: the saved value of some registers if WORD == 4: - # ebp + ebx + esi + edi + 12 extra words + return address = 17 words - FRAME_FIXED_SIZE = 17 - PASS_ON_MY_FRAME = 12 + # ebp + ebx + esi + edi + 14 extra words + return address = 19 words + FRAME_FIXED_SIZE = 19 + PASS_ON_MY_FRAME = 14 JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float else: # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19 diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1118,11 +1118,6 @@ n = len(arglocs) for i in range(start, n): loc = arglocs[i] - if isinstance(loc, RegLoc): - if loc.is_xmm: - stack_depth += 2 - else: - stack_depth += 1 stack_depth += loc.get_width() // WORD if stack_depth > stack_max: align = align_stack_words(stack_depth - stack_max) From noreply at buildbot.pypy.org Thu Mar 14 18:04:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Mar 2013 18:04:37 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: Add my abstract. Message-ID: <20130314170437.9075C1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4953:add47fd491cd Date: 2013-03-14 10:04 -0700 http://bitbucket.org/pypy/extradoc/changeset/add47fd491cd/ Log: Add my abstract. diff --git a/talk/pycon2013/abstract_arigo.rst b/talk/pycon2013/abstract_arigo.rst new file mode 100644 --- /dev/null +++ b/talk/pycon2013/abstract_arigo.rst @@ -0,0 +1,42 @@ +PyPy without the GIL +==================== + +Description +----------- + +PyPy has a version without the Global Interpreter Lock (GIL). It can run +multiple threads concurrently. But the real benefit is that you have +other, new ways of using all your cores. In this talk I will describe +how it is possible (STM) and then focus on some of these new +opportunities, e.g. show how we used multiple cores in a single really +big program without adding thread locks everywhere. + +Abstract +-------- + +PyPy has a version without the Global Interpreter Lock (GIL). It can run +multiple threads concurrently. Internally, this is possible thanks to +Software Transactional Memory (STM). But the real benefit is that STM +gives other, new ways of using all your cores. + +In this talk I will describe the basics of STM which make it possible, +and give a word about the upcoming Hardware Transactional Memory. I will +then focus on some of these new opportunities. Indeed, PyPy can run a +single multi-threaded program using multiple cores --- but using threads +in the first place is a brittle endeavour, even in Python (even if not +as much as in lower-level languages). You have to carefully use implicit +or explicit locking, at one level or another, and in a large program, +each missing lock equals to one rare non-reproducible bug. + +With STM, other options arise naturally if you can control the length of +each "transaction". I will show a small library that uses threads +internally, but in which each thread executes a series of (large) +transactions. This gives a very clean high-level view that seems to have +no concurrency at all, while internally running transactions in +parallel. + +Obviously this is not a silver bullet: usually, you still have to work +on debugging your program. But the program is always correct, and you +fight efficiency bugs --- as opposed to the regular multi-threaded +model, where the program is always efficient, but you fight correctness +bugs. From noreply at buildbot.pypy.org Thu Mar 14 19:23:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 14 Mar 2013 19:23:11 +0100 (CET) Subject: [pypy-commit] pypy default: update some more paths for vendor-rename Message-ID: <20130314182311.545ED1C13E3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62336:3f578eb93744 Date: 2013-03-14 14:22 -0400 http://bitbucket.org/pypy/pypy/changeset/3f578eb93744/ Log: update some more paths for vendor-rename diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -23,7 +23,7 @@ leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. """ - return sys.version[:3] + return sys.version[0] def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): diff --git a/lib-python/2/sysconfig.py b/lib-python/2/sysconfig.py --- a/lib-python/2/sysconfig.py +++ b/lib-python/2/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python/{py_version_short}', - 'platstdlib': '{base}/lib-python/{py_version_short}', - 'purelib': '{base}/lib-python/{py_version_short}', - 'platlib': '{base}/lib-python/{py_version_short}', + 'stdlib': '{base}/lib-python/{py_version}', + 'platstdlib': '{base}/lib-python/{py_version}', + 'purelib': '{base}/lib-python/{py_version}', + 'platlib': '{base}/lib-python/{py_version}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', From noreply at buildbot.pypy.org Thu Mar 14 19:24:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Mar 2013 19:24:56 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: In-progress Message-ID: <20130314182456.5BC561C13E3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4954:1eae9d7ddf7f Date: 2013-03-14 11:24 -0700 http://bitbucket.org/pypy/extradoc/changeset/1eae9d7ddf7f/ Log: In-progress diff --git a/talk/pycon2013/pypy_without_gil.txt b/talk/pycon2013/pypy_without_gil.txt new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil.txt @@ -0,0 +1,140 @@ +==================== +PyPy without the GIL +==================== + +Intro +--------------------------- + +- PyPy intro + +- thanks to contributors for STM + + + +Demo +--------------------------- + +- demo: ~/br/stm-thread-2/64compiled/pypy-c-r61735+-stm + + * run some random multithreaded program + + +- missing in pypy-stm: + + * GC major collection + * JIT + * some more optimizations possible (= tons of) + + +- __pypy__.thread.atomic + + * with atomic: + print "hello", username + + * the illusion of serialization + + +Lower level: STM +--------------------------- + +- pypy and not cpython? + + +- STM = Software Transactional Memory + + +- Basic idea: each thread runs in parallel, but everything it does is + in a series of "transactions" + + +- A transaction keeps all changes to pre-existing memory "local" + + +- The changes are made visible only when the transaction "commits" + + +- The transaction will "abort" if a conflict is detected, and + it will be transparently retried + + +- Non-reversible operations like I/O turn the transaction "inevitable" + and stop progress in the other threads + + +- __pypy__.thread.last_abort_info() -> traceback-like information + + +- (GC-supported structure: when we want to modify a pre-existing object, + we first copy it into "local" memory, and when we commit, it becomes + the newer version of the old pre-existing object; we end up with a + chained list of versions, and we have to make sure we always use the + latest one. We rely on GC major collections to free them eventually.) + + +- alternative: HTM...? + + +Higher level: not threads +--------------------------- + + +- based on (and fully compatible with) threads + + * existing multithreaded programs work + + +- but opens up unexpected alternatives + + * we can run multiple threads but at the same time use ``atomic`` + + * with the GIL-based idea of ``atomic`` it doesn't make sense: + we have multiple threads but they're all using ``atomic``, i.e. + only one at a time will ever run... except no :-) + + +- transaction.py + + * demo + + * illusion of serial execution: can "sanely" reason about algorithms + + * "Conflict tracebacks" + + * Might need to debug them --- but they are performance bugs, not + correctness bugs + + * The idea is that we fix only XX% of the bugs and we are done + + * Maybe some new "performance debugger" tools might help us too + + +- TigerQuoll, 1st March: same idea with JavaScript (for servers) + + * various models possible: + + . events dispatchers + + . futures + + . map/reduce, scatter/gather + + +- Event dispatchers + + * twisted, tulip, etc. + + * run the event dispatcher in one thread (e.g. the main thread), + and schedule the actual events to run on a different thread from + a pool + + * the events are run with ``atomic``, so that they appear to run + serially + + * this tweaked event loop should work with just any existing program + + +- Futures + + * e.g. twisted's deferred + + ... From noreply at buildbot.pypy.org Thu Mar 14 19:38:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 14 Mar 2013 19:38:24 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: (arigo, fijal) progress Message-ID: <20130314183824.DAD331C1409@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4955:0d97b6116477 Date: 2013-03-14 11:38 -0700 http://bitbucket.org/pypy/extradoc/changeset/0d97b6116477/ Log: (arigo, fijal) progress diff --git a/talk/pycon2013/pypy_without_gil.txt b/talk/pycon2013/pypy_without_gil.txt --- a/talk/pycon2013/pypy_without_gil.txt +++ b/talk/pycon2013/pypy_without_gil.txt @@ -9,7 +9,31 @@ - thanks to contributors for STM +Problem +------- +* a complex, large program that does stuff + +* stuff is mostly independent + +|pause| + +* ... but not quite + +* shared mutable state, however, not too much + +* we want to parallelize the problem + +Classic solutions +----------------- + +* multithreading + + * large shared state (tons of lock) + + * no shared mutable state (copying, keeping in sync) + +* MPI - message passing, with limited shared state Demo --------------------------- From noreply at buildbot.pypy.org Thu Mar 14 20:04:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 14 Mar 2013 20:04:07 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix surrogatepass Message-ID: <20130314190407.DDB081C1409@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62337:42ec5de26dd7 Date: 2013-03-14 12:03 -0700 http://bitbucket.org/pypy/pypy/changeset/42ec5de26dd7/ Log: fix surrogatepass diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -288,7 +288,7 @@ raise OperationError(space.type(w_exc), w_exc) res += chr(0xe0 | (ch >> 12)) res += chr(0x80 | ((ch >> 6) & 0x3f)) - res += chr(0x80 | (ch >> 0x3f)) + res += chr(0x80 | (ch & 0x3f)) return space.newtuple([space.wrapbytes(res), w_end]) elif space.isinstance_w(w_exc, space.w_UnicodeDecodeError): start = space.int_w(space.getattr(w_exc, space.wrap('start'))) diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -515,6 +515,10 @@ b"abc\xed\xa0\x80def") assert (b"abc\xed\xa0\x80def".decode("utf-8", "surrogatepass") == "abc\ud800def") + assert ('surrogate:\udcff'.encode("utf-8", "surrogatepass") == + b'surrogate:\xed\xb3\xbf') + assert (b'surrogate:\xed\xb3\xbf'.decode("utf-8", "surrogatepass") == + 'surrogate:\udcff') raises(UnicodeDecodeError, b"abc\xed\xa0".decode, "utf-8", "surrogatepass") raises(UnicodeDecodeError, b"abc\xed\xa0z".decode, "utf-8", From noreply at buildbot.pypy.org Thu Mar 14 20:38:27 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 14 Mar 2013 20:38:27 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: remove difference with default Message-ID: <20130314193827.5A7DD1C0253@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62338:1edc3644c19e Date: 2013-02-25 17:50 -0800 http://bitbucket.org/pypy/pypy/changeset/1edc3644c19e/ Log: remove difference with default diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -250,7 +250,7 @@ space.sys.get('modules'), space.wrap(name)) else: - return space.wrap(os.path.dirname(mod)) + return os.path.dirname(mod) @unwrap_spec(mod=str, name=str) def reimport_module(space, mod, name): From noreply at buildbot.pypy.org Thu Mar 14 20:38:28 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 14 Mar 2013 20:38:28 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: fix for Issue1422: there should be no need for $ROOTSYS if root-config is available Message-ID: <20130314193828.970261C0253@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62339:f4974f9f635f Date: 2013-03-14 12:37 -0700 http://bitbucket.org/pypy/pypy/changeset/f4974f9f635f/ Log: fix for Issue1422: there should be no need for $ROOTSYS if root- config is available diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi/reflex_capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -9,18 +9,23 @@ srcpath = pkgpath.join("src") incpath = pkgpath.join("include") +import commands +(config_stat, incdir) = commands.getstatusoutput("root-config --incdir") + if os.environ.get("ROOTSYS"): - import commands - (stat, incdir) = commands.getstatusoutput("root-config --incdir") - if stat != 0: # presumably Reflex-only + if config_stat != 0: # presumably Reflex-only rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")] else: rootincpath = [incdir] rootlibpath = commands.getoutput("root-config --libdir").split() else: - rootincpath = [] - rootlibpath = [] + if config_stat == 0: + rootincpath = [incdir] + rootlibpath = commands.getoutput("root-config --libdir").split() + else: + rootincpath = [] + rootlibpath = [] def identify(): return 'Reflex' diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -7,7 +7,7 @@ ifeq ($(ROOTSYS),) genreflex=genreflex - cppflags= + cppflags=-I$(shell root-config --incdir) -L$(shell root-config --libdir) else genreflex=$(ROOTSYS)/bin/genreflex ifeq ($(wildcard $(ROOTSYS)/include),) # standard locations used? diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py --- a/pypy/module/cppyy/test/test_pythonify.py +++ b/pypy/module/cppyy/test/test_pythonify.py @@ -6,6 +6,9 @@ test_dct = str(currpath.join("example01Dict.so")) def setup_module(mod): + # force removal of ROOTSYS for this one test, which serves as a test itself + if os.getenv("ROOTSYS"): + os.unsetenv("ROOTSYS") if sys.platform == 'win32': py.test.skip("win32 not supported so far") err = os.system("cd '%s' && make example01Dict.so" % currpath) From noreply at buildbot.pypy.org Thu Mar 14 22:09:27 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 14 Mar 2013 22:09:27 +0100 (CET) Subject: [pypy-commit] pypy default: fix for Issue1422: there should be no need for $ROOTSYS if root-config is available Message-ID: <20130314210927.AD8D41C0253@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: Changeset: r62341:eb98e4d9205d Date: 2013-03-14 14:09 -0700 http://bitbucket.org/pypy/pypy/changeset/eb98e4d9205d/ Log: fix for Issue1422: there should be no need for $ROOTSYS if root- config is available fix a test that was broken diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi/reflex_capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -9,18 +9,23 @@ srcpath = pkgpath.join("src") incpath = pkgpath.join("include") +import commands +(config_stat, incdir) = commands.getstatusoutput("root-config --incdir") + if os.environ.get("ROOTSYS"): - import commands - (stat, incdir) = commands.getstatusoutput("root-config --incdir") - if stat != 0: # presumably Reflex-only + if config_stat != 0: # presumably Reflex-only rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")] else: rootincpath = [incdir] rootlibpath = commands.getoutput("root-config --libdir").split() else: - rootincpath = [] - rootlibpath = [] + if config_stat == 0: + rootincpath = [incdir] + rootlibpath = commands.getoutput("root-config --libdir").split() + else: + rootincpath = [] + rootlibpath = [] def identify(): return 'Reflex' diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -7,7 +7,7 @@ ifeq ($(ROOTSYS),) genreflex=genreflex - cppflags= + cppflags=-I$(shell root-config --incdir) -L$(shell root-config --libdir) else genreflex=$(ROOTSYS)/bin/genreflex ifeq ($(wildcard $(ROOTSYS)/include),) # standard locations used? diff --git a/pypy/module/cppyy/test/test_crossing.py b/pypy/module/cppyy/test/test_crossing.py --- a/pypy/module/cppyy/test/test_crossing.py +++ b/pypy/module/cppyy/test/test_crossing.py @@ -1,6 +1,16 @@ import py, os, sys +from pypy.interpreter.gateway import interp2app, unwrap_spec +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.translator import platform +from rpython.translator.gensupp import uniquemodulename +from rpython.tool.udir import udir + +from pypy.module.cpyext import api +from pypy.module.cpyext.state import State + from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("crossingDict.so")) @@ -11,27 +21,90 @@ if err: raise OSError("'make' failed (see stderr)") +# from pypy/module/cpyext/test/test_cpyext.py; modified to accept more external +# symbols and called directly instead of import_module +def compile_extension_module(space, modname, symbols, **kwds): + """ + Build an extension module and return the filename of the resulting native + code file. + + modname is the name of the module, possibly including dots if it is a module + inside a package. + + Any extra keyword arguments are passed on to ExternalCompilationInfo to + build the module (so specify your source with one of those). + """ + state = space.fromcache(State) + api_library = state.api_lib + if sys.platform == 'win32': + kwds["libraries"] = [api_library] + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] + elif sys.platform == 'darwin': + kwds["link_files"] = [str(api_library + '.dylib')] + else: + kwds["link_files"] = [str(api_library + '.so')] + if sys.platform.startswith('linux'): + kwds["compile_extra"]=["-Werror=implicit-function-declaration"] + + modname = modname.split('.')[-1] + eci = ExternalCompilationInfo( + export_symbols=['init%s' % (modname,)]+symbols, + include_dirs=api.include_dirs, + **kwds + ) + eci = eci.convert_sources_to_files() + dirname = (udir/uniquemodulename('module')).ensure(dir=1) + soname = platform.platform.compile( + [], eci, + outputfilename=str(dirname/modname), + standalone=False) + from pypy.module.imp.importing import get_so_extension + pydname = soname.new(purebasename=modname, ext=get_so_extension(space)) + soname.rename(pydname) + return str(pydname) class AppTestCrossing(AppTestCpythonExtensionBase): spaceconfig = dict(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi', 'array', 'itertools', 'rctime', 'binascii']) def setup_class(cls): - # following from AppTestCpythonExtensionBase, with cppyy added - cls.space.getbuiltinmodule("cpyext") - from pypy.module.imp.importing import importhook - importhook(cls.space, "os") # warm up reference counts - from pypy.module.cpyext.pyobject import RefcountState - state = cls.space.fromcache(RefcountState) - state.non_heaptypes_w[:] = [] - - # cppyy specific additions (not that the test_dct is loaded late + AppTestCpythonExtensionBase.setup_class.im_func(cls) + # cppyy specific additions (note that test_dct is loaded late # to allow the generated extension module be loaded first) cls.w_test_dct = cls.space.wrap(test_dct) cls.w_pre_imports = cls.space.appexec([], """(): import cppyy, ctypes""") # prevents leak-checking complaints on ctypes - from pypy.module.imp.importing import get_so_extension - cls.w_soext = cls.space.wrap(get_so_extension(cls.space)) + + def setup_method(self, func): + AppTestCpythonExtensionBase.setup_method.im_func(self, func) + + @unwrap_spec(name=str, init=str, body=str) + def load_cdll(space, name, init, body, w_symbols): + # the following is loosely from test_cpyext.py import_module; it + # is copied here to be able to tweak the call to + # compile_extension_module and to get a different return result + # than in that function + code = """ + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + kwds = dict(separate_module_sources=[code]) + symbols = [space.str_w(w_item) for w_item in space.fixedview(w_symbols)] + mod = compile_extension_module(space, name, symbols, **kwds) + + # explicitly load the module as a CDLL rather than as a module + import ctypes + from pypy.module.imp.importing import get_so_extension + fullmodname = os.path.join( + os.path.dirname(mod), name + get_so_extension(space)) + return ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) + + self.w_load_cdll = self.space.wrap(interp2app(load_cdll)) def test00_base_class(self): """Test from cpyext; only here to see whether the imported class works""" @@ -49,10 +122,13 @@ import os, ctypes + name = 'bar' + init = """ if (Py_IsInitialized()) Py_InitModule("bar", methods); """ + # note: only the symbols are needed for C, none for python body = """ long bar_unwrap(PyObject* arg) @@ -67,10 +143,12 @@ { NULL } }; """ + # explicitly load the module as a CDLL rather than as a module +# dirname = space.wrap(os.path.dirname(mod)) - dirname = self.import_module(name='bar', init=init, body=body, load_it=False) - fullmodname = os.path.join(dirname, 'bar' + self.soext) - self.cmodule = ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) +# dirname = self.import_module(name='bar', init=init, body=body, load_it=False) +# fullmodname = os.path.join(dirname, name + self.soext) + self.cmodule = self.load_cdll(name, init, body, ['bar_unwrap', 'bar_wrap'])#ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) def test02_crossing_dict(self): """Test availability of all needed classes in the dict""" diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py --- a/pypy/module/cppyy/test/test_pythonify.py +++ b/pypy/module/cppyy/test/test_pythonify.py @@ -6,6 +6,9 @@ test_dct = str(currpath.join("example01Dict.so")) def setup_module(mod): + # force removal of ROOTSYS for this one test, which serves as a test itself + if os.getenv("ROOTSYS"): + os.unsetenv("ROOTSYS") if sys.platform == 'win32': py.test.skip("win32 not supported so far") err = os.system("cd '%s' && make example01Dict.so" % currpath) From noreply at buildbot.pypy.org Fri Mar 15 00:29:13 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:13 +0100 (CET) Subject: [pypy-commit] pypy default: reorder checks for upstream compatability, enable pedantic test Message-ID: <20130314232913.3533A1C138E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r62342:a5c03ba0f6bc Date: 2013-03-12 21:21 -0700 http://bitbucket.org/pypy/pypy/changeset/a5c03ba0f6bc/ Log: reorder checks for upstream compatability, enable pedantic test diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -109,19 +109,19 @@ _axis = axis if axis < 0: _axis = len(shape) + axis - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for arr in args_w[1:]: - dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, - arr.get_dtype()) - if _axis < 0 or len(arr.get_shape()) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for i, axis_size in enumerate(arr.get_shape()): if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, + arr.get_dtype()) + if _axis < 0 or len(arr.get_shape()) <= _axis: + raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) + if _axis < 0 or len(shape) <= _axis: + raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -1470,12 +1470,11 @@ assert str(exc.value) == \ "all the input arrays must have same number of dimensions" - if 0: # XXX too pedantic - g1 = array([0,1,2]) - g2 = array([[3,4,5]]) - exc = raises(ValueError, concatenate, (g1, g2), axis=2) - assert str(exc.value) == \ - "all the input arrays must have same number of dimensions" + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] From noreply at buildbot.pypy.org Fri Mar 15 00:29:14 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:14 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: make str dtypes more reliable Message-ID: <20130314232914.691121C13E3@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62343:d50d0fffaa1b Date: 2013-03-13 07:52 -0700 http://bitbucket.org/pypy/pypy/changeset/d50d0fffaa1b/ Log: make str dtypes more reliable From noreply at buildbot.pypy.org Fri Mar 15 00:29:19 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:19 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: comment why one test passes and the other not Message-ID: <20130314232919.64AE41C141F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62347:28560d094490 Date: 2013-03-14 12:22 -0700 http://bitbucket.org/pypy/pypy/changeset/28560d094490/ Log: comment why one test passes and the other not 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 @@ -1646,6 +1646,7 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 + # scalar vs. array try: a = array([1, 2, 3.14156]).astype('S3').dtype assert a.itemsize == 3 From noreply at buildbot.pypy.org Fri Mar 15 00:29:20 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:20 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: a failing test (passes in numpy) Message-ID: <20130314232920.9F38D1C138E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62348:442ac683b187 Date: 2013-03-14 12:58 -0700 http://bitbucket.org/pypy/pypy/changeset/442ac683b187/ Log: a failing test (passes in numpy) 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 @@ -1480,6 +1480,8 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' def test_std(self): from numpypy import array From noreply at buildbot.pypy.org Fri Mar 15 00:29:15 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:15 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: astype fails for str Message-ID: <20130314232915.A9E821C13F9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62344:dd8e18e4b12b Date: 2013-03-13 07:54 -0700 http://bitbucket.org/pypy/pypy/changeset/dd8e18e4b12b/ Log: astype fails for str 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 @@ -1646,6 +1646,8 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 + a = array([1, 2, 3.14156]).astype('S3').dtype + assert a.itemsize == 3 def test_base(self): from numpypy import array From noreply at buildbot.pypy.org Fri Mar 15 00:29:21 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:21 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: add failing test Message-ID: <20130314232921.D1B011C138E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62349:37b3032c46fa Date: 2013-03-14 13:05 -0700 http://bitbucket.org/pypy/pypy/changeset/37b3032c46fa/ Log: add failing test 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 @@ -1480,6 +1480,8 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() + a = concatenate((array([1]), array(['abc']))) + assert a.dtype == 'S3' a = concatenate((array([]), array(['abc']))) assert a[0] == 'abc' From noreply at buildbot.pypy.org Fri Mar 15 00:29:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:23 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: test more, partial fix Message-ID: <20130314232923.1C4DF1C138E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62350:88b9b898cd98 Date: 2013-03-14 16:05 -0700 http://bitbucket.org/pypy/pypy/changeset/88b9b898cd98/ Log: test more, partial fix diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -122,6 +122,9 @@ raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) if _axis < 0 or len(shape) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) + if dtype is None: + raise OperationError(space.w_TypeError, space.wrap( + 'invalid type promotion')) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -277,6 +277,10 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) + def convert_to(self, dtype): + assert dtype.fields == self.dtype.fields + return self + class W_CharacterBox(W_FlexibleBox): pass 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind: + if dt1.kind == dt2.kind and dt1.fields == dt2.fields: return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,7 +434,24 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - else: + elif dt2.is_flexible_type(): + # For those operations that get here (concatenate, stack), + # flexible types take precedence over numeric type + if dt2.is_record_type(): + if dt1.fields == dt2.fields: + #record types require an exact match + return dt2 + return None + if dt1.is_str_or_unicode(): + if dt2.num == 18: + size = max(dt2.itemtype.get_element_size(), + dt1.itemtype.get_element_size()) + return interp_dtype.new_string_type(size) + size = max(dt2.itemtype.get_element_size(), + dt1.itemtype.get_element_size()) + return interp_dtype.new_unitype_type(size) + return dt2 + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -1484,6 +1484,22 @@ assert a.dtype == 'S3' a = concatenate((array([]), array(['abc']))) assert a[0] == 'abc' + + def test_record_concatenate(self): + # only an exact match can succeed + from numpypy import zeros, concatenate + a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), + zeros((2,),dtype=[('x', int), ('y', float)]))) + assert a.shape == (4,) + raises(TypeError, concatenate, + (zeros((2,), dtype=[('x', int), ('y', float)]), + (zeros((2,), dtype=[('x', float), ('y', float)])))) + raises(TypeError, concatenate, ([1], zeros((2,), + dtype=[('x', int), ('y', float)]))) + raises(TypeError, concatenate, (['abc'], zeros((2,), + dtype=[('x', int), ('y', float)]))) + + def test_std(self): from numpypy import array From noreply at buildbot.pypy.org Fri Mar 15 00:29:16 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:16 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: simplify Message-ID: <20130314232916.E7E691C1409@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62345:b009349f6dde Date: 2013-03-14 11:44 -0700 http://bitbucket.org/pypy/pypy/changeset/b009349f6dde/ Log: simplify 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 @@ -1634,7 +1634,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) From noreply at buildbot.pypy.org Fri Mar 15 00:29:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:24 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: skip missing functionality Message-ID: <20130314232924.4A9CE1C138E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62351:4adb8f504e1f Date: 2013-03-14 16:16 -0700 http://bitbucket.org/pypy/pypy/changeset/4adb8f504e1f/ Log: skip missing functionality diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -47,6 +47,9 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return + if self.dtype.is_str_or_unicode(): + raise OperationError(space.w_NotImplementedError, space.wrap( + "concatenate(%s) not implemented yet" % self.dtype)) shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: impl = impl.copy() @@ -276,7 +279,7 @@ return ArrayBuffer(self) def astype(self, space, dtype): - if dtype.is_flexible_type(): + if dtype.is_str_or_unicode(): raise OperationError(space.w_NotImplementedError, space.wrap( "astype(%s) not implemented yet" % dtype)) new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) 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 @@ -1480,10 +1480,13 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() - a = concatenate((array([1]), array(['abc']))) - assert a.dtype == 'S3' - a = concatenate((array([]), array(['abc']))) - assert a[0] == 'abc' + try: + a = concatenate((array([1]), array(['abc']))) + assert a.dtype == 'S3' + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' + except NotImplementedError: + skip('cannot concatenate numeric with string') def test_record_concatenate(self): # only an exact match can succeed From noreply at buildbot.pypy.org Fri Mar 15 00:29:18 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:18 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: cannot implement astype('S3') without StringType.box, but box would require an unavailable space instance to convert values to strings Message-ID: <20130314232918.3518D1C140A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62346:351a29aeb5e8 Date: 2013-03-14 12:10 -0700 http://bitbucket.org/pypy/pypy/changeset/351a29aeb5e8/ Log: cannot implement astype('S3') without StringType.box, but box would require an unavailable space instance to convert values to strings diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -276,6 +276,9 @@ return ArrayBuffer(self) def astype(self, space, dtype): + if dtype.is_flexible_type(): + raise OperationError(space.w_NotImplementedError, space.wrap( + "astype(%s) not implemented yet" % dtype)) new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) loop.copy_from_to(self, new_arr.implementation, dtype) return new_arr 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 @@ -1646,8 +1646,11 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 - a = array([1, 2, 3.14156]).astype('S3').dtype - assert a.itemsize == 3 + try: + a = array([1, 2, 3.14156]).astype('S3').dtype + assert a.itemsize == 3 + except NotImplementedError: + skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array From noreply at buildbot.pypy.org Fri Mar 15 00:29:25 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 15 Mar 2013 00:29:25 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130314232925.A368B1C138E@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r62352:f90828f177b9 Date: 2013-03-14 16:21 -0700 http://bitbucket.org/pypy/pypy/changeset/f90828f177b9/ Log: merge heads diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -23,7 +23,7 @@ leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. """ - return sys.version[:3] + return sys.version[0] def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): diff --git a/lib-python/2/sysconfig.py b/lib-python/2/sysconfig.py --- a/lib-python/2/sysconfig.py +++ b/lib-python/2/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python/{py_version_short}', - 'platstdlib': '{base}/lib-python/{py_version_short}', - 'purelib': '{base}/lib-python/{py_version_short}', - 'platlib': '{base}/lib-python/{py_version_short}', + 'stdlib': '{base}/lib-python/{py_version}', + 'platstdlib': '{base}/lib-python/{py_version}', + 'purelib': '{base}/lib-python/{py_version}', + 'platlib': '{base}/lib-python/{py_version}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi/reflex_capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -9,18 +9,23 @@ srcpath = pkgpath.join("src") incpath = pkgpath.join("include") +import commands +(config_stat, incdir) = commands.getstatusoutput("root-config --incdir") + if os.environ.get("ROOTSYS"): - import commands - (stat, incdir) = commands.getstatusoutput("root-config --incdir") - if stat != 0: # presumably Reflex-only + if config_stat != 0: # presumably Reflex-only rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")] else: rootincpath = [incdir] rootlibpath = commands.getoutput("root-config --libdir").split() else: - rootincpath = [] - rootlibpath = [] + if config_stat == 0: + rootincpath = [incdir] + rootlibpath = commands.getoutput("root-config --libdir").split() + else: + rootincpath = [] + rootlibpath = [] def identify(): return 'Reflex' diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -7,7 +7,7 @@ ifeq ($(ROOTSYS),) genreflex=genreflex - cppflags= + cppflags=-I$(shell root-config --incdir) -L$(shell root-config --libdir) else genreflex=$(ROOTSYS)/bin/genreflex ifeq ($(wildcard $(ROOTSYS)/include),) # standard locations used? diff --git a/pypy/module/cppyy/test/test_crossing.py b/pypy/module/cppyy/test/test_crossing.py --- a/pypy/module/cppyy/test/test_crossing.py +++ b/pypy/module/cppyy/test/test_crossing.py @@ -1,6 +1,16 @@ import py, os, sys +from pypy.interpreter.gateway import interp2app, unwrap_spec +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.translator import platform +from rpython.translator.gensupp import uniquemodulename +from rpython.tool.udir import udir + +from pypy.module.cpyext import api +from pypy.module.cpyext.state import State + from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("crossingDict.so")) @@ -11,27 +21,90 @@ if err: raise OSError("'make' failed (see stderr)") +# from pypy/module/cpyext/test/test_cpyext.py; modified to accept more external +# symbols and called directly instead of import_module +def compile_extension_module(space, modname, symbols, **kwds): + """ + Build an extension module and return the filename of the resulting native + code file. + + modname is the name of the module, possibly including dots if it is a module + inside a package. + + Any extra keyword arguments are passed on to ExternalCompilationInfo to + build the module (so specify your source with one of those). + """ + state = space.fromcache(State) + api_library = state.api_lib + if sys.platform == 'win32': + kwds["libraries"] = [api_library] + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] + elif sys.platform == 'darwin': + kwds["link_files"] = [str(api_library + '.dylib')] + else: + kwds["link_files"] = [str(api_library + '.so')] + if sys.platform.startswith('linux'): + kwds["compile_extra"]=["-Werror=implicit-function-declaration"] + + modname = modname.split('.')[-1] + eci = ExternalCompilationInfo( + export_symbols=['init%s' % (modname,)]+symbols, + include_dirs=api.include_dirs, + **kwds + ) + eci = eci.convert_sources_to_files() + dirname = (udir/uniquemodulename('module')).ensure(dir=1) + soname = platform.platform.compile( + [], eci, + outputfilename=str(dirname/modname), + standalone=False) + from pypy.module.imp.importing import get_so_extension + pydname = soname.new(purebasename=modname, ext=get_so_extension(space)) + soname.rename(pydname) + return str(pydname) class AppTestCrossing(AppTestCpythonExtensionBase): spaceconfig = dict(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi', 'array', 'itertools', 'rctime', 'binascii']) def setup_class(cls): - # following from AppTestCpythonExtensionBase, with cppyy added - cls.space.getbuiltinmodule("cpyext") - from pypy.module.imp.importing import importhook - importhook(cls.space, "os") # warm up reference counts - from pypy.module.cpyext.pyobject import RefcountState - state = cls.space.fromcache(RefcountState) - state.non_heaptypes_w[:] = [] - - # cppyy specific additions (not that the test_dct is loaded late + AppTestCpythonExtensionBase.setup_class.im_func(cls) + # cppyy specific additions (note that test_dct is loaded late # to allow the generated extension module be loaded first) cls.w_test_dct = cls.space.wrap(test_dct) cls.w_pre_imports = cls.space.appexec([], """(): import cppyy, ctypes""") # prevents leak-checking complaints on ctypes - from pypy.module.imp.importing import get_so_extension - cls.w_soext = cls.space.wrap(get_so_extension(cls.space)) + + def setup_method(self, func): + AppTestCpythonExtensionBase.setup_method.im_func(self, func) + + @unwrap_spec(name=str, init=str, body=str) + def load_cdll(space, name, init, body, w_symbols): + # the following is loosely from test_cpyext.py import_module; it + # is copied here to be able to tweak the call to + # compile_extension_module and to get a different return result + # than in that function + code = """ + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + kwds = dict(separate_module_sources=[code]) + symbols = [space.str_w(w_item) for w_item in space.fixedview(w_symbols)] + mod = compile_extension_module(space, name, symbols, **kwds) + + # explicitly load the module as a CDLL rather than as a module + import ctypes + from pypy.module.imp.importing import get_so_extension + fullmodname = os.path.join( + os.path.dirname(mod), name + get_so_extension(space)) + return ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) + + self.w_load_cdll = self.space.wrap(interp2app(load_cdll)) def test00_base_class(self): """Test from cpyext; only here to see whether the imported class works""" @@ -49,10 +122,13 @@ import os, ctypes + name = 'bar' + init = """ if (Py_IsInitialized()) Py_InitModule("bar", methods); """ + # note: only the symbols are needed for C, none for python body = """ long bar_unwrap(PyObject* arg) @@ -67,10 +143,12 @@ { NULL } }; """ + # explicitly load the module as a CDLL rather than as a module +# dirname = space.wrap(os.path.dirname(mod)) - dirname = self.import_module(name='bar', init=init, body=body, load_it=False) - fullmodname = os.path.join(dirname, 'bar' + self.soext) - self.cmodule = ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) +# dirname = self.import_module(name='bar', init=init, body=body, load_it=False) +# fullmodname = os.path.join(dirname, name + self.soext) + self.cmodule = self.load_cdll(name, init, body, ['bar_unwrap', 'bar_wrap'])#ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) def test02_crossing_dict(self): """Test availability of all needed classes in the dict""" diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py --- a/pypy/module/cppyy/test/test_pythonify.py +++ b/pypy/module/cppyy/test/test_pythonify.py @@ -6,6 +6,9 @@ test_dct = str(currpath.join("example01Dict.so")) def setup_module(mod): + # force removal of ROOTSYS for this one test, which serves as a test itself + if os.getenv("ROOTSYS"): + os.unsetenv("ROOTSYS") if sys.platform == 'win32': py.test.skip("win32 not supported so far") err = os.system("cd '%s' && make example01Dict.so" % currpath) From noreply at buildbot.pypy.org Fri Mar 15 07:20:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Mar 2013 07:20:37 +0100 (CET) Subject: [pypy-commit] pypy default: redo this adjustment for vendor-rename because get_python_version is an exposed api Message-ID: <20130315062037.BC7121C0CA3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62353:eb674fd688ee Date: 2013-03-15 02:18 -0400 http://bitbucket.org/pypy/pypy/changeset/eb674fd688ee/ Log: redo this adjustment for vendor-rename because get_python_version is an exposed api diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -23,7 +23,7 @@ leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. """ - return sys.version[0] + return sys.version[:3] def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): @@ -43,7 +43,7 @@ if prefix is None: prefix = PREFIX if standard_lib: - return os.path.join(prefix, "lib-python", get_python_version()) + return os.path.join(prefix, "lib-python", sys.version[0]) return os.path.join(prefix, 'site-packages') From noreply at buildbot.pypy.org Fri Mar 15 15:29:49 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 15 Mar 2013 15:29:49 +0100 (CET) Subject: [pypy-commit] pypy default: add a script to download the latest nightly and extract the pypy binary in the current directory Message-ID: <20130315142949.067851C0253@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62354:d572df7a5ac4 Date: 2013-03-15 15:29 +0100 http://bitbucket.org/pypy/pypy/changeset/d572df7a5ac4/ Log: add a script to download the latest nightly and extract the pypy binary in the current directory diff --git a/pypy/goal/getnightly.py b/pypy/goal/getnightly.py new file mode 100755 --- /dev/null +++ b/pypy/goal/getnightly.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import sys +import os +import py + +if sys.platform.startswith('linux'): + arch = 'linux' +else: + print 'Cannot determine the platform, please update this scrip' + sys.exit(1) + +if sys.maxint == 2**63 - 1: + arch += '64' + +filename = 'pypy-c-jit-latest-%s.tar.bz2' % arch +url = 'http://buildbot.pypy.org/nightly/trunk/%s' % filename +tmp = py.path.local.mkdtemp() +mydir = tmp.chdir() +print 'Downloading pypy to', tmp +if os.system('wget "%s"' % url) != 0: + sys.exit(1) + +print 'Extracting pypy binary' +mydir.chdir() +os.system("tar -x -v --wildcards --strip-components=2 -f %s '*/bin/pypy'" % tmp.join(filename)) + From noreply at buildbot.pypy.org Fri Mar 15 16:31:35 2013 From: noreply at buildbot.pypy.org (timfel) Date: Fri, 15 Mar 2013 16:31:35 +0100 (CET) Subject: [pypy-commit] lang-gameboy default: Update rsdl to work with after rpython split Message-ID: <20130315153135.693E11C1360@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r5:5c7bcc86c8f9 Date: 2013-03-15 16:31 +0100 http://bitbucket.org/pypy/lang-gameboy/changeset/5c7bcc86c8f9/ Log: Update rsdl to work with after rpython split diff --git a/rsdl/RIMG.py b/rsdl/RIMG.py --- a/rsdl/RIMG.py +++ b/rsdl/RIMG.py @@ -1,7 +1,7 @@ import sys -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rpython.tool import rffi_platform as platform -from pypy.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform as platform +from rpython.translator.tool.cbuild import ExternalCompilationInfo from rsdl import RSDL diff --git a/rsdl/RMix.py b/rsdl/RMix.py --- a/rsdl/RMix.py +++ b/rsdl/RMix.py @@ -1,7 +1,7 @@ import sys -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rpython.tool import rffi_platform as platform -from pypy.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform as platform +from rpython.translator.tool.cbuild import ExternalCompilationInfo from rsdl import RSDL diff --git a/rsdl/RSDL.py b/rsdl/RSDL.py --- a/rsdl/RSDL.py +++ b/rsdl/RSDL.py @@ -1,8 +1,8 @@ -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rpython.tool import rffi_platform as platform +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform as platform from rsdl.constants import _constants from rsdl.eci import get_rsdl_compilation_info -from pypy.rlib.objectmodel import we_are_translated +from rpython.rlib.objectmodel import we_are_translated import py import sys @@ -162,6 +162,11 @@ Uint32, Uint32, Uint32, Uint32], SurfacePtr) +CreateRGBSurfaceFrom = external('SDL_CreateRGBSurfaceFrom', + [rffi.VOIDP, rffi.INT, rffi.INT, rffi.INT, rffi.INT, + Uint32, Uint32, Uint32, Uint32], + SurfacePtr) + LockSurface = external('SDL_LockSurface', [SurfacePtr], rffi.INT) diff --git a/rsdl/RSDL_helper.py b/rsdl/RSDL_helper.py --- a/rsdl/RSDL_helper.py +++ b/rsdl/RSDL_helper.py @@ -1,4 +1,4 @@ -from pypy.rpython.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem import lltype, rffi from rsdl import RSDL def get_rgb(color, format): @@ -105,4 +105,3 @@ dstrect = mallocrect(x, y, rffi.getintfield(src, 'c_w'), rffi.getintfield(src, 'c_w')) RSDL.BlitSurface(src, lltype.nullptr(RSDL.Rect), dst, dstrect) lltype.free(dstrect, flavor='raw') - diff --git a/rsdl/eci.py b/rsdl/eci.py --- a/rsdl/eci.py +++ b/rsdl/eci.py @@ -1,5 +1,5 @@ -from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.platform import CompilationError +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.translator.platform import CompilationError import py import sys diff --git a/rsdl/test/conftest.py b/rsdl/test/conftest.py --- a/rsdl/test/conftest.py +++ b/rsdl/test/conftest.py @@ -1,4 +1,4 @@ -from pypy.rlib.rsdl.eci import check_sdl_installation, SDLNotInstalled +from rsdl.eci import check_sdl_installation, SDLNotInstalled import py def pytest_ignore_collect(path): diff --git a/rsdl/test/test_basic.py b/rsdl/test/test_basic.py --- a/rsdl/test/test_basic.py +++ b/rsdl/test/test_basic.py @@ -1,7 +1,7 @@ import py -from pypy.rlib.rsdl import RSDL -from pypy.rlib.rarithmetic import r_uint -from pypy.rpython.lltypesystem import rffi +from rsdl import RSDL +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import rffi def test_sdl_init(): @@ -34,4 +34,4 @@ i = RSDL.GetTicks() assert i >= 10 RSDL.Quit() - \ No newline at end of file + diff --git a/rsdl/test/test_sdl_image.py b/rsdl/test/test_sdl_image.py --- a/rsdl/test/test_sdl_image.py +++ b/rsdl/test/test_sdl_image.py @@ -1,6 +1,6 @@ import py, os from rsdl import RSDL, RIMG, RSDL_helper, test -from pypy.rpython.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem import lltype, rffi this_dir = test.__path__[0] diff --git a/rsdl/test/test_sdl_mixer.py b/rsdl/test/test_sdl_mixer.py --- a/rsdl/test/test_sdl_mixer.py +++ b/rsdl/test/test_sdl_mixer.py @@ -1,8 +1,8 @@ import py import os import time -from pypy.rlib.rsdl import RSDL, RMix, RSDL_helper -from pypy.rpython.lltypesystem import lltype, rffi +from rsdl import RSDL, RMix, RSDL_helper +from rpython.rtyper.lltypesystem import lltype, rffi def test_open_mixer(): if RMix.OpenAudio(22050, RSDL.AUDIO_S16LSB, 2, 1024) != 0: diff --git a/rsdl/test/test_surface.py b/rsdl/test/test_surface.py --- a/rsdl/test/test_surface.py +++ b/rsdl/test/test_surface.py @@ -1,7 +1,7 @@ import py, sys -from pypy.rlib.rsdl import RSDL, RSDL_helper -from pypy.rlib.rarithmetic import r_uint -from pypy.rpython.lltypesystem import lltype, rffi +from rsdl import RSDL, RSDL_helper +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import lltype, rffi class TestSurface: diff --git a/rsdl/test/test_video.py b/rsdl/test/test_video.py --- a/rsdl/test/test_video.py +++ b/rsdl/test/test_video.py @@ -1,8 +1,8 @@ import py, sys -from pypy.rlib.rsdl import RSDL, RSDL_helper -from pypy.rlib.rarithmetic import r_uint -from pypy.rpython.lltypesystem import lltype, rffi +from rsdl import RSDL, RSDL_helper +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import lltype, rffi # # This test file is skipped unless run with "py.test --view". From noreply at buildbot.pypy.org Fri Mar 15 17:20:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Mar 2013 17:20:00 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: in-progress Message-ID: <20130315162000.839051C3A37@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4956:e29ffc17e9b2 Date: 2013-03-15 09:19 -0700 http://bitbucket.org/pypy/extradoc/changeset/e29ffc17e9b2/ Log: in-progress diff --git a/talk/pycon2013/pypy_without_gil/message_passing.py b/talk/pycon2013/pypy_without_gil/message_passing.py new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/message_passing.py @@ -0,0 +1,28 @@ +import thread, Queue + + +def compute(queue): + # + for j in range(10): + for k in range(10**6): + pass + queue.put(1) + # + queue.put("done") + + +queue = Queue.Queue() +for i in range(10): + thread.start_new_thread(compute, (queue,)) + +running_threads = 10 +num = 0 + +while running_threads > 0: + item = queue.get() + if item == "done": + running_threads -= 1 + else: + num += 1 + +print num diff --git a/talk/pycon2013/pypy_without_gil/multithreading.py b/talk/pycon2013/pypy_without_gil/multithreading.py new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/multithreading.py @@ -0,0 +1,21 @@ +import thread + + +def compute(lock): + # + for k in xrange(10**7): + pass + # + lock.release() + + +all_locks = [thread.allocate_lock() for i in range(10)] + +for i in range(10): + lock = all_locks[i] + lock.acquire() + thread.start_new_thread(compute, (lock,)) + +for i in range(10): + lock = all_locks[i] + lock.acquire() diff --git a/talk/pycon2013/pypy_without_gil/multithreading2.py b/talk/pycon2013/pypy_without_gil/multithreading2.py new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/multithreading2.py @@ -0,0 +1,27 @@ +import thread + + +def compute(lock): + global num + # + for j in range(10): + for k in range(10**6): + pass + num += 1 # not actually safe! needs a lock + # + lock.release() + + +num = 0 +all_locks = [thread.allocate_lock() for i in range(10)] + +for i in range(10): + lock = all_locks[i] + lock.acquire() + thread.start_new_thread(compute, (lock,)) + +for i in range(10): + lock = all_locks[i] + lock.acquire() + +print num diff --git a/talk/pycon2013/pypy_without_gil.txt b/talk/pycon2013/pypy_without_gil/pypy_without_gil.txt rename from talk/pycon2013/pypy_without_gil.txt rename to talk/pycon2013/pypy_without_gil/pypy_without_gil.txt --- a/talk/pycon2013/pypy_without_gil.txt +++ b/talk/pycon2013/pypy_without_gil/pypy_without_gil.txt @@ -9,38 +9,101 @@ - thanks to contributors for STM + Problem ------- -* a complex, large program that does stuff +* An existing complex, large program that does stuff -* stuff is mostly independent +* "stuff" consists of bits that are mostly independent from each other |pause| * ... but not quite -* shared mutable state, however, not too much -* we want to parallelize the problem +Problem +------- + +* We want to parallelize the program to use all these cores + +* We have some shared mutable state + +|pause| + +* Not too much of it --- otherwise, no chance for parallelism + +* But still some + Classic solutions ----------------- -* multithreading +Bare-metal multi-threading: - * large shared state (tons of lock) +* large shared state - * no shared mutable state (copying, keeping in sync) +* needs careful usage of locks -* MPI - message passing, with limited shared state +* mostly hindered by the GIL in CPython + (but not in Jython) + + +Classic solutions +----------------- + +Multi-processing: + +* no shared mutable state at all + +* copying, keeping in sync are your problem + +* memory usage is often multiplied (unless you're lucky with ``fork``) + + +Classic solutions +----------------- + +A range of intermediate solutions: + +* MPI: message passing, with limited shared state + +* etc.: tons of experiments that never caught on + + +Classic solutions +----------------- + +The typical solution for web servers: + +* run independent processes + +* share data only via the database + +* the database itself handles concurrency with transactions + Demo --------------------------- -- demo: ~/br/stm-thread-2/64compiled/pypy-c-r61735+-stm +* ``pypy-stm`` - * run some random multithreaded program +* internally based on "transactions" (STM, HTM) + + +Demo +--------------------------- + +- demo: + + * multithreading.py + + * multithreading2.py + + * message_passing.py + + * transactions2.py + - missing in pypy-stm: @@ -102,6 +165,9 @@ --------------------------- +- xxx memory usage good + + - based on (and fully compatible with) threads * existing multithreaded programs work @@ -129,7 +195,7 @@ * The idea is that we fix only XX% of the bugs and we are done - * Maybe some new "performance debugger" tools might help us too + * Maybe some new "performance debugger" tools might help too - TigerQuoll, 1st March: same idea with JavaScript (for servers) @@ -154,11 +220,4 @@ * the events are run with ``atomic``, so that they appear to run serially - * this tweaked event loop should work with just any existing program - - -- Futures - - * e.g. twisted's deferred - - ... + * does not rely on any change to the user program diff --git a/talk/pycon2013/pypy_without_gil/transactions0.py b/talk/pycon2013/pypy_without_gil/transactions0.py new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/transactions0.py @@ -0,0 +1,13 @@ +import transaction + + + +def compute(): + for k in range(10**7): + pass + + +for i in range(10): + transaction.add(compute) + +transaction.run() diff --git a/talk/pycon2013/pypy_without_gil/transactions1.py b/talk/pycon2013/pypy_without_gil/transactions1.py new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/transactions1.py @@ -0,0 +1,24 @@ +import transaction + + + +class MyStuff(object): + counter = 0 + +def increment_class_counter(): + MyStuff.counter += 1 + + +def compute(): + for j in range(10): + for k in range(10**6): + pass + transaction.add(increment_class_counter) + + +for i in range(10): + transaction.add(compute) + +transaction.run() + +print MyStuff.counter diff --git a/talk/pycon2013/pypy_without_gil/transactions2.py b/talk/pycon2013/pypy_without_gil/transactions2.py new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/transactions2.py @@ -0,0 +1,18 @@ +import transaction + + +def do_stuff(x): + # huge piece of code doing tons of messy things + for j in range(10**6): + assert x != 42 + + +def do_stuff_for_all(lst): + for x in lst: + do_stuff(x) + #for x in lst: + # transaction.add(do_stuff, x) + #transaction.run() + + +do_stuff_for_all(range(20)) From noreply at buildbot.pypy.org Fri Mar 15 17:42:26 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Mar 2013 17:42:26 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: (fijal, arigo) in the typical pypy style copy-paste beamerdefs Message-ID: <20130315164226.A65D61C1360@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4957:48522e7e372b Date: 2013-03-15 09:42 -0700 http://bitbucket.org/pypy/extradoc/changeset/48522e7e372b/ Log: (fijal, arigo) in the typical pypy style copy-paste beamerdefs diff --git a/talk/pycon2013/pypy_without_gil/Makefile b/talk/pycon2013/pypy_without_gil/Makefile new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/Makefile @@ -0,0 +1,16 @@ +# you can find rst2beamer.py and inkscapeslide.py here: +# http://bitbucket.org/antocuni/env/src/619f486c4fad/bin/rst2beamer.py +# http://bitbucket.org/antocuni/env/src/619f486c4fad/bin/inkscapeslide.py + + +talk.pdf: talk.rst author.latex title.latex stylesheet.latex + rst2beamer --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit + sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit + #sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit + pdflatex talk.latex || exit + +view: talk.pdf + evince talk.pdf & + +xpdf: talk.pdf + xpdf talk.pdf & diff --git a/talk/pycon2013/pypy_without_gil/author.latex b/talk/pycon2013/pypy_without_gil/author.latex new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[Python without the GIL]{Python without the GIL} +\author[arigo, fijal] +{Armin Rigo \\ Maciej Fijałkowski} + +\institute{Pycon US 2013} +\date{March 15 2013} diff --git a/talk/pycon2013/pypy_without_gil/beamerdefs.txt b/talk/pycon2013/pypy_without_gil/beamerdefs.txt new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/beamerdefs.txt @@ -0,0 +1,108 @@ +.. colors +.. =========================== + +.. role:: green +.. role:: red + + +.. general useful commands +.. =========================== + +.. |pause| raw:: latex + + \pause + +.. |small| raw:: latex + + {\small + +.. |end_small| raw:: latex + + } + +.. |scriptsize| raw:: latex + + {\scriptsize + +.. |end_scriptsize| raw:: latex + + } + +.. |strike<| raw:: latex + + \sout{ + +.. closed bracket +.. =========================== + +.. |>| raw:: latex + + } + + +.. example block +.. =========================== + +.. |example<| raw:: latex + + \begin{exampleblock}{ + + +.. |end_example| raw:: latex + + \end{exampleblock} + + + +.. alert block +.. =========================== + +.. |alert<| raw:: latex + + \begin{alertblock}{ + + +.. |end_alert| raw:: latex + + \end{alertblock} + + + +.. columns +.. =========================== + +.. |column1| raw:: latex + + \begin{columns} + \begin{column}{0.45\textwidth} + +.. |column2| raw:: latex + + \end{column} + \begin{column}{0.45\textwidth} + + +.. |end_columns| raw:: latex + + \end{column} + \end{columns} + + + +.. |snake| image:: ../../img/py-web-new.png + :scale: 15% + + + +.. nested blocks +.. =========================== + +.. |nested| raw:: latex + + \begin{columns} + \begin{column}{0.85\textwidth} + +.. |end_nested| raw:: latex + + \end{column} + \end{columns} diff --git a/talk/pycon2013/pypy_without_gil/pypy_without_gil.txt b/talk/pycon2013/pypy_without_gil/pypy_without_gil.txt --- a/talk/pycon2013/pypy_without_gil/pypy_without_gil.txt +++ b/talk/pycon2013/pypy_without_gil/pypy_without_gil.txt @@ -46,7 +46,7 @@ * needs careful usage of locks * mostly hindered by the GIL in CPython - (but not in Jython) + (but not in Jython or IronPython) Classic solutions @@ -56,9 +56,12 @@ * no shared mutable state at all -* copying, keeping in sync are your problem +* copying, keeping in sync is your problem -* memory usage is often multiplied (unless you're lucky with ``fork``) +* serializing and deserializing is expensive and hard + +* memory usage is often multiplied (unless you're lucky with ``fork``, + but not on Python) Classic solutions @@ -68,7 +71,7 @@ * MPI: message passing, with limited shared state -* etc.: tons of experiments that never caught on +* etc.: tons of experiments that never caught on in the mainstream Classic solutions @@ -84,7 +87,7 @@ Demo ---------------------------- +---- * ``pypy-stm`` @@ -92,7 +95,7 @@ Demo ---------------------------- +---- - demo: @@ -104,13 +107,18 @@ * transactions2.py +Status of the implementation +---------------------------- +* mostly works -- missing in pypy-stm: +* major GC collections missing (leaks slowly) - * GC major collection - * JIT - * some more optimizations possible (= tons of) +* JIT integration is not done + +* tons of optimizations possible + + - __pypy__.thread.atomic diff --git a/talk/pycon2013/pypy_without_gil/stylesheet.latex b/talk/pycon2013/pypy_without_gil/stylesheet.latex new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/stylesheet.latex @@ -0,0 +1,11 @@ +\usetheme{Boadilla} +\usecolortheme{whale} +\setbeamercovered{transparent} +\setbeamertemplate{navigation symbols}{} + +\definecolor{darkgreen}{rgb}{0, 0.5, 0.0} +\newcommand{\docutilsrolegreen}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\docutilsrolered}[1]{\color{red}#1\normalcolor} + +\newcommand{\green}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\red}[1]{\color{red}#1\normalcolor} diff --git a/talk/pycon2013/pypy_without_gil/talk.rst b/talk/pycon2013/pypy_without_gil/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pycon2013/pypy_without_gil/talk.rst @@ -0,0 +1,233 @@ +.. include:: beamerdefs.txt + +==================== +PyPy without the GIL +==================== + +Intro +--------------------------- + +- PyPy intro + +- thanks to contributors for STM + + +Problem +------- + +* An existing complex, large program that does stuff + +* "stuff" consists of bits that are mostly independent from each other + +|pause| + +* ... but not quite + + +Problem +------- + +* We want to parallelize the program to use all these cores + +* We have some shared mutable state + +|pause| + +* Not too much of it --- otherwise, no chance for parallelism + +* But still some + + +Classic solutions +----------------- + +Bare-metal multi-threading: + +* large shared state + +* needs careful usage of locks + +* mostly hindered by the GIL in CPython + (but not in Jython or IronPython) + + +Classic solutions +----------------- + +Multi-processing: + +* no shared mutable state at all + +* copying, keeping in sync is your problem + +* serializing and deserializing is expensive and hard + +* memory usage is often multiplied (unless you're lucky with ``fork``, + but not on Python) + + +Classic solutions +----------------- + +A range of intermediate solutions: + +* MPI: message passing, with limited shared state + +* etc.: tons of experiments that never caught on in the mainstream + + +Classic solutions +----------------- + +The typical solution for web servers: + +* run independent processes + +* share data only via the database + +* the database itself handles concurrency with transactions + + +Demo +---- + +* ``pypy-stm`` + +* internally based on "transactions" (STM, HTM) + + +Demo +---- + +- demo: + + * multithreading.py + + * multithreading2.py + + * message_passing.py + + * transactions2.py + +Status of the implementation +---------------------------- + +* mostly works + +* major GC collections missing (leaks slowly) + +* JIT integration is not done + +* tons of optimizations possible + + + + +- __pypy__.thread.atomic + + * with atomic: + print "hello", username + + * the illusion of serialization + + +Lower level: STM +--------------------------- + +- pypy and not cpython? + + +- STM = Software Transactional Memory + + +- Basic idea: each thread runs in parallel, but everything it does is + in a series of "transactions" + + +- A transaction keeps all changes to pre-existing memory "local" + + +- The changes are made visible only when the transaction "commits" + + +- The transaction will "abort" if a conflict is detected, and + it will be transparently retried + + +- Non-reversible operations like I/O turn the transaction "inevitable" + and stop progress in the other threads + + +- __pypy__.thread.last_abort_info() -> traceback-like information + + +- (GC-supported structure: when we want to modify a pre-existing object, + we first copy it into "local" memory, and when we commit, it becomes + the newer version of the old pre-existing object; we end up with a + chained list of versions, and we have to make sure we always use the + latest one. We rely on GC major collections to free them eventually.) + + +- alternative: HTM...? + + +Higher level: not threads +--------------------------- + + +- xxx memory usage good + + +- based on (and fully compatible with) threads + + * existing multithreaded programs work + + +- but opens up unexpected alternatives + + * we can run multiple threads but at the same time use ``atomic`` + + * with the GIL-based idea of ``atomic`` it doesn't make sense: + we have multiple threads but they're all using ``atomic``, i.e. + only one at a time will ever run... except no :-) + + +- transaction.py + + * demo + + * illusion of serial execution: can "sanely" reason about algorithms + + * "Conflict tracebacks" + + * Might need to debug them --- but they are performance bugs, not + correctness bugs + + * The idea is that we fix only XX% of the bugs and we are done + + * Maybe some new "performance debugger" tools might help too + + +- TigerQuoll, 1st March: same idea with JavaScript (for servers) + + * various models possible: + + . events dispatchers + + . futures + + . map/reduce, scatter/gather + + +- Event dispatchers + + * twisted, tulip, etc. + + * run the event dispatcher in one thread (e.g. the main thread), + and schedule the actual events to run on a different thread from + a pool + + * the events are run with ``atomic``, so that they appear to run + serially + + * does not rely on any change to the user program From noreply at buildbot.pypy.org Fri Mar 15 17:54:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Mar 2013 17:54:40 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: some progress and slidification Message-ID: <20130315165440.6A6BC1C3A3C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4958:643f8e36f6a8 Date: 2013-03-15 09:54 -0700 http://bitbucket.org/pypy/extradoc/changeset/643f8e36f6a8/ Log: some progress and slidification diff --git a/talk/pycon2013/pypy_without_gil/talk.rst b/talk/pycon2013/pypy_without_gil/talk.rst --- a/talk/pycon2013/pypy_without_gil/talk.rst +++ b/talk/pycon2013/pypy_without_gil/talk.rst @@ -120,64 +120,53 @@ * tons of optimizations possible +How do I use it? +---------------- +* just like with the GIL +* ``__pypy__.thread.atomic`` -- __pypy__.thread.atomic +:: + with atomic: + print "hello", username - * with atomic: - print "hello", username +* the illusion of serialization - * the illusion of serialization +STM - low level +--------------- +* STM = Software Transactional Memory -Lower level: STM ---------------------------- - -- pypy and not cpython? - - -- STM = Software Transactional Memory - - -- Basic idea: each thread runs in parallel, but everything it does is +* Basic idea: each thread runs in parallel, but everything it does is in a series of "transactions" +* A transaction keeps all changes to pre-existing memory "local" -- A transaction keeps all changes to pre-existing memory "local" +* The changes are made visible only when the transaction "commits" -- The changes are made visible only when the transaction "commits" +STM - low level (2) +------------------- - -- The transaction will "abort" if a conflict is detected, and +* The transaction will "abort" if a conflict is detected, and it will be transparently retried -- Non-reversible operations like I/O turn the transaction "inevitable" +* Non-reversible operations like I/O turn the transaction "inevitable" and stop progress in the other threads -- __pypy__.thread.last_abort_info() -> traceback-like information +* __pypy__.thread.last_abort_info() -> traceback-like information +Alternative - HTM +----------------- -- (GC-supported structure: when we want to modify a pre-existing object, - we first copy it into "local" memory, and when we commit, it becomes - the newer version of the old pre-existing object; we end up with a - chained list of versions, and we have to make sure we always use the - latest one. We rely on GC major collections to free them eventually.) - - -- alternative: HTM...? - +XXX Higher level: not threads --------------------------- - -- xxx memory usage good - - - based on (and fully compatible with) threads * existing multithreaded programs work @@ -192,6 +181,13 @@ only one at a time will ever run... except no :-) + + +- xxx memory usage good + + + + - transaction.py * demo @@ -219,15 +215,32 @@ . map/reduce, scatter/gather -- Event dispatchers +Event dispatchers +----------------- - * twisted, tulip, etc. +* twisted, tulip, etc. - * run the event dispatcher in one thread (e.g. the main thread), - and schedule the actual events to run on a different thread from - a pool +* run the event dispatcher in one thread (e.g. the main thread), + and schedule the actual events to run on a different thread from + a pool - * the events are run with ``atomic``, so that they appear to run - serially +* the events are run with ``atomic``, so that they appear to run + serially - * does not rely on any change to the user program +* does not rely on any change to the user program + +Donate! +------- + +* STM is primarily funded by donations + +* We got quite far with $22k USD + +* Thanks to the PSF and all others! + +* We need your help too + +Q&A +--- + +* http://pypy.org From noreply at buildbot.pypy.org Fri Mar 15 18:23:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Mar 2013 18:23:27 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: some progress Message-ID: <20130315172327.0D94A1C3A8D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4959:9cdffd5bbe29 Date: 2013-03-15 09:55 -0700 http://bitbucket.org/pypy/extradoc/changeset/9cdffd5bbe29/ Log: some progress diff --git a/talk/pycon2013/pypy_without_gil/talk.rst b/talk/pycon2013/pypy_without_gil/talk.rst --- a/talk/pycon2013/pypy_without_gil/talk.rst +++ b/talk/pycon2013/pypy_without_gil/talk.rst @@ -5,12 +5,11 @@ ==================== Intro ---------------------------- +----- -- PyPy intro +* PyPy is a Python interpreter with stuff (like JIT, STM, ...) -- thanks to contributors for STM - +* No PyPy talk this year, find us around, come to BoF Problem ------- From noreply at buildbot.pypy.org Fri Mar 15 18:27:41 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 15 Mar 2013 18:27:41 +0100 (CET) Subject: [pypy-commit] pypy default: make sure that import * imports this function too Message-ID: <20130315172741.73BCA1C3B23@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62355:90949f100ecd Date: 2013-03-15 18:27 +0100 http://bitbucket.org/pypy/pypy/changeset/90949f100ecd/ Log: make sure that import * imports this function too diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -4,6 +4,7 @@ 'array_repr', 'array_str', 'set_string_function', 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + 'seterr', ] import sys From noreply at buildbot.pypy.org Fri Mar 15 19:11:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Mar 2013 19:11:22 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: The final talk, with pdf Message-ID: <20130315181122.7635A1C3A37@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4960:98ba962a18f1 Date: 2013-03-15 19:11 +0100 http://bitbucket.org/pypy/extradoc/changeset/98ba962a18f1/ Log: The final talk, with pdf diff --git a/talk/pycon2013/pypy_without_gil/Makefile b/talk/pycon2013/pypy_without_gil/Makefile --- a/talk/pycon2013/pypy_without_gil/Makefile +++ b/talk/pycon2013/pypy_without_gil/Makefile @@ -3,8 +3,8 @@ # http://bitbucket.org/antocuni/env/src/619f486c4fad/bin/inkscapeslide.py -talk.pdf: talk.rst author.latex title.latex stylesheet.latex - rst2beamer --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit +talk.pdf: talk.rst author.latex stylesheet.latex + rst2beamer.py --input-encoding=utf8 --output-encoding=utf8 --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit #sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit pdflatex talk.latex || exit diff --git a/talk/pycon2013/pypy_without_gil/author.latex b/talk/pycon2013/pypy_without_gil/author.latex --- a/talk/pycon2013/pypy_without_gil/author.latex +++ b/talk/pycon2013/pypy_without_gil/author.latex @@ -4,5 +4,5 @@ \author[arigo, fijal] {Armin Rigo \\ Maciej Fijałkowski} -\institute{Pycon US 2013} +\institute{PyCon US 2013} \date{March 15 2013} diff --git a/talk/pycon2013/pypy_without_gil/talk.pdf b/talk/pycon2013/pypy_without_gil/talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..42a99f8e0181cc640fe47ec8ff46d3fe59db3af6 GIT binary patch [cut] diff --git a/talk/pycon2013/pypy_without_gil/talk.rst b/talk/pycon2013/pypy_without_gil/talk.rst --- a/talk/pycon2013/pypy_without_gil/talk.rst +++ b/talk/pycon2013/pypy_without_gil/talk.rst @@ -7,9 +7,19 @@ Intro ----- -* PyPy is a Python interpreter with stuff (like JIT, STM, ...) +* PyPy is a Python interpreter with stuff -* No PyPy talk this year, find us around, come to BoF +* No general PyPy talk this year, find us around, come to the BoF (tomorrow 2pm) + + +This is about... +---------------- + +* This talk is about using multiple cores to achieve better performance + +* in Python (or any other existing, non-trivial, non-functional, + non-designed-for-this-problem, language) + Problem ------- @@ -126,9 +136,7 @@ * ``__pypy__.thread.atomic`` -:: - with atomic: - print "hello", username +* ``with atomic:`` ``print "hello",`` ``username`` * the illusion of serialization @@ -156,15 +164,20 @@ and stop progress in the other threads -* __pypy__.thread.last_abort_info() -> traceback-like information +* ``__pypy__.thread.last_abort_info()`` -> traceback-like information Alternative - HTM ----------------- -XXX +* Intel Haswell (released soon) has got HTM -Higher level: not threads ---------------------------- +* great for the "remove the GIL" part + +* not so great for large transactions, at least for now + + +Higher level: Threads Are Bad +----------------------------- - based on (and fully compatible with) threads @@ -173,45 +186,56 @@ - but opens up unexpected alternatives - * we can run multiple threads but at the same time use ``atomic`` - * with the GIL-based idea of ``atomic`` it doesn't make sense: - we have multiple threads but they're all using ``atomic``, i.e. - only one at a time will ever run... except no :-) +Higher level: Atomic +-------------------- +* we can run multiple threads but at the same time use ``atomic`` +* with the GIL-based idea of ``atomic`` it wouldn't make sense + - multiple threads + + - but they're all using ``atomic`` -- xxx memory usage good + - i.e. only one at a time will ever run + - ...except no :-) +Transactions +------------ -- transaction.py +* ``transaction.py``: example of wrapper hiding threads - * demo +* illusion of serial execution: can "sanely" reason about algorithms - * illusion of serial execution: can "sanely" reason about algorithms - * "Conflict tracebacks" +Transaction conflicts +--------------------- - * Might need to debug them --- but they are performance bugs, not - correctness bugs +* "Conflict tracebacks" - * The idea is that we fix only XX% of the bugs and we are done +* Might need to debug them --- but they are performance bugs, not + correctness bugs - * Maybe some new "performance debugger" tools might help too +* The idea is that we fix only XX% of the bugs and we are done +* Maybe some new "performance debugger" tools might help too -- TigerQuoll, 1st March: same idea with JavaScript (for servers) - * various models possible: +We're not the only ones +----------------------- - . events dispatchers +TigerQuoll, 1st March: same idea with JavaScript (for servers) - . futures +Various models possible: - . map/reduce, scatter/gather +* events dispatchers + +* futures + +* map/reduce, scatter/gather Event dispatchers @@ -243,3 +267,5 @@ --- * http://pypy.org + +* http://bit.ly/pypystm From noreply at buildbot.pypy.org Fri Mar 15 21:08:17 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 15 Mar 2013 21:08:17 +0100 (CET) Subject: [pypy-commit] pypy pickle-dumps: speed up pickle.dumps - use StringBuilder instead of StringIO - see issue #979 Message-ID: <20130315200817.7A6831C1360@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: pickle-dumps Changeset: r62356:15467e502b39 Date: 2013-03-15 20:56 +0400 http://bitbucket.org/pypy/pypy/changeset/15467e502b39/ Log: speed up pickle.dumps - use StringBuilder instead of StringIO - see issue #979 diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,6 +34,8 @@ import struct import re +from __pypy__.builders import StringBuilder + __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1409,11 +1411,27 @@ except ImportError: from StringIO import StringIO + +class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + + def write(self, data): + for x in data: + self.builder.append(data) + + def getvalue(self): + return self.builder.build() + + def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -2,7 +2,7 @@ # Reimplementation of cPickle, mostly as a copy of pickle.py # -from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass +from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass, StringBuilderFile from pickle import __doc__, __version__, format_version, compatible_formats from types import * from copy_reg import dispatch_table @@ -120,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() From noreply at buildbot.pypy.org Fri Mar 15 21:08:18 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 15 Mar 2013 21:08:18 +0100 (CET) Subject: [pypy-commit] pypy pickle-dumps: err, fix stupid error, now pickle tests pass Message-ID: <20130315200818.BFB631C1360@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: pickle-dumps Changeset: r62357:158e496963dd Date: 2013-03-15 21:10 +0400 http://bitbucket.org/pypy/pypy/changeset/158e496963dd/ Log: err, fix stupid error, now pickle tests pass diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1421,7 +1421,7 @@ def write(self, data): for x in data: - self.builder.append(data) + self.builder.append(x) def getvalue(self): return self.builder.build() From noreply at buildbot.pypy.org Fri Mar 15 21:08:20 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 15 Mar 2013 21:08:20 +0100 (CET) Subject: [pypy-commit] pypy pickle-dumps: (bdkearns) this is 2x faster on small objects and slighly faster on large ones Message-ID: <20130315200820.009A71C1360@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: pickle-dumps Changeset: r62358:d8645c92cc8b Date: 2013-03-15 23:16 +0400 http://bitbucket.org/pypy/pypy/changeset/d8645c92cc8b/ Log: (bdkearns) this is 2x faster on small objects and slighly faster on large ones diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1420,8 +1420,7 @@ self.builder = StringBuilder() def write(self, data): - for x in data: - self.builder.append(x) + self.builder.append(data) def getvalue(self): return self.builder.build() From noreply at buildbot.pypy.org Fri Mar 15 21:08:21 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 15 Mar 2013 21:08:21 +0100 (CET) Subject: [pypy-commit] pypy pickle-dumps: this makes StringBuilder match StringIO on small objects, although it is strange Message-ID: <20130315200821.3B0DF1C1360@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: pickle-dumps Changeset: r62359:519e4fca15cb Date: 2013-03-15 23:22 +0400 http://bitbucket.org/pypy/pypy/changeset/519e4fca15cb/ Log: this makes StringBuilder match StringIO on small objects, although it is strange diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1418,9 +1418,7 @@ ''' def __init__(self): self.builder = StringBuilder() - - def write(self, data): - self.builder.append(data) + self.write = self.builder.append def getvalue(self): return self.builder.build() From noreply at buildbot.pypy.org Fri Mar 15 21:08:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Mar 2013 21:08:22 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in kostialopuhin/pypy/pickle-dumps (pull request #132) Message-ID: <20130315200822.616681C1360@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62360:cf4882ee100b Date: 2013-03-15 13:08 -0700 http://bitbucket.org/pypy/pypy/changeset/cf4882ee100b/ Log: Merged in kostialopuhin/pypy/pickle-dumps (pull request #132) Speed up pickle.dumps - fixes issue 979 diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,6 +34,8 @@ import struct import re +from __pypy__.builders import StringBuilder + __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1409,11 +1411,24 @@ except ImportError: from StringIO import StringIO + +class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + self.write = self.builder.append + + def getvalue(self): + return self.builder.build() + + def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -2,7 +2,7 @@ # Reimplementation of cPickle, mostly as a copy of pickle.py # -from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass +from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass, StringBuilderFile from pickle import __doc__, __version__, format_version, compatible_formats from types import * from copy_reg import dispatch_table @@ -120,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() From noreply at buildbot.pypy.org Fri Mar 15 21:29:58 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Mar 2013 21:29:58 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130315202958.242021C0CA3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62361:c6ce849b9749 Date: 2013-03-15 16:29 -0400 http://bitbucket.org/pypy/pypy/changeset/c6ce849b9749/ Log: fix whatsnew 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 @@ -42,6 +42,7 @@ .. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal +.. branch: pickle-dumps .. branch: release-2.0-beta1 From noreply at buildbot.pypy.org Fri Mar 15 22:07:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Mar 2013 22:07:11 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _marshal.dump_unicode (fixes issue 1420) Message-ID: <20130315210711.EE59E1C3B3F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62362:6cbb87a9026d Date: 2013-03-15 16:51 -0400 http://bitbucket.org/pypy/pypy/changeset/6cbb87a9026d/ Log: test and fix for _marshal.dump_unicode (fixes issue 1420) diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -167,8 +167,8 @@ def dump_unicode(self, x): self._write(TYPE_UNICODE) #s = x.encode('utf8') - s, len_s = utf_8_encode(x) - self.w_long(len_s) + s = utf_8_encode(x)[0] + self.w_long(len(s)) self._write(s) try: unicode @@ -387,7 +387,7 @@ n = self.r_long() s = self._read(n) #ret = s.decode('utf8') - ret, len_ret = utf_8_decode(s) + ret = utf_8_decode(s)[0] return ret dispatch[TYPE_UNICODE] = load_unicode diff --git a/pypy/module/test_lib_pypy/test_marshal_extra.py b/pypy/module/test_lib_pypy/test_marshal_extra.py --- a/pypy/module/test_lib_pypy/test_marshal_extra.py +++ b/pypy/module/test_lib_pypy/test_marshal_extra.py @@ -145,3 +145,8 @@ def test_load_truncated_string(): s = '(\x02\x00\x00\x00i\x03\x00\x00\x00sB\xf9\x00\x00\nabcd' py.test.raises(EOFError, marshal.loads, s) + +def test_dump_unicode_length(): + s = u'123\xe9' + r = marshal.dumps(s) + assert r == b'u\x05\x00\x00\x00123\xc3\xa9' From noreply at buildbot.pypy.org Fri Mar 15 22:07:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Mar 2013 22:07:13 +0100 (CET) Subject: [pypy-commit] pypy default: call encode/decode instead of using utf_8_encode/decode Message-ID: <20130315210713.38F461C3B3F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62363:9ea8ae583d55 Date: 2013-03-15 16:59 -0400 http://bitbucket.org/pypy/pypy/changeset/9ea8ae583d55/ Log: call encode/decode instead of using utf_8_encode/decode diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -7,7 +7,6 @@ # the "sandboxed" process. It must work for Python2 as well. import types -from _codecs import utf_8_decode, utf_8_encode try: intern @@ -166,8 +165,7 @@ def dump_unicode(self, x): self._write(TYPE_UNICODE) - #s = x.encode('utf8') - s = utf_8_encode(x)[0] + s = x.encode('utf8') self.w_long(len(s)) self._write(s) try: @@ -386,8 +384,7 @@ def load_unicode(self): n = self.r_long() s = self._read(n) - #ret = s.decode('utf8') - ret = utf_8_decode(s)[0] + ret = s.decode('utf8') return ret dispatch[TYPE_UNICODE] = load_unicode From noreply at buildbot.pypy.org Fri Mar 15 22:27:58 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Mar 2013 22:27:58 +0100 (CET) Subject: [pypy-commit] pypy default: generalize this test to work on py3k also Message-ID: <20130315212758.849C11C3B7A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62364:5d0ade08b064 Date: 2013-03-15 17:27 -0400 http://bitbucket.org/pypy/pypy/changeset/5d0ade08b064/ Log: generalize this test to work on py3k also diff --git a/pypy/module/test_lib_pypy/test_marshal_extra.py b/pypy/module/test_lib_pypy/test_marshal_extra.py --- a/pypy/module/test_lib_pypy/test_marshal_extra.py +++ b/pypy/module/test_lib_pypy/test_marshal_extra.py @@ -147,6 +147,6 @@ py.test.raises(EOFError, marshal.loads, s) def test_dump_unicode_length(): - s = u'123\xe9' + s = b'123\xe9'.decode('latin-1') r = marshal.dumps(s) assert r == b'u\x05\x00\x00\x00123\xc3\xa9' From noreply at buildbot.pypy.org Sat Mar 16 01:26:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Mar 2013 01:26:49 +0100 (CET) Subject: [pypy-commit] pypy default: fix testing cPickle on cpython Message-ID: <20130316002649.6C31D1C3A3C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62365:706f2784ba43 Date: 2013-03-15 20:25 -0400 http://bitbucket.org/pypy/pypy/changeset/706f2784ba43/ Log: fix testing cPickle on cpython diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -2,7 +2,7 @@ # Reimplementation of cPickle, mostly as a copy of pickle.py # -from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass, StringBuilderFile +from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass from pickle import __doc__, __version__, format_version, compatible_formats from types import * from copy_reg import dispatch_table @@ -96,6 +96,11 @@ # closer to the ones produced by cPickle in CPython from pickle import StringIO +try: + from pickle import StringBuilderFile +except ImportError: + assert '__pypy__' not in sys.builtin_module_names + from pickle import StringIO as StringBuilderFile PythonPickler = Pickler class Pickler(PythonPickler): From noreply at buildbot.pypy.org Sat Mar 16 02:08:14 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Mar 2013 02:08:14 +0100 (CET) Subject: [pypy-commit] pypy default: (fijal, arigo, bivab, others) Message-ID: <20130316010814.DF82D1C1360@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62366:b564452df4ad Date: 2013-03-15 18:08 -0700 http://bitbucket.org/pypy/pypy/changeset/b564452df4ad/ Log: (fijal, arigo, bivab, others) merge jitframe-on-heap, which moves optimized JIT frames from stack to heap. As a side effect it enables stackless to work well with the JIT on PyPy. Also removes a bunch of code from the GC which fixes cannot find gc roots. diff too long, truncating to 2000 out of 21811 lines diff --git a/pypy/TODO b/pypy/TODO new file mode 100644 --- /dev/null +++ b/pypy/TODO @@ -0,0 +1,2 @@ + +* ARM diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -19,11 +19,6 @@ # - normal: self.sthread != None, not is_empty_handle(self.h) # - finished: self.sthread != None, is_empty_handle(self.h) - def __del__(self): - sthread = self.sthread - if sthread is not None and not sthread.is_empty_handle(self.h): - sthread.destroy(self.h) - def check_sthread(self): ec = self.space.getexecutioncontext() if ec.stacklet_thread is not self.sthread: @@ -34,7 +29,7 @@ if self.sthread is not None: raise geterror(self.space, "continulet already __init__ialized") sthread = build_sthread(self.space) - workaround_disable_jit(sthread) + #workaround_disable_jit(sthread) # # hackish: build the frame "by hand", passing it the correct arguments space = self.space @@ -77,7 +72,7 @@ global_state.clear() raise geterror(self.space, "continulet already finished") self.check_sthread() - workaround_disable_jit(self.sthread) + #workaround_disable_jit(self.sthread) # global_state.origin = self if to is None: 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 @@ -5,14 +5,14 @@ from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError -from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, hlstr from rpython.rtyper.lltypesystem.rclass import OBJECT -from rpython.jit.metainterp.resoperation import rop, AbstractResOp +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 -from rpython.rlib.rarithmetic import r_uint +from rpython.rlib.objectmodel import compute_unique_id from pypy.module.pypyjit.interp_jit import pypyjitdriver class Cache(object): @@ -270,7 +270,8 @@ self.jd_name = debug_info.get_jitdriver().name self.type = debug_info.type if is_bridge: - self.bridge_no = debug_info.fail_descr_no + self.bridge_no = compute_unique_id(debug_info.fail_descr) + #self.bridge_no = debug_info.fail_descr_no self.w_green_key = space.w_None else: self.w_green_key = wrap_greenkey(space, diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py --- a/pypy/module/pypyjit/policy.py +++ b/pypy/module/pypyjit/policy.py @@ -106,7 +106,7 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat']: + '_cffi_backend', 'pyexpat', '_continuation']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -2,7 +2,8 @@ import py from pypy.interpreter.gateway import interp2app from pypy.interpreter.pycode import PyCode -from rpython.jit.metainterp.history import JitCellToken, ConstInt, ConstPtr +from rpython.jit.metainterp.history import JitCellToken, ConstInt, ConstPtr,\ + BasicFailDescr from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.logger import Logger from rpython.rtyper.annlowlevel import (cast_instance_to_base_ptr, @@ -69,7 +70,7 @@ oplist, 'loop', greenkey) di_loop.asminfo = AsmInfo(offset, 0, 0) di_bridge = JitDebugInfo(MockJitDriverSD, logger, JitCellToken(), - oplist, 'bridge', fail_descr_no=0) + oplist, 'bridge', fail_descr=BasicFailDescr()) di_bridge.asminfo = AsmInfo(offset, 0, 0) def interp_on_compile(): diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -34,7 +34,7 @@ self.descr = descr self._is_guard = name.startswith('guard_') if self._is_guard: - self.guard_no = int(self.descr[len(') + guard_false(v0, descr=) guard_true(v0, descr=) ''') bridge = parse(''' - # bridge out of Guard 13 + # bridge out of Guard 1a [] int_add(0, 1) ''') LoopStorage().reconnect_loops([main, bridge]) assert adjust_bridges(main, {})[1].name == 'guard_true' - assert adjust_bridges(main, {'loop-13': True})[1].name == 'int_add' + assert adjust_bridges(main, {'loop-1a': True})[1].name == 'int_add' def test_parsing_strliteral(): loop = parse(""" @@ -259,7 +259,7 @@ +348: i32 = int_is_true(i31) +360: i33 = int_or(i27, i32) +364: i34 = int_is_true(i33) -guard_false(i34, descr=) [i1, i22, p2] +guard_false(i34, descr=) [i1, i22, p2] +372: i35 = int_add(i22, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +376: jump(i35, i1, p2, p4, descr=TargetToken(1081858656)) @@ -323,7 +323,7 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) @@ -336,10 +336,10 @@ i0 = int_lt(1, 2) finish(i0) ''') - bridge.comment = 'bridge out of Guard 2 with 1 ops' + bridge.comment = 'bridge out of Guard af with 1 ops' loop.comment = 'Loop 0' loops = split_trace(loop) + split_trace(bridge) - input = ['grrr:123\nasb:12\nbridge 2:1234'] + input = ['grrr:123\nasb:12\nbridge af:1234'] parse_log_counts(input, loops) assert loops[-1].count == 1234 assert loops[1].count == 123 diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -1,7 +1,3 @@ -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import r_uint - - FUNC_ALIGN = 8 WORD = 4 DOUBLE_WORD = 8 @@ -14,54 +10,12 @@ PC_OFFSET = 8 FORCE_INDEX_OFS = 0 -from rpython.translator.tool.cbuild import ExternalCompilationInfo -eci = ExternalCompilationInfo(post_include_bits=[""" -static int pypy__arm_int_div(int a, int b) { - return a/b; -} -static unsigned int pypy__arm_uint_div(unsigned int a, unsigned int b) { - return a/b; -} -static int pypy__arm_int_mod(int a, int b) { - return a % b; -} -"""]) - - -def arm_int_div_emulator(a, b): - return int(a / float(b)) -arm_int_div_sign = lltype.Ptr( - lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) -arm_int_div = rffi.llexternal( - "pypy__arm_int_div", [lltype.Signed, lltype.Signed], lltype.Signed, - _callable=arm_int_div_emulator, - compilation_info=eci, - _nowrapper=True, elidable_function=True) - - -def arm_uint_div_emulator(a, b): - return r_uint(a) / r_uint(b) -arm_uint_div_sign = lltype.Ptr( - lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned)) -arm_uint_div = rffi.llexternal( - "pypy__arm_uint_div", [lltype.Unsigned, lltype.Unsigned], lltype.Unsigned, - _callable=arm_uint_div_emulator, - compilation_info=eci, - _nowrapper=True, elidable_function=True) - - -def arm_int_mod_emulator(a, b): - sign = 1 - if a < 0: - a = -1 * a - sign = -1 - if b < 0: - b = -1 * b - res = a % b - return sign * res -arm_int_mod_sign = arm_int_div_sign -arm_int_mod = rffi.llexternal( - "pypy__arm_int_mod", [lltype.Signed, lltype.Signed], lltype.Signed, - _callable=arm_int_mod_emulator, - compilation_info=eci, - _nowrapper=True, elidable_function=True) +# The stack contains the force_index and the, callee saved registers and +# ABI required information +# All the rest of the data is in a GC-managed variable-size "frame". +# This jitframe object's address is always stored in the register FP +# A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME +# Stack frame fixed area +# Currently only the force_index +JITFRAME_FIXED_SIZE = 11 + 16 * 2 + 1 +# 11 GPR + 16 VFP Regs (64bit) + 1 word for alignment diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -5,11 +5,13 @@ from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, FUNC_ALIGN, \ - N_REGISTERS_SAVED_BY_MALLOC + N_REGISTERS_SAVED_BY_MALLOC, \ + JITFRAME_FIXED_SIZE from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder -from rpython.jit.backend.arm.locations import get_fp_offset +from rpython.jit.backend.arm.locations import get_fp_offset, imm, StackLocation from rpython.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, CoreRegisterManager, check_imm_arg, + VFPRegisterManager, operations as regalloc_operations, operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper @@ -21,7 +23,7 @@ from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.rlib import rgc from rpython.rlib.objectmodel import we_are_translated, specialize -from rpython.rtyper.annlowlevel import llhelper +from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi, llmemory from rpython.rtyper.lltypesystem.lloperation import llop from rpython.jit.backend.arm.opassembler import ResOpAssembler @@ -29,9 +31,8 @@ have_debug_prints, fatalerror) from rpython.rlib.jit import AsmInfo from rpython.rlib.objectmodel import compute_unique_id +from rpython.rlib.rarithmetic import intmask, r_uint -# XXX Move to llsupport -from rpython.jit.backend.x86.support import memcpy_fn DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), ('type', lltype.Char), # 'b'ridge, 'l'abel or @@ -41,51 +42,36 @@ class AssemblerARM(ResOpAssembler): - STACK_FIXED_AREA = -1 - - debug = True + debug = False def __init__(self, cpu, translate_support_code=False): - self.cpu = cpu + ResOpAssembler.__init__(self, cpu, translate_support_code) self.setup_failure_recovery() self.mc = None - self.memcpy_addr = 0 self.pending_guards = None self._exit_code_addr = 0 self.current_clt = None self.malloc_slowpath = 0 - self.wb_slowpath = [0, 0, 0, 0] + self.wb_slowpath = [0, 0, 0, 0, 0] self._regalloc = None self.datablockwrapper = None self.propagate_exception_path = 0 self.stack_check_slowpath = 0 - self._compute_stack_size() self._debug = False self.loop_run_counters = [] self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i') - self.force_token_to_dead_frame = {} # XXX temporary hack + self.gcrootmap_retaddr_forced = 0 def set_debug(self, v): r = self._debug self._debug = v return r - def _compute_stack_size(self): - self.STACK_FIXED_AREA = len(r.callee_saved_registers) * WORD - self.STACK_FIXED_AREA += WORD # FORCE_TOKEN - self.STACK_FIXED_AREA += N_REGISTERS_SAVED_BY_MALLOC * WORD - if self.cpu.supports_floats: - self.STACK_FIXED_AREA += (len(r.callee_saved_vfp_registers) - * DOUBLE_WORD) - if self.STACK_FIXED_AREA % 8 != 0: - self.STACK_FIXED_AREA += WORD # Stack alignment - assert self.STACK_FIXED_AREA % 8 == 0 - - def setup(self, looptoken, operations): + def setup(self, looptoken): + assert self.memcpy_addr != 0, 'setup_once() not called?' + if we_are_translated(): + self.debug = False self.current_clt = looptoken.compiled_loop_token - operations = self.cpu.gc_ll_descr.rewrite_assembler(self.cpu, - operations, self.current_clt.allgcrefs) - assert self.memcpy_addr != 0, 'setup_once() not called?' self.mc = ARMv7Builder() self.pending_guards = [] assert self.datablockwrapper is None @@ -93,7 +79,6 @@ self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) self.target_tokens_currently_compiling = {} - return operations def teardown(self): self.current_clt = None @@ -102,34 +87,8 @@ self.pending_guards = None assert self.datablockwrapper is None - def setup_once(self): - # Addresses of functions called by new_xxx operations - gc_ll_descr = self.cpu.gc_ll_descr - gc_ll_descr.initialize() - self._build_wb_slowpath(False) - self._build_wb_slowpath(True) - self._build_failure_recovery(exc=True, withfloats=False) - self._build_failure_recovery(exc=False, withfloats=False) - if self.cpu.supports_floats: - self._build_wb_slowpath(False, withfloats=True) - self._build_wb_slowpath(True, withfloats=True) - self._build_failure_recovery(exc=True, withfloats=True) - self._build_failure_recovery(exc=False, withfloats=True) - self._build_propagate_exception_path() - if gc_ll_descr.get_malloc_slowpath_addr is not None: - self._build_malloc_slowpath() - self._build_stack_check_slowpath() - if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack: - self._build_release_gil(gc_ll_descr.gcrootmap) - self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn) - - if not self._debug: - # if self._debug is already set it means that someone called - # set_debug by hand before initializing the assembler. Leave it - # as it is - debug_start('jit-backend-counts') - self.set_debug(have_debug_prints()) - debug_stop('jit-backend-counts') + def setup_failure_recovery(self): + self.failure_recovery_code = [0, 0, 0, 0] def finish_once(self): if self._debug: @@ -218,22 +177,84 @@ self.reacqgil_addr = rffi.cast(lltype.Signed, reacqgil_func) def _build_propagate_exception_path(self): - if self.cpu.propagate_exception_v < 0: + if not self.cpu.propagate_exception_descr: return # not supported (for tests, or non-translated) # mc = ARMv7Builder() - # - # Call the helper, which will return a dead frame object with - # the correct exception set, or MemoryError by default - # XXX make sure we return the correct value here - addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception()) - mc.BL(addr) - self.gen_func_epilog(mc=mc) - self.propagate_exception_path = mc.materialize(self.cpu.asmmemmgr, []) + self._store_and_reset_exception(mc, r.r0) + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + mc.LDR_ri(r.r0.value, r.fp.value, imm=ofs) + propagate_exception_descr = rffi.cast(lltype.Signed, + cast_instance_to_gcref(self.cpu.propagate_exception_descr)) + # put propagate_exception_descr into frame + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + mc.gen_load_int(r.r0.value, propagate_exception_descr) + mc.STR_ri(r.r0.value, r.fp.value, imm=ofs) + mc.MOV_rr(r.r0.value, r.fp.value) + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu.asmmemmgr, []) + self.propagate_exception_path = rawstart + + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + on_frame=False): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ + assert excvalloc is not r.ip + assert exctploc is not r.ip + tmpreg = r.lr + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if excvalloc is not None: # store + assert excvalloc.is_reg() + self.load_reg(mc, excvalloc, r.ip) + if on_frame: + # store exc_value in JITFRAME + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(ofs) + self.store_reg(mc, r.ip, r.fp, ofs) + if exctploc is not None: + # store pos_exception in exctploc + assert exctploc.is_reg() + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.load_reg(mc, exctploc, r.ip) + + # reset exception + mc.gen_load_int(tmpreg.value, 0) + + self.store_reg(mc, tmpreg, r.ip, 0) + + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, tmpreg, r.ip, 0) + + def _restore_exception(self, mc, excvalloc, exctploc): + assert excvalloc is not r.ip + assert exctploc is not r.ip + tmpreg = r.lr # use lr as a second temporary reg + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if excvalloc is not None: + assert excvalloc.is_reg() + self.store_reg(mc, excvalloc, r.ip) + else: + assert exctploc is not r.fp + # load exc_value from JITFRAME and put it in pos_exc_value + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + self.load_reg(mc, tmpreg, r.fp, ofs) + self.store_reg(mc, tmpreg, r.ip) + # reset exc_value in the JITFRAME + mc.gen_load_int(tmpreg.value, 0) + self.store_reg(mc, tmpreg, r.fp, ofs) + + # restore pos_exception from exctploc register + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, exctploc, r.ip) def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() - if slowpathaddr == 0 or self.cpu.propagate_exception_v < 0: + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: return # no stack check (for tests, or non-translated) # # make a "function" that is called immediately at the start of @@ -276,7 +297,7 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart - def _build_wb_slowpath(self, withcards, withfloats=False): + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): descr = self.cpu.gc_ll_descr.write_barrier_descr if descr is None: return @@ -295,12 +316,28 @@ # It must keep stack alignment accordingly. mc = ARMv7Builder() # - if withfloats: - floats = r.caller_vfp_resp + exc0 = exc1 = None + mc.PUSH([r.ip.value, r.lr.value]) # push two words to keep alignment + if not for_frame: + self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) else: - floats = [] - with saved_registers(mc, r.caller_resp + [r.ip, r.lr], floats): - mc.BL(func) + # we're possibly called from the slowpath of malloc + # save the caller saved registers + # assuming we do not collect here + exc0, exc1 = r.r4, r.r5 + mc.PUSH([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) + mc.VPUSH([vfpr.value for vfpr in r.caller_vfp_resp]) + + self._store_and_reset_exception(mc, exc0, exc1) + mc.BL(func) + # + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + self._restore_exception(mc, exc0, exc1) + mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + mc.POP([gpr.value for gpr in r.caller_resp] + + [exc0.value, exc1.value]) # if withcards: # A final TEST8 before the RET, for the caller. Careful to @@ -310,350 +347,174 @@ imm=descr.jit_wb_if_flag_byteofs) mc.TST_ri(r.ip.value, imm=0x80) # - mc.MOV_rr(r.pc.value, r.lr.value) + mc.POP([r.ip.value, r.pc.value]) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) - self.wb_slowpath[withcards + 2 * withfloats] = rawstart - - def setup_failure_recovery(self): - - #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold - def failure_recovery_func(mem_loc, frame_pointer, stack_pointer): - """mem_loc is a structure in memory describing where the values for - the failargs are stored. frame loc is the address of the frame - pointer for the frame to be decoded frame """ - vfp_registers = rffi.cast(rffi.LONGP, stack_pointer) - registers = rffi.ptradd(vfp_registers, 2*len(r.all_vfp_regs)) - registers = rffi.cast(rffi.LONGP, registers) - bytecode = rffi.cast(rffi.UCHARP, mem_loc) - return self.grab_frame_values(self.cpu, bytecode, frame_pointer, - registers, vfp_registers) - self.failure_recovery_code = [0, 0, 0, 0] - - self.failure_recovery_func = failure_recovery_func - - _FAILURE_RECOVERY_FUNC = lltype.Ptr(lltype.FuncType([rffi.LONGP] * 3, - llmemory.GCREF)) - - @staticmethod - #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold - def grab_frame_values(cpu, bytecode, frame_pointer, - registers, vfp_registers): - # no malloc allowed here!! xxx apart from one, hacking a lot - force_index = rffi.cast(lltype.Signed, frame_pointer) - num = 0 - deadframe = lltype.nullptr(jitframe.DEADFRAME) - # step 1: lots of mess just to count the final value of 'num' - bytecode1 = bytecode - while 1: - code = rffi.cast(lltype.Signed, bytecode1[0]) - bytecode1 = rffi.ptradd(bytecode1, 1) - if code >= AssemblerARM.CODE_FROMSTACK: - while code > 0x7F: - code = rffi.cast(lltype.Signed, bytecode1[0]) - bytecode1 = rffi.ptradd(bytecode1, 1) - else: - kind = code & 3 - if kind == AssemblerARM.DESCR_SPECIAL: - if code == AssemblerARM.CODE_HOLE: - num += 1 - continue - if code == AssemblerARM.CODE_INPUTARG: - continue - if code == AssemblerARM.CODE_FORCED: - # resuming from a GUARD_NOT_FORCED - token = force_index - deadframe = ( - cpu.assembler.force_token_to_dead_frame.pop(token)) - deadframe = lltype.cast_opaque_ptr( - jitframe.DEADFRAMEPTR, deadframe) - continue - assert code == AssemblerARM.CODE_STOP - break - num += 1 - - # allocate the deadframe - if not deadframe: - # Remove the "reserve" at the end of the nursery. This means - # that it is guaranteed that the following malloc() works - # without requiring a collect(), but it needs to be re-added - # as soon as possible. - cpu.gc_clear_extra_threshold() - assert num <= cpu.get_failargs_limit() - try: - deadframe = lltype.malloc(jitframe.DEADFRAME, num) - except MemoryError: - fatalerror("memory usage error in grab_frame_values") - # fill it - code_inputarg = False - num = 0 - value_hi = 0 - while 1: - # decode the next instruction from the bytecode - code = rffi.cast(lltype.Signed, bytecode[0]) - bytecode = rffi.ptradd(bytecode, 1) - if code >= AssemblerARM.CODE_FROMSTACK: - if code > 0x7F: - shift = 7 - code &= 0x7F - while True: - nextcode = rffi.cast(lltype.Signed, bytecode[0]) - bytecode = rffi.ptradd(bytecode, 1) - code |= (nextcode & 0x7F) << shift - shift += 7 - if nextcode <= 0x7F: - break - # load the value from the stack - kind = code & 3 - code = (code - AssemblerARM.CODE_FROMSTACK) >> 2 - if code_inputarg: - code = ~code - code_inputarg = False - stackloc = force_index - get_fp_offset(int(code)) - value = rffi.cast(rffi.LONGP, stackloc)[0] - if kind == AssemblerARM.DESCR_FLOAT: - assert WORD == 4 - value_hi = value - value = rffi.cast(rffi.LONGP, stackloc - WORD)[0] - else: - kind = code & 3 - if kind == AssemblerARM.DESCR_SPECIAL: - if code == AssemblerARM.CODE_HOLE: - num += 1 - continue - if code == AssemblerARM.CODE_INPUTARG: - code_inputarg = True - continue - if code == AssemblerARM.CODE_FORCED: - continue - assert code == AssemblerARM.CODE_STOP - break - # 'code' identifies a register: load its value - code >>= 2 - if kind == AssemblerARM.DESCR_FLOAT: - if WORD == 4: - value = vfp_registers[2*code] - value_hi = vfp_registers[2*code + 1] - else: - value = registers[code] - else: - value = registers[code] - # store the loaded value into fail_boxes_ - if kind == AssemblerARM.DESCR_INT: - deadframe.jf_values[num].int = value - elif kind == AssemblerARM.DESCR_REF: - deadframe.jf_values[num].ref = rffi.cast(llmemory.GCREF, value) - elif kind == AssemblerARM.DESCR_FLOAT: - assert WORD == 4 - assert not longlong.is_64_bit - floatvalue = rffi.cast(lltype.SignedLongLong, value_hi) - floatvalue <<= 32 - floatvalue |= rffi.cast(lltype.SignedLongLong, - rffi.cast(lltype.Unsigned, value)) - deadframe.jf_values[num].float = floatvalue - else: - assert 0, "bogus kind" - num += 1 - # - assert num == len(deadframe.jf_values) - if not we_are_translated(): - assert bytecode[4] == 0xCC - fail_index = rffi.cast(rffi.INTP, bytecode)[0] - fail_descr = cpu.get_fail_descr_from_number(fail_index) - deadframe.jf_descr = fail_descr.hide(cpu) - return lltype.cast_opaque_ptr(llmemory.GCREF, deadframe) - - def decode_inputargs(self, code): - descr_to_box_type = [REF, INT, FLOAT] - bytecode = rffi.cast(rffi.UCHARP, code) - arglocs = [] - code_inputarg = False - while 1: - # decode the next instruction from the bytecode - code = rffi.cast(lltype.Signed, bytecode[0]) - bytecode = rffi.ptradd(bytecode, 1) - if code >= self.CODE_FROMSTACK: - # 'code' identifies a stack location - if code > 0x7F: - shift = 7 - code &= 0x7F - while True: - nextcode = rffi.cast(lltype.Signed, bytecode[0]) - bytecode = rffi.ptradd(bytecode, 1) - code |= (nextcode & 0x7F) << shift - shift += 7 - if nextcode <= 0x7F: - break - kind = code & 3 - code = (code - self.CODE_FROMSTACK) >> 2 - if code_inputarg: - code = ~code - code_inputarg = False - loc = ARMFrameManager.frame_pos(code, descr_to_box_type[kind]) - elif code == self.CODE_STOP: - break - elif code == self.CODE_HOLE: - continue - elif code == self.CODE_INPUTARG: - code_inputarg = True - continue - else: - # 'code' identifies a register - kind = code & 3 - code >>= 2 - if kind == self.DESCR_FLOAT: - loc = r.all_vfp_regs[code] - else: - loc = r.all_regs[code] - arglocs.append(loc) - return arglocs[:] + if for_frame: + self.wb_slowpath[4] = rawstart + else: + self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): mc = ARMv7Builder() - if self.cpu.supports_floats: - vfp_regs = r.all_vfp_regs - else: - vfp_regs = [] + self._push_all_regs_to_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + # store the gc pattern + mc.POP([r.r2.value]) + self.store_reg(mc, r.r2, r.fp, ofs) # We need to push two registers here because we are going to make a # call an therefore the stack needs to be 8-byte aligned mc.PUSH([r.ip.value, r.lr.value]) - with saved_registers(mc, [], vfp_regs): - # At this point we know that the values we need to compute the size - # are stored in r0 and r1. - mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value) - addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() - for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items(): - mc.STR_ri(reg.value, r.fp.value, imm=ofs) - mc.BL(addr) - for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items(): - mc.LDR_ri(reg.value, r.fp.value, imm=ofs) + # At this point we know that the values we need to compute the size + # are stored in r0 and r1. + mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value) # compute the size we want + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_rr(r.r1.value, r.fp.value) + + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() + mc.BL(addr) + + # + # If the slowpath malloc failed, we raise a MemoryError that + # always interrupts the current loop, as a "good enough" + # approximation. mc.CMP_ri(r.r0.value, 0) mc.B(self.propagate_exception_path, c=c.EQ) + # + self._reload_frame_if_necessary(mc, align_stack=True) + self._pop_all_regs_from_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) + # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() mc.gen_load_int(r.r1.value, nursery_free_adr) mc.LDR_ri(r.r1.value, r.r1.value) - # see above + # clear the gc pattern + mc.gen_load_int(r.ip.value, 0) + self.store_reg(mc, r.ip, r.fp, ofs) + # return mc.POP([r.ip.value, r.pc.value]) rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.malloc_slowpath = rawstart + def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(r.ip.value, rst) + self.load_reg(mc, r.ip, r.ip) + self.load_reg(mc, r.fp, r.ip, ofs=-WORD) + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + if gcrootmap and wbdescr: + # frame never uses card marking, so we enforce this is not + # an array + self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False, + is_frame=True)#, align_stack=align_stack) + def propagate_memoryerror_if_r0_is_null(self): # see ../x86/assembler.py:propagate_memoryerror_if_eax_is_null self.mc.CMP_ri(r.r0.value, 0) self.mc.B(self.propagate_exception_path, c=c.EQ) + def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX use STMDB ops here + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD) + if withfloats: + if callee_only: + regs = VFPRegisterManager.save_around_call_regs + else: + regs = VFPRegisterManager.all_regs + for i, vfpr in enumerate(regs): + if vfpr in ignored_regs: + continue + ofs = len(CoreRegisterManager.all_regs) * WORD + ofs += i * DOUBLE_WORD + base_ofs + self.store_reg(mc, vfpr, r.fp, ofs) + + def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Pop all general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX use LDMDB ops here + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + ofs = i * WORD + base_ofs + self.load_reg(mc, gpr, r.fp, ofs) + if withfloats: + # Pop all XMM regs + if callee_only: + regs = VFPRegisterManager.save_around_call_regs + else: + regs = VFPRegisterManager.all_regs + for i, vfpr in enumerate(regs): + if vfpr in ignored_regs: + continue + ofs = len(CoreRegisterManager.all_regs) * WORD + ofs += i * DOUBLE_WORD + base_ofs + self.load_reg(mc, vfpr, r.fp, ofs) + def _build_failure_recovery(self, exc, withfloats=False): mc = ARMv7Builder() - failure_recovery = llhelper(self._FAILURE_RECOVERY_FUNC, - self.failure_recovery_func) - self._insert_checks(mc) - if withfloats: - f = r.all_vfp_regs - else: - f = [] - with saved_registers(mc, r.all_regs, f): - if exc: - # We might have an exception pending. Load it into r4 - # (this is a register saved across calls) - mc.gen_load_int(r.r5.value, self.cpu.pos_exc_value()) - mc.LDR_ri(r.r4.value, self.cpu.pos_exc_value()) - # clear the exc flags - mc.gen_load_int(r.r6.value, 0) - mc.STR_ri(r.r6.value, r.r5.value) - mc.gen_load_int(r.r5.value, self.cpu.pos_exception()) - mc.STR_ri(r.r6.value, r.r5.value) - # move mem block address, to r0 to pass as - mc.MOV_rr(r.r0.value, r.lr.value) - # pass the current frame pointer as second param - mc.MOV_rr(r.r1.value, r.fp.value) - # pass the current stack pointer as third param - mc.MOV_rr(r.r2.value, r.sp.value) - self._insert_checks(mc) - mc.BL(rffi.cast(lltype.Signed, failure_recovery)) - if exc: - # save ebx into 'jf_guard_exc' - from rpython.jit.backend.llsupport.descr import unpack_fielddescr - descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) - offset, size, _ = unpack_fielddescr(descrs.jf_guard_exc) - mc.STR_rr(r.r4.value, r.r0.value, offset, cond=c.AL) - mc.MOV_rr(r.ip.value, r.r0.value) - mc.MOV_rr(r.r0.value, r.ip.value) - self.gen_func_epilog(mc=mc) - rawstart = mc.materialize(self.cpu.asmmemmgr, [], - self.cpu.gc_ll_descr.gcrootmap) + self._push_all_regs_to_jitframe(mc, [], withfloats) + + if exc: + # We might have an exception pending. Load it into r4 + # (this is a register saved across calls) + mc.gen_load_int(r.r5.value, self.cpu.pos_exc_value()) + mc.LDR_ri(r.r4.value, r.r5.value) + # clear the exc flags + mc.gen_load_int(r.r6.value, 0) + mc.STR_ri(r.r6.value, r.r5.value) # pos_exc_value is still in r5 + mc.gen_load_int(r.r5.value, self.cpu.pos_exception()) + mc.STR_ri(r.r6.value, r.r5.value) + # save r4 into 'jf_guard_exc' + offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(abs(offset)) + mc.STR_ri(r.r4.value, r.fp.value, imm=offset) + # now we return from the complete frame, which starts from + # _call_header_with_stack_check(). The LEA in _call_footer below + # throws away most of the frame, including all the PUSHes that we + # did just above. + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + assert check_imm_arg(abs(ofs)) + ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap') + assert check_imm_arg(abs(ofs2)) + base_ofs = self.cpu.get_baseofs_of_frame_field() + # store the gcmap + mc.POP([r.ip.value]) + mc.STR_ri(r.ip.value, r.fp.value, imm=ofs2) + # store the descr + mc.POP([r.ip.value]) + mc.STR_ri(r.ip.value, r.fp.value, imm=ofs) + + # set return value + assert check_imm_arg(base_ofs) + mc.MOV_rr(r.r0.value, r.fp.value) + # + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.failure_recovery_code[exc + 2 * withfloats] = rawstart - self.mc = None - DESCR_REF = 0x00 - DESCR_INT = 0x01 - DESCR_FLOAT = 0x02 - DESCR_SPECIAL = 0x03 - CODE_FROMSTACK = 64 - CODE_STOP = 0 | DESCR_SPECIAL - CODE_HOLE = 4 | DESCR_SPECIAL - CODE_INPUTARG = 8 | DESCR_SPECIAL - CODE_FORCED = 12 | DESCR_SPECIAL #XXX where should this be written? - - def write_failure_recovery_description(self, descr, failargs, locs): - assert self.mc is not None - for i in range(len(failargs)): - arg = failargs[i] - if arg is not None: - if arg.type == REF: - kind = self.DESCR_REF - elif arg.type == INT: - kind = self.DESCR_INT - elif arg.type == FLOAT: - kind = self.DESCR_FLOAT - else: - raise AssertionError("bogus kind") - loc = locs[i] - if loc.is_stack(): - pos = loc.position - if pos < 0: - self.mc.writechar(chr(self.CODE_INPUTARG)) - pos = ~pos - n = self.CODE_FROMSTACK // 4 + pos - else: - assert loc.is_reg() or loc.is_vfp_reg() - n = loc.value - n = kind + 4 * n - while n > 0x7F: - self.mc.writechar(chr((n & 0x7F) | 0x80)) - n >>= 7 - else: - n = self.CODE_HOLE - self.mc.writechar(chr(n)) - self.mc.writechar(chr(self.CODE_STOP)) - - - def generate_quick_failure(self, guardtok, fcond=c.AL): - assert isinstance(guardtok.save_exc, bool) - fail_index = self.cpu.get_fail_descr_number(guardtok.descr) + def generate_quick_failure(self, guardtok): startpos = self.mc.currpos() - withfloats = False - for box in guardtok.failargs: - if box is not None and box.type == FLOAT: - withfloats = True - break - exc = guardtok.save_exc - target = self.failure_recovery_code[exc + 2 * withfloats] - assert target != 0 + fail_descr, target = self.store_info_on_descr(startpos, guardtok) + self.regalloc_push(imm(fail_descr)) + self.push_gcmap(self.mc, gcmap=guardtok.gcmap, push=True) self.mc.BL(target) - # write tight data that describes the failure recovery - if guardtok.is_guard_not_forced: - self.mc.writechar(chr(self.CODE_FORCED)) - self.write_failure_recovery_description(guardtok.descr, - guardtok.failargs, guardtok.faillocs[1:]) - self.mc.write32(fail_index) - # for testing the decoding, write a final byte 0xCC - if not we_are_translated(): - self.mc.writechar('\xCC') - faillocs = [loc for loc in guardtok.faillocs if loc is not None] - guardtok.descr._arm_debug_faillocs = faillocs - self.align() return startpos def align(self): @@ -661,37 +522,35 @@ self.mc.writechar(chr(0)) def gen_func_epilog(self, mc=None, cond=c.AL): - stack_size = self.STACK_FIXED_AREA - stack_size -= len(r.callee_saved_registers) * WORD - if self.cpu.supports_floats: - stack_size -= len(r.callee_saved_vfp_registers) * 2 * WORD - gcrootmap = self.cpu.gc_ll_descr.gcrootmap if mc is None: mc = self.mc if gcrootmap and gcrootmap.is_shadow_stack: self.gen_footer_shadowstack(gcrootmap, mc) - mc.MOV_rr(r.sp.value, r.fp.value, cond=cond) - mc.ADD_ri(r.sp.value, r.sp.value, stack_size, cond=cond) if self.cpu.supports_floats: mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond) - mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond) + # push all callee saved registers and IP to keep the alignment + mc.POP([reg.value for reg in r.callee_restored_registers] + + [r.ip.value], cond=cond) + mc.BKPT() def gen_func_prolog(self): - stack_size = self.STACK_FIXED_AREA - stack_size -= len(r.callee_saved_registers) * WORD + stack_size = WORD #alignment + stack_size += len(r.callee_saved_registers) * WORD if self.cpu.supports_floats: - stack_size -= len(r.callee_saved_vfp_registers) * 2 * WORD + stack_size += len(r.callee_saved_vfp_registers) * 2 * WORD - self.mc.PUSH([reg.value for reg in r.callee_saved_registers]) + # push all callee saved registers and IP to keep the alignment + self.mc.PUSH([reg.value for reg in r.callee_saved_registers] + + [r.ip.value]) if self.cpu.supports_floats: self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers]) - # here we modify the stack pointer to leave room for the 9 registers - # that are going to be saved here around malloc calls and one word to - # store the force index - self.mc.SUB_ri(r.sp.value, r.sp.value, stack_size) - self.mc.MOV_rr(r.fp.value, r.sp.value) + assert stack_size % 8 == 0 # ensure we keep alignment + + # set fp to point to the JITFRAME + self.mc.MOV_rr(r.fp.value, r.r0.value) + # gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: self.gen_shadowstack_header(gcrootmap) @@ -699,25 +558,24 @@ def gen_shadowstack_header(self, gcrootmap): # we need to put two words into the shadowstack: the MARKER_FRAME # and the address of the frame (fp, actually) + # lr = rst addr + # ip = *lr rst = gcrootmap.get_root_stack_top_addr() - self.mc.gen_load_int(r.ip.value, rst) - self.mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop] + self.mc.gen_load_int(r.lr.value, rst) + self.load_reg(self.mc, r.ip, r.lr) + # *ip = r.fp + self.store_reg(self.mc, r.fp, r.ip) # - MARKER = gcrootmap.MARKER_FRAME - self.mc.ADD_ri(r.r5.value, r.r4.value, - imm=2 * WORD) # ADD r5, r4 [2*WORD] - self.mc.gen_load_int(r.r6.value, MARKER) - self.mc.STR_ri(r.r6.value, r.r4.value, WORD) # STR MARKER, r4 [WORD] - self.mc.STR_ri(r.fp.value, r.r4.value) # STR fp, r4 - # - self.mc.STR_ri(r.r5.value, r.ip.value) # STR r5 [rootstacktop] + self.mc.ADD_ri(r.ip.value, r.ip.value, WORD) + # *lr = ip + WORD + self.store_reg(self.mc, r.ip, r.lr) def gen_footer_shadowstack(self, gcrootmap, mc): rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip.value, rst) - mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop] - mc.SUB_ri(r.r5.value, r.r4.value, imm=2 * WORD) # ADD r5, r4 [2*WORD] - mc.STR_ri(r.r5.value, r.ip.value) + self.load_reg(mc, r.r4, r.ip) + mc.SUB_ri(r.r4.value, r.r4.value, WORD) + self.store_reg(mc, r.r4, r.ip) def _dump(self, ops, type='loop'): debug_start('jit-backend-ops') @@ -754,7 +612,6 @@ # cpu interface def assemble_loop(self, loopname, inputargs, operations, looptoken, log): clt = CompiledLoopToken(self.cpu, looptoken.number) - clt.allgcrefs = [] looptoken.compiled_loop_token = clt clt._debug_nbargs = len(inputargs) @@ -762,133 +619,254 @@ # Arguments should be unique assert len(set(inputargs)) == len(inputargs) - operations = self.setup(looptoken, operations) - if log: + self.setup(looptoken) + + frame_info = self.datablockwrapper.malloc_aligned( + jitframe.JITFRAMEINFO_SIZE, alignment=WORD) + clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) + clt.allgcrefs = [] + clt.frame_info.clear() # for now + + if False and log: operations = self._inject_debugging_code(looptoken, operations, 'e', looptoken.number) self._call_header_with_stack_check() - sp_patch_location = self._prepare_sp_patch_position() - regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager()) - regalloc.prepare_loop(inputargs, operations) + regalloc = Regalloc(assembler=self) + operations = regalloc.prepare_loop(inputargs, operations, looptoken, + clt.allgcrefs) loop_head = self.mc.get_relative_pos() - looptoken._arm_loop_code = loop_head + looptoken._ll_loop_code = loop_head # - clt.frame_depth = -1 - frame_depth = self._assemble(operations, regalloc) - clt.frame_depth = frame_depth + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) # size_excluding_failure_stuff = self.mc.get_relative_pos() - self._patch_sp_offset(sp_patch_location, frame_depth) self.write_pending_failure_recoveries() rawstart = self.materialize_loop(looptoken) - looptoken._arm_func_addr = rawstart + looptoken._function_addr = looptoken._ll_function_addr = rawstart self.process_pending_guards(rawstart) self.fixup_target_tokens(rawstart) if log and not we_are_translated(): self.mc._dump_trace(rawstart, - 'loop_%s.asm' % self.cpu.total_compiled_loops) + 'loop.asm') ops_offset = self.mc.ops_offset self.teardown() debug_start("jit-backend-addr") - debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( + debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( looptoken.number, loopname, - rawstart + loop_head, - rawstart + size_excluding_failure_stuff, - rawstart)) + r_uint(rawstart + loop_head), + r_uint(rawstart + size_excluding_failure_stuff), + r_uint(rawstart))) debug_stop("jit-backend-addr") return AsmInfo(ops_offset, rawstart + loop_head, size_excluding_failure_stuff - loop_head) - def _assemble(self, operations, regalloc): + def _assemble(self, regalloc, inputargs, operations): regalloc.compute_hint_frame_locations(operations) - self._walk_operations(operations, regalloc) - frame_depth = regalloc.frame_manager.get_frame_depth() + self._walk_operations(inputargs, operations, regalloc) + frame_depth = regalloc.get_final_frame_depth() jump_target_descr = regalloc.jump_target_descr if jump_target_descr is not None: - frame_depth = max(frame_depth, - jump_target_descr._arm_clt.frame_depth) + tgt_depth = jump_target_descr._arm_clt.frame_info.jfi_frame_depth + target_frame_depth = tgt_depth - JITFRAME_FIXED_SIZE + frame_depth = max(frame_depth, target_frame_depth) return frame_depth def assemble_bridge(self, faildescr, inputargs, operations, original_loop_token, log): - operations = self.setup(original_loop_token, operations) - descr_number = self.cpu.get_fail_descr_number(faildescr) + if not we_are_translated(): + # Arguments should be unique + assert len(set(inputargs)) == len(inputargs) + + self.setup(original_loop_token) + descr_number = compute_unique_id(faildescr) if log: operations = self._inject_debugging_code(faildescr, operations, 'b', descr_number) + assert isinstance(faildescr, AbstractFailDescr) - code = self._find_failure_recovery_bytecode(faildescr) - frame_depth = faildescr._arm_current_frame_depth - arglocs = self.decode_inputargs(code) - if not we_are_translated(): - assert len(inputargs) == len(arglocs) - regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager()) - regalloc.prepare_bridge(inputargs, arglocs, operations) + arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) - sp_patch_location = self._prepare_sp_patch_position() + regalloc = Regalloc(assembler=self) + startpos = self.mc.get_relative_pos() + operations = regalloc.prepare_bridge(inputargs, arglocs, + operations, + self.current_clt.allgcrefs, + self.current_clt.frame_info) - startpos = self.mc.get_relative_pos() + stack_check_patch_ofs = self._check_frame_depth(self.mc, + regalloc.get_gcmap()) - frame_depth = self._assemble(operations, regalloc) + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() - self._patch_sp_offset(sp_patch_location, frame_depth) - self.write_pending_failure_recoveries() rawstart = self.materialize_loop(original_loop_token) self.process_pending_guards(rawstart) - self.fixup_target_tokens(rawstart) + # patch the jump from original guard self.patch_trace(faildescr, original_loop_token, rawstart, regalloc) if not we_are_translated(): - # for the benefit of tests - faildescr._arm_bridge_frame_depth = frame_depth if log: - self.mc._dump_trace(rawstart, 'bridge_%d.asm' % - self.cpu.total_compiled_bridges) - self.current_clt.frame_depth = max(self.current_clt.frame_depth, - frame_depth) + self.mc._dump_trace(rawstart, 'bridge.asm') + ops_offset = self.mc.ops_offset + frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, + frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + self.fixup_target_tokens(rawstart) + self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth) + self.update_frame_depth(frame_depth) self.teardown() debug_start("jit-backend-addr") - debug_print("bridge out of Guard %d has address %x to %x" % - (descr_number, rawstart, rawstart + codeendpos)) + debug_print("bridge out of Guard %d has address 0x%x to 0x%x" % + (descr_number, r_uint(rawstart), + r_uint(rawstart + codeendpos))) debug_stop("jit-backend-addr") return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) - def _find_failure_recovery_bytecode(self, faildescr): - guard_stub_addr = faildescr._arm_failure_recovery_block - if guard_stub_addr == 0: - # This case should be prevented by the logic in compile.py: - # look for CNT_BUSY_FLAG, which disables tracing from a guard - # when another tracing from the same guard is already in progress. - raise BridgeAlreadyCompiled - # a guard requires 3 words to encode the jump to the exit code. - return guard_stub_addr + 3 * WORD + def new_stack_loc(self, i, pos, tp): + base_ofs = self.cpu.get_baseofs_of_frame_field() + return StackLocation(i, pos + base_ofs, tp) + + def check_frame_before_jump(self, target_token): + if target_token in self.target_tokens_currently_compiling: + return + if target_token._arm_clt is self.current_clt: + return + # We can have a frame coming from god knows where that's + # passed to a jump to another loop. Make sure it has the + # correct depth + expected_size = target_token._arm_clt.frame_info.jfi_frame_depth + self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), + expected_size=expected_size) + + + def _check_frame_depth(self, mc, gcmap, expected_size=-1): + """ check if the frame is of enough depth to follow this bridge. + Otherwise reallocate the frame in a helper. + There are other potential solutions + to that, but this one does not sound too bad. + """ + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) + stack_check_cmp_ofs = mc.currpos() + if expected_size == -1: + mc.NOP() + mc.NOP() + else: + mc.gen_load_int(r.lr.value, expected_size) + mc.CMP_rr(r.ip.value, r.lr.value) + + jg_location = mc.currpos() + mc.BKPT() + + # the size value is still stored in lr + mc.PUSH([r.lr.value]) + + self.push_gcmap(mc, gcmap, push=True) + + self.mc.BL(self._frame_realloc_slowpath) + + # patch jg_location above + currpos = self.mc.currpos() + pmc = OverwritingBuilder(mc, jg_location, WORD) + pmc.B_offs(currpos, c.GE) + + return stack_check_cmp_ofs + + def build_frame_realloc_slowpath(self): + # this code should do the following steps + # a) store all registers in the jitframe + # b) fish for the arguments passed by the caller + # c) store the gcmap in the jitframe + # d) call realloc_frame + # e) set the fp to point to the new jitframe + # f) store the address of the new jitframe in the shadowstack + # c) set the gcmap field to 0 in the new jitframe + # g) restore registers and return + mc = ARMv7Builder() + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) + # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame + # and the expected_size pushed in _check_stack_frame + # pop the values passed on the stack, gcmap -> r0, expected_size -> r1 + mc.POP([r.r0.value, r.r1.value]) + # store return address and keep the stack aligned + mc.PUSH([r.ip.value, r.lr.value]) + + # store the current gcmap(r0) in the jitframe + gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + assert check_imm_arg(abs(gcmap_ofs)) + mc.STR_ri(r.r0.value, r.fp.value, imm=gcmap_ofs) + + # set first arg, which is the old jitframe address + mc.MOV_rr(r.r0.value, r.fp.value) + + # store a possibly present exception + # we use a callee saved reg here as a tmp for the exc. + self._store_and_reset_exception(mc, None, r.r4, on_frame=True) + + # call realloc_frame, it takes two arguments + # arg0: the old jitframe + # arg1: the new size + # + mc.BL(self.cpu.realloc_frame) + + # set fp to the new jitframe returned from the previous call + mc.MOV_rr(r.fp.value, r.r0.value) + + # restore a possibly present exception + self._restore_exception(mc, None, r.r4) + + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self._load_shadowstack_top(mc, r.r5, gcrootmap) + # store the new jitframe addr in the shadowstack + mc.STR_ri(r.r0.value, r.r5.value, imm=-WORD) + + # reset the jf_gcmap field in the jitframe + mc.gen_load_int(r.ip.value, 0) + mc.STR_ri(r.ip.value, r.fp.value, imm=gcmap_ofs) + + # restore registers + self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) + mc.POP([r.ip.value, r.pc.value]) # return + self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, []) + + def _load_shadowstack_top(self, mc, reg, gcrootmap): + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(reg.value, rst) + mc.gen_load_int(reg.value, reg.value) + return rst def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: - targettoken._arm_loop_code += rawstart + targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None + def _patch_stackadjust(self, adr, allocated_depth): + mc = ARMv7Builder() + mc.gen_load_int(r.lr.value, allocated_depth) + mc.copy_to_raw_memory(adr) + def target_arglocs(self, loop_token): return loop_token._arm_arglocs @@ -899,17 +877,19 @@ return self.mc.materialize(self.cpu.asmmemmgr, allblocks, self.cpu.gc_ll_descr.gcrootmap) + def update_frame_depth(self, frame_depth): + baseofs = self.cpu.get_baseofs_of_frame_field() + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) + def write_pending_failure_recoveries(self): for tok in self.pending_guards: #generate the exit stub and the encoded representation tok.pos_recovery_stub = self.generate_quick_failure(tok) - # store info on the descr - tok.descr._arm_current_frame_depth = tok.faillocs[0].getint() def process_pending_guards(self, block_start): clt = self.current_clt for tok in self.pending_guards: - descr = tok.descr + descr = tok.faildescr assert isinstance(descr, AbstractFailDescr) failure_recovery_pos = block_start + tok.pos_recovery_stub descr._arm_failure_recovery_block = failure_recovery_pos @@ -931,48 +911,7 @@ clt.asmmemmgr_blocks = [] return clt.asmmemmgr_blocks - def _prepare_sp_patch_position(self): - """Generate NOPs as placeholder to patch the instruction(s) to update - the sp according to the number of spilled variables""" - size = (self.mc.size_of_gen_load_int + WORD) - l = self.mc.currpos() - for _ in range(size // WORD): - self.mc.NOP() - return l - - def _patch_sp_offset(self, pos, frame_depth): - cb = OverwritingBuilder(self.mc, pos, - OverwritingBuilder.size_of_gen_load_int + WORD) - n = frame_depth * WORD - - # ensure the sp is 8 byte aligned when patching it - if n % 8 != 0: - n += WORD - assert n % 8 == 0 - - self._adjust_sp(n, cb, base_reg=r.fp) - - def _adjust_sp(self, n, cb=None, fcond=c.AL, base_reg=r.sp): - if cb is None: - cb = self.mc - if n < 0: - n = -n - rev = True - else: - rev = False - if n <= 0xFF and fcond == c.AL: - if rev: - cb.ADD_ri(r.sp.value, base_reg.value, n) - else: - cb.SUB_ri(r.sp.value, base_reg.value, n) - else: - cb.gen_load_int(r.ip.value, n, cond=fcond) - if rev: - cb.ADD_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond) - else: - cb.SUB_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond) - - def _walk_operations(self, operations, regalloc): + def _walk_operations(self, inputargs, operations, regalloc): fcond = c.AL self._regalloc = regalloc while regalloc.position() < len(operations) - 1: @@ -983,7 +922,7 @@ opnum = op.getopnum() if op.has_no_side_effect() and op.result not in regalloc.longevity: regalloc.possibly_free_vars_for_op(op) - elif self.can_merge_with_next_guard(op, i, operations): + elif self._regalloc.can_merge_with_next_guard(op, i, operations): guard = operations[i + 1] assert guard.is_guard() arglocs = regalloc_operations_with_guard[opnum](regalloc, op, @@ -1009,31 +948,6 @@ regalloc._check_invariants() self.mc.mark_op(None) # end of the loop - # from ../x86/regalloc.py - def can_merge_with_next_guard(self, op, i, operations): - if (op.getopnum() == rop.CALL_MAY_FORCE or - op.getopnum() == rop.CALL_ASSEMBLER or - op.getopnum() == rop.CALL_RELEASE_GIL): - assert operations[i + 1].getopnum() == rop.GUARD_NOT_FORCED - return True - if not op.is_comparison(): - if op.is_ovf(): - if (operations[i + 1].getopnum() != rop.GUARD_NO_OVERFLOW and - operations[i + 1].getopnum() != rop.GUARD_OVERFLOW): - not_implemented("int_xxx_ovf not followed by " - "guard_(no)_overflow") - return True - return False - if (operations[i + 1].getopnum() != rop.GUARD_TRUE and - operations[i + 1].getopnum() != rop.GUARD_FALSE): - return False - if operations[i + 1].getarg(0) is not op.result: - return False - if (self._regalloc.longevity[op.result][1] > i + 1 or - op.result in operations[i + 1].getfailargs()): - return False - return True - def regalloc_emit_llong(self, op, arglocs, fcond, regalloc): effectinfo = op.getdescr().get_extra_info() oopspecindex = effectinfo.oopspecindex @@ -1046,15 +960,6 @@ asm_math_operations[oopspecindex](self, op, arglocs, regalloc, fcond) return fcond - - def _insert_checks(self, mc=None): - if not we_are_translated() and self._debug: - if mc is None: - mc = self.mc - mc.CMP_rr(r.fp.value, r.sp.value) - mc.MOV_rr(r.pc.value, r.pc.value, cond=c.GE) - mc.BKPT() - def _ensure_result_bit_extension(self, resloc, size, signed): if size == 4: return @@ -1082,6 +987,7 @@ # regalloc support def load(self, loc, value): + """load an immediate value into a register""" assert (loc.is_reg() and value.is_imm() or loc.is_vfp_reg() and value.is_imm_float()) if value.is_imm(): @@ -1090,6 +996,48 @@ self.mc.gen_load_int(r.ip.value, value.getint()) self.mc.VLDR(loc.value, r.ip.value) + def load_reg(self, mc, target, base, ofs=0, cond=c.AL, helper=r.ip): + if target.is_vfp_reg(): + return self._load_vfp_reg(mc, target, base, ofs, cond, helper) + elif target.is_reg(): + return self._load_core_reg(mc, target, base, ofs, cond, helper) + + def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VLDR(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.ADD_rr(helper.value, base.value, helper.value, cond=cond) + mc.VLDR(target.value, helper.value, cond=cond) + + def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(abs(ofs)): + mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.LDR_rr(target.value, base.value, helper.value, cond=cond) + + def store_reg(self, mc, source, base, ofs=0, cond=c.AL, helper=r.ip): + if source.is_vfp_reg(): + return self._store_vfp_reg(mc, source, base, ofs, cond, helper) + else: + return self._store_core_reg(mc, source, base, ofs, cond, helper) + + def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VSTR(source.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.ADD_rr(helper.value, base.value, helper.value, cond=cond) + mc.VSTR(source.value, helper.value, cond=cond) + + def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.STR_rr(source.value, base.value, helper.value, cond=cond) + def _mov_imm_to_loc(self, prev_loc, loc, cond=c.AL): if not loc.is_reg() and not (loc.is_stack() and loc.type != FLOAT): raise AssertionError("invalid target for move from imm value") @@ -1117,15 +1065,12 @@ else: temp = r.ip offset = loc.value - if not check_imm_arg(offset, size=0xFFF): + is_imm = check_imm_arg(offset, size=0xFFF) + if not is_imm: self.mc.PUSH([temp.value], cond=cond) - self.mc.gen_load_int(temp.value, -offset, cond=cond) - self.mc.STR_rr(prev_loc.value, r.fp.value, - temp.value, cond=cond) + self.store_reg(self.mc, prev_loc, r.fp, offset, helper=temp, cond=cond) + if not is_imm: self.mc.POP([temp.value], cond=cond) - else: - self.mc.STR_ri(prev_loc.value, r.fp.value, - imm=-offset, cond=cond) else: assert 0, 'unsupported case' @@ -1138,29 +1083,22 @@ when moving from the stack' # unspill a core register offset = prev_loc.value - if not check_imm_arg(offset, size=0xFFF): + is_imm = check_imm_arg(offset, size=0xFFF) + if not is_imm: self.mc.PUSH([r.lr.value], cond=cond) - pushed = True - self.mc.gen_load_int(r.lr.value, -offset, cond=cond) - self.mc.LDR_rr(loc.value, r.fp.value, r.lr.value, cond=cond) - else: - self.mc.LDR_ri(loc.value, r.fp.value, imm=-offset, cond=cond) - if pushed: + self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.lr) + if not is_imm: self.mc.POP([r.lr.value], cond=cond) elif loc.is_vfp_reg(): assert prev_loc.type == FLOAT, 'trying to load from an \ incompatible location into a float register' # load spilled value into vfp reg offset = prev_loc.value - self.mc.PUSH([r.ip.value], cond=cond) - pushed = True - if not check_imm_arg(offset): - self.mc.gen_load_int(r.ip.value, offset, cond=cond) - self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) - else: - self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond) - self.mc.VLDR(loc.value, r.ip.value, cond=cond) - if pushed: + is_imm = check_imm_arg(offset) + if not is_imm: + self.mc.PUSH([r.ip.value], cond=cond) + self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.ip) + if not is_imm: self.mc.POP([r.ip.value], cond=cond) else: assert 0, 'unsupported case' @@ -1169,7 +1107,7 @@ if loc.is_vfp_reg(): self.mc.PUSH([r.ip.value], cond=cond) self.mc.gen_load_int(r.ip.value, prev_loc.getint(), cond=cond) - self.mc.VLDR(loc.value, r.ip.value, cond=cond) + self.load_reg(self.mc, loc, r.ip, 0, cond=cond) self.mc.POP([r.ip.value], cond=cond) elif loc.is_stack(): self.regalloc_push(r.vfp_ip) @@ -1186,15 +1124,13 @@ assert loc.type == FLOAT, 'trying to store to an \ incompatible location from a float register' # spill vfp register - self.mc.PUSH([r.ip.value], cond=cond) offset = loc.value - if not check_imm_arg(offset): - self.mc.gen_load_int(r.ip.value, offset, cond=cond) - self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) - else: - self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond) - self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond) - self.mc.POP([r.ip.value], cond=cond) + is_imm = check_imm_arg(offset) + if not is_imm: + self.mc.PUSH([r.ip.value], cond=cond) + self.store_reg(self.mc, prev_loc, r.fp, offset, cond=cond) + if not is_imm: + self.mc.POP([r.ip.value], cond=cond) else: assert 0, 'unsupported case' @@ -1233,15 +1169,15 @@ offset = vfp_loc.value if not check_imm_arg(offset, size=0xFFF): self.mc.PUSH([r.ip.value], cond=cond) - self.mc.gen_load_int(r.ip.value, -offset, cond=cond) + self.mc.gen_load_int(r.ip.value, offset, cond=cond) self.mc.LDR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond) self.mc.ADD_ri(r.ip.value, r.ip.value, imm=WORD, cond=cond) self.mc.LDR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond) self.mc.POP([r.ip.value], cond=cond) else: - self.mc.LDR_ri(reg1.value, r.fp.value, imm=-offset, cond=cond) + self.mc.LDR_ri(reg1.value, r.fp.value, imm=offset, cond=cond) self.mc.LDR_ri(reg2.value, r.fp.value, - imm=-offset + WORD, cond=cond) + imm=offset + WORD, cond=cond) else: assert 0, 'unsupported case' @@ -1254,17 +1190,17 @@ elif vfp_loc.is_stack(): # move from two core registers to a float stack location offset = vfp_loc.value - if not check_imm_arg(offset, size=0xFFF): + if not check_imm_arg(offset + WORD, size=0xFFF): self.mc.PUSH([r.ip.value], cond=cond) - self.mc.gen_load_int(r.ip.value, -offset, cond=cond) + self.mc.gen_load_int(r.ip.value, offset, cond=cond) self.mc.STR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond) self.mc.ADD_ri(r.ip.value, r.ip.value, imm=WORD, cond=cond) self.mc.STR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond) self.mc.POP([r.ip.value], cond=cond) else: - self.mc.STR_ri(reg1.value, r.fp.value, imm=-offset, cond=cond) + self.mc.STR_ri(reg1.value, r.fp.value, imm=offset, cond=cond) self.mc.STR_ri(reg2.value, r.fp.value, - imm=-offset + WORD, cond=cond) + imm=offset + WORD, cond=cond) else: assert 0, 'unsupported case' @@ -1310,17 +1246,21 @@ else: raise AssertionError('Trying to pop to an invalid location') - def malloc_cond(self, nursery_free_adr, nursery_top_adr, size): - assert size & (WORD-1) == 0 # must be correctly aligned + def malloc_cond(self, nursery_free_adr, nursery_top_adr, sizeloc, gcmap): + if sizeloc.is_imm(): # must be correctly aligned + assert sizeloc.value & (WORD-1) == 0 self.mc.gen_load_int(r.r0.value, nursery_free_adr) self.mc.LDR_ri(r.r0.value, r.r0.value) - if check_imm_arg(size): - self.mc.ADD_ri(r.r1.value, r.r0.value, size) + if sizeloc.is_imm(): + if check_imm_arg(sizeloc.value): + self.mc.ADD_ri(r.r1.value, r.r0.value, sizeloc.value) + else: + self.mc.gen_load_int(r.r1.value, sizeloc.value) + self.mc.ADD_rr(r.r1.value, r.r0.value, r.r1.value) else: - self.mc.gen_load_int(r.r1.value, size) - self.mc.ADD_rr(r.r1.value, r.r0.value, r.r1.value) + self.mc.ADD_rr(r.r1.value, r.r0.value, sizeloc.value) self.mc.gen_load_int(r.ip.value, nursery_top_adr) self.mc.LDR_ri(r.ip.value, r.ip.value) @@ -1334,35 +1274,30 @@ # malloc_slowpath in case we called malloc_slowpath, which returns the # new value of nursery_free_adr in r1 and the adr of the new object in # r0. - self.mark_gc_roots(self.write_new_force_index(), - use_copy_area=True) + self.push_gcmap(self.mc, gcmap, push=True, cond=c.HI) + self.mc.BL(self.malloc_slowpath, c=c.HI) self.mc.gen_load_int(r.ip.value, nursery_free_adr) self.mc.STR_ri(r.r1.value, r.ip.value) - def mark_gc_roots(self, force_index, use_copy_area=False): - if force_index < 0: - return # not needed - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap: - mark = self._regalloc.get_mark_gc_roots(gcrootmap, use_copy_area) - assert gcrootmap.is_shadow_stack - gcrootmap.write_callshape(mark, force_index) + def push_gcmap(self, mc, gcmap, push=False, store=False, cond=c.AL): + ptr = rffi.cast(lltype.Signed, gcmap) + if push: + mc.gen_load_int(r.ip.value, ptr, cond=cond) + mc.PUSH([r.ip.value], cond=cond) + else: + assert store + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.gen_load_int(r.ip.value, ptr, cond=cond) + mc.STR_ri(r.ip.value, r.fp.value, imm=ofs, cond=cond) - def write_new_force_index(self): - # for shadowstack only: get a new, unused force_index number and - # write it to FORCE_INDEX_OFS. Used to record the call shape - # (i.e. where the GC pointers are in the stack) around a CALL - # instruction that doesn't already have a force_index. - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - clt = self.current_clt - force_index = clt.reserve_and_record_some_faildescr_index() - self._write_fail_index(force_index) - return force_index - else: - return 0 + def pop_gcmap(self, mc): + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + assert check_imm_arg(ofs) + mc.gen_load_int(r.ip.value, 0) + self.store_reg(mc, r.ip, r.fp, ofs) + def not_implemented(msg): diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -1,7 +1,7 @@ -from rpython.jit.backend.arm import arch from rpython.jit.backend.arm import conditions as cond from rpython.jit.backend.arm import registers as reg -from rpython.jit.backend.arm.arch import (WORD, FUNC_ALIGN) +from rpython.jit.backend.arm import support +from rpython.jit.backend.arm.arch import (WORD, FUNC_ALIGN, PC_OFFSET) from rpython.jit.backend.arm.instruction_builder import define_instructions from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin from rpython.rlib.objectmodel import we_are_translated @@ -17,7 +17,7 @@ def binary_helper_call(name): - function = getattr(arch, 'arm_%s' % name) + function = getattr(support, 'arm_%s' % name) def f(self, c=cond.AL): """Generates a call to a helper function, takes its @@ -186,7 +186,7 @@ def B_offs(self, target_ofs, c=cond.AL): pos = self.currpos() - target_ofs = target_ofs - (pos + arch.PC_OFFSET) + target_ofs = target_ofs - (pos + PC_OFFSET) assert target_ofs & 0x3 == 0 self.write32(c << 28 | 0xA << 24 | (target_ofs >> 2) & 0xFFFFFF) diff --git a/rpython/jit/backend/arm/locations.py b/rpython/jit/backend/arm/locations.py --- a/rpython/jit/backend/arm/locations.py +++ b/rpython/jit/backend/arm/locations.py @@ -1,5 +1,5 @@ from rpython.jit.metainterp.history import INT, FLOAT -from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD +from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE class AssemblerLocation(object): @@ -21,9 +21,14 @@ def is_imm_float(self): return False + def is_float(self): + return False + def as_key(self): raise NotImplementedError + def get_position(self): + raise NotImplementedError # only for stack class RegisterLocation(AssemblerLocation): _immutable_ = True @@ -63,6 +68,9 @@ def as_key(self): return self.value + 20 + def is_float(self): + return True + class ImmLocation(AssemblerLocation): _immutable_ = True @@ -103,6 +111,8 @@ def as_key(self): return self.value + def is_float(self): + return True class StackLocation(AssemblerLocation): _immutable_ = True @@ -122,6 +132,9 @@ def location_code(self): return 'b' + def get_position(self): + return self.position + def assembler(self): return repr(self) @@ -131,14 +144,13 @@ def as_key(self): return self.position + 10000 + def is_float(self): + return type == FLOAT + def imm(i): return ImmLocation(i) -def get_fp_offset(i): - if i >= 0: - # Take the FORCE_TOKEN into account - return (1 + i) * WORD From noreply at buildbot.pypy.org Sat Mar 16 04:03:16 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 16 Mar 2013 04:03:16 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: reuse setslice, remove code duplication Message-ID: <20130316030316.DE01E1C3A4D@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62368:38af381ec596 Date: 2013-03-15 19:36 -0700 http://bitbucket.org/pypy/pypy/changeset/38af381ec596/ Log: reuse setslice, remove code duplication diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -279,11 +279,12 @@ return ArrayBuffer(self) def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) if dtype.is_str_or_unicode(): raise OperationError(space.w_NotImplementedError, space.wrap( - "astype(%s) not implemented yet" % dtype)) - new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) + "astype(%s) not implemented yet" % self.dtype)) + else: + loop.setslice(new_arr.get_shape(), new_arr.implementation, self) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): 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 @@ -458,18 +458,6 @@ val_arr.descr_getitem(space, w_idx)) iter.next() -copy_from_to_driver = jit.JitDriver(greens = ['dtype'], - reds = 'auto') - -def copy_from_to(from_, to, dtype): - from_iter = from_.create_iter() - to_iter = to.create_iter() - while not from_iter.done(): - copy_from_to_driver.jit_merge_point(dtype=dtype) - to_iter.setitem(from_iter.getitem().convert_to(dtype)) - to_iter.next() - from_iter.next() - byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') From noreply at buildbot.pypy.org Sat Mar 16 13:35:33 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:33 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Add BlueBook BitBlt simulation. This has been generalized to use a configurable WordSize, and a "sanitize inputs" method has been added to deal with assumptions. Message-ID: <20130316123533.2A5801C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r181:c1447657197d Date: 2013-03-15 10:43 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c1447657197d/ Log: Add BlueBook BitBlt simulation. This has been generalized to use a configurable WordSize, and a "sanitize inputs" method has been added to deal with assumptions. diff --git a/BitBltSim.14.cs b/BitBltSim.14.cs new file mode 100644 --- /dev/null +++ b/BitBltSim.14.cs @@ -0,0 +1,1 @@ +'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 15 March 2013 at 10:42:24 am'! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta ' classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' poolDictionaries: '' category: 'Graphics-Support'! !BitBlt methodsFor: 'private'! clipRange destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - (clipY - destY). simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! !BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! copyBitsAgain self simulateCopyBits.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! calculateOffsets "check if we need to preload buffer (i.e., two words of source needed for first word of destination)" simPreload _ (sourceForm notNil) and: [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. simHDir < 0 ifTrue: [simPreload _ simPreload == false]. "calculate starting offsets" simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). simDestIndex _ simDy * simDestRaster + (simDx // WordSize). "calculate increments from end of 1 line to start of next" simSourceDelta _ (simSourceRaster * simVDir) - (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:28'! checkOverlap | t | "check for possible overlap of source and destination" simHDir _ simVDir _ 1. "defaults for no overlap" (sourceForm == destForm and: [simDy >= simSy]) ifTrue: [simDy > simSy "have to start at bottom" ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] ifFalse: [simDx > simSx "y's are equal, but x's are backward" ifTrue: [simHDir _ -1. simSx _ simSx + simW - 1. "start at right" simDx _ simDx + simW - 1. "and fix up masks" simSkewMask _ simSkewMask bitInvert. t _ simMask1. simMask1 _ simMask2. simMask2 _ t]]]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:26'! computeMasks | startBits endBits | "calculate skeq and edge masks" simDestBits _ destForm bits. simDestRaster _ destForm width - 1 // WordSize + 1. sourceForm notNil ifTrue: [simSourceBits _ sourceForm bits. simSourceRaster _ sourceForm width - 1 // WordSize + 1]. halftoneForm notNil ifTrue: [simHalftoneBits _ halftoneForm bits]. simSkew _ (simSx - simDx) bitAnd: WordSize0. "how many bits source gets skewed to right" startBits _ WordSize - (simDx bitAnd: WordSize0). "how many bits in first word" simMask1 _ RightMasks at: startBits + 1. endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). "how many bits in last word" simMask2 _ (RightMasks at: endBits + 1) bitInvert. simSkewMask _ (simSkew = 0 ifTrue: [0] ifFalse: [RightMasks at: WordSize - simSkew + 1]). "determine number of words stored per line; merge masks if necessary" simW < startBits ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. simMask2 _ 0. simNWords _ 1] ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:39'! copyLoop | prevWord thisWord skewWord mergeMask halftoneWord mergeWord | 1 to: simH do: "here is the vertical loop" [:i | (halftoneForm notNil) ifTrue: "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" [halftoneWord _ simHalftoneBits at: (1 + ((simDy bitAnd: WordSize0) \\ simHalftoneBits size)). simDy _ simDy + simVDir] ifFalse: [halftoneWord _ AllOnes]. skewWord _ halftoneWord. simPreload ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. "load the 32bit shifter" 1 halt. simSourceIndex _ simSourceIndex + simHDir] ifFalse: [prevWord _ 0]. mergeMask _ simMask1. 1 to: simNWords do: "here is the inner horizontal loop" [:word | sourceForm notNil "if source is used" ifTrue: [prevWord _ prevWord bitAnd: simSkewMask. thisWord _ simSourceBits at: simSourceIndex + 1. "pick up next word" skewWord _ prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert). prevWord _ thisWord. skewWord _ (skewWord bitShift: simSkew) bitOr: (skewWord bitShift: simSkew - WordSize)]. "WordSize-bit rotate" mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (simDestBits at: simDestIndex + 1). simDestBits at: simDestIndex + 1 put: ((mergeMask bitAnd: mergeWord) bitOr: (mergeMask bitInvert bitAnd: (simDestBits at: simDestIndex + 1))). simSourceIndex _ simSourceIndex + simHDir. simDestIndex _ simDestIndex + simHDir. word = (simNWords - 1) ifTrue: [mergeMask _ simMask2] ifFalse: [mergeMask _ AllOnes]]. simSourceIndex _ simSourceIndex + simSourceDelta. simDestIndex _ simDestIndex + simDestDelta]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:40'! merge: srcWord with: dstWord "These are the 16 combination rules." combinationRule = 0 ifTrue: [^ 0]. combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert]. combinationRule = 3 ifTrue: [^ srcWord]. combinationRule = 4 ifTrue: [^ srcWord bitInvert bitAnd: dstWord]. combinationRule = 5 ifTrue: [^ dstWord]. combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. combinationRule = 8 ifTrue: [^ srcWord bitInvert bitAnd: dstWord bitInvert]. combinationRule = 9 ifTrue: [^ srcWord bitInvert bitXor: dstWord]. combinationRule = 10 ifTrue: [^ dstWord bitInvert]. combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert]. combinationRule = 12 ifTrue: [^ srcWord bitInvert]. combinationRule = 13 ifTrue: [^ srcWord bitInvert bitOr: dstWord]. combinationRule = 14 ifTrue: [^ srcWord bitInvert bitOr: dstWord bitInvert]. combinationRule = 15 ifTrue: [^ AllOnes]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:16'! sanitizeInput destForm unhibernate. sourceForm ifNil: [sourceForm := destForm] ifNotNil: [sourceForm unhibernate]. halftoneForm ifNotNil: [ halftoneForm isForm ifFalse: [halftoneForm := Form new bits: halftoneForm; yourself]. halftoneForm unhibernate]. width ifNil: [width := sourceForm width]. height ifNil: [height := sourceForm height]. self roundVariables.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:20'! simClipRange "clip and adjust source origin and extent appropriately" "first in x" destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. "then in y" destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - clipY - destY. simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:12'! simulateCopyBits self sanitizeInput. self simClipRange. (simW <= 0 or: [simH <= 0]) ifTrue: [^ self]. self computeMasks. self checkOverlap. self calculateOffsets. self copyLoop.! ! !BitBlt class methodsFor: 'benchmarks' stamp: 'tfel 3/13/2013 14:48'! simpleBenchmark | aBitBlt depth f time | depth := Display depth. Display newDepth: 1. time := Time millisecondsToRun: [ f := Form extent: 20 @ 20. f fillBlack. aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: 5 destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits]. Display newDepth: depth. ^ time! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! exampleOne "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" | pathClass path displayDepth | displayDepth := Display depth. Display newDepth: 1. (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. Display fillWhite. 1 to: 16 do: [:index | BitBlt exampleAt: (path at: index) rule: index - 1 fillColor: nil]. [Sensor anyButtonPressed] whileFalse: []. Display newDepth: displayDepth. "BitBlt exampleOne"! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! exampleTwo "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." | f aBitBlt displayDepth | "create a small black Form source as a brush. " displayDepth := Display depth. Display newDepth: 1. f := Form extent: 20 @ 20. f fillBlack. "create a BitBlt which will OR gray into the display. " aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: Form over destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. "paint the gray Form on the screen for a while. " [Sensor anyButtonPressed] whileFalse: [aBitBlt destOrigin: Sensor cursorPoint. aBitBlt simulateCopyBits]. Display newDepth: displayDepth. "BitBlt exampleTwo"! ! !BitBlt class methodsFor: 'private' stamp: 'tfel 3/13/2013 09:05'! exampleAt: originPoint rule: rule fillColor: mask "This builds a source and destination form and copies the source to the destination using the specifed rule and mask. It is called from the method named exampleOne. Only works with Display depth of 1" | s d border aBitBlt | border:=Form extent: 32 at 32. border fillBlack. border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). s displayOn: Display at: originPoint. border displayOn: Display at: originPoint rule: Form under. d displayOn: Display at: originPoint + (s width @0). border displayOn: Display at: originPoint + (s width @0) rule: Form under. d displayOn: Display at: originPoint + (s extent // (2 @ 1)). aBitBlt := BitBlt destForm: Display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits. border displayOn: Display at: originPoint + (s extent // (2 @ 1)) rule: Form under. "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! !BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! initialize "self initialize" super initialize. WordSize := 32. WordSize0 := WordSize - 1. RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. AllOnes _ (2 raisedTo: WordSize) - 1. ! ! BitBlt initialize! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta' classVariableNames: 'AllOnes RightMasks WordSize WordSize0' poolDictionaries: '' category: 'Graphics-Support'! \ No newline at end of file From noreply at buildbot.pypy.org Sat Mar 16 13:35:34 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Add bitblt tests and fix them Message-ID: <20130316123534.5000D1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r182:2cb6bf300e13 Date: 2013-03-15 12:53 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2cb6bf300e13/ Log: Add bitblt tests and fix them diff --git a/BitBltSim.14.cs b/BitBltSim.14.cs --- a/BitBltSim.14.cs +++ b/BitBltSim.14.cs @@ -1,1 +1,1 @@ -'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 15 March 2013 at 10:42:24 am'! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta ' classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' poolDictionaries: '' category: 'Graphics-Support'! !BitBlt methodsFor: 'private'! clipRange destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - (clipY - destY). simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! !BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! copyBitsAgain self simulateCopyBits.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! calculateOffsets "check if we need to preload buffer (i.e., two words of source needed for first word of destination)" simPreload _ (sourceForm notNil) and: [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. simHDir < 0 ifTrue: [simPreload _ simPreload == false]. "calculate starting offsets" simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). simDestIndex _ simDy * simDestRaster + (simDx // WordSize). "calculate increments from end of 1 line to start of next" simSourceDelta _ (simSourceRaster * simVDir) - (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:28'! checkOverlap | t | "check for possible overlap of source and destination" simHDir _ simVDir _ 1. "defaults for no overlap" (sourceForm == destForm and: [simDy >= simSy]) ifTrue: [simDy > simSy "have to start at bottom" ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] ifFalse: [simDx > simSx "y's are equal, but x's are backward" ifTrue: [simHDir _ -1. simSx _ simSx + simW - 1. "start at right" simDx _ simDx + simW - 1. "and fix up masks" simSkewMask _ simSkewMask bitInvert. t _ simMask1. simMask1 _ simMask2. simMask2 _ t]]]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:26'! computeMasks | startBits endBits | "calculate skeq and edge masks" simDestBits _ destForm bits. simDestRaster _ destForm width - 1 // WordSize + 1. sourceForm notNil ifTrue: [simSourceBits _ sourceForm bits. simSourceRaster _ sourceForm width - 1 // WordSize + 1]. halftoneForm notNil ifTrue: [simHalftoneBits _ halftoneForm bits]. simSkew _ (simSx - simDx) bitAnd: WordSize0. "how many bits source gets skewed to right" startBits _ WordSize - (simDx bitAnd: WordSize0). "how many bits in first word" simMask1 _ RightMasks at: startBits + 1. endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). "how many bits in last word" simMask2 _ (RightMasks at: endBits + 1) bitInvert. simSkewMask _ (simSkew = 0 ifTrue: [0] ifFalse: [RightMasks at: WordSize - simSkew + 1]). "determine number of words stored per line; merge masks if necessary" simW < startBits ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. simMask2 _ 0. simNWords _ 1] ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:39'! copyLoop | prevWord thisWord skewWord mergeMask halftoneWord mergeWord | 1 to: simH do: "here is the vertical loop" [:i | (halftoneForm notNil) ifTrue: "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" [halftoneWord _ simHalftoneBits at: (1 + ((simDy bitAnd: WordSize0) \\ simHalftoneBits size)). simDy _ simDy + simVDir] ifFalse: [halftoneWord _ AllOnes]. skewWord _ halftoneWord. simPreload ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. "load the 32bit shifter" 1 halt. simSourceIndex _ simSourceIndex + simHDir] ifFalse: [prevWord _ 0]. mergeMask _ simMask1. 1 to: simNWords do: "here is the inner horizontal loop" [:word | sourceForm notNil "if source is used" ifTrue: [prevWord _ prevWord bitAnd: simSkewMask. thisWord _ simSourceBits at: simSourceIndex + 1. "pick up next word" skewWord _ prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert). prevWord _ thisWord. skewWord _ (skewWord bitShift: simSkew) bitOr: (skewWord bitShift: simSkew - WordSize)]. "WordSize-bit rotate" mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (simDestBits at: simDestIndex + 1). simDestBits at: simDestIndex + 1 put: ((mergeMask bitAnd: mergeWord) bitOr: (mergeMask bitInvert bitAnd: (simDestBits at: simDestIndex + 1))). simSourceIndex _ simSourceIndex + simHDir. simDestIndex _ simDestIndex + simHDir. word = (simNWords - 1) ifTrue: [mergeMask _ simMask2] ifFalse: [mergeMask _ AllOnes]]. simSourceIndex _ simSourceIndex + simSourceDelta. simDestIndex _ simDestIndex + simDestDelta]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:40'! merge: srcWord with: dstWord "These are the 16 combination rules." combinationRule = 0 ifTrue: [^ 0]. combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert]. combinationRule = 3 ifTrue: [^ srcWord]. combinationRule = 4 ifTrue: [^ srcWord bitInvert bitAnd: dstWord]. combinationRule = 5 ifTrue: [^ dstWord]. combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. combinationRule = 8 ifTrue: [^ srcWord bitInvert bitAnd: dstWord bitInvert]. combinationRule = 9 ifTrue: [^ srcWord bitInvert bitXor: dstWord]. combinationRule = 10 ifTrue: [^ dstWord bitInvert]. combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert]. combinationRule = 12 ifTrue: [^ srcWord bitInvert]. combinationRule = 13 ifTrue: [^ srcWord bitInvert bitOr: dstWord]. combinationRule = 14 ifTrue: [^ srcWord bitInvert bitOr: dstWord bitInvert]. combinationRule = 15 ifTrue: [^ AllOnes]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:16'! sanitizeInput destForm unhibernate. sourceForm ifNil: [sourceForm := destForm] ifNotNil: [sourceForm unhibernate]. halftoneForm ifNotNil: [ halftoneForm isForm ifFalse: [halftoneForm := Form new bits: halftoneForm; yourself]. halftoneForm unhibernate]. width ifNil: [width := sourceForm width]. height ifNil: [height := sourceForm height]. self roundVariables.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:20'! simClipRange "clip and adjust source origin and extent appropriately" "first in x" destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. "then in y" destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - clipY - destY. simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:12'! simulateCopyBits self sanitizeInput. self simClipRange. (simW <= 0 or: [simH <= 0]) ifTrue: [^ self]. self computeMasks. self checkOverlap. self calculateOffsets. self copyLoop.! ! !BitBlt class methodsFor: 'benchmarks' stamp: 'tfel 3/13/2013 14:48'! simpleBenchmark | aBitBlt depth f time | depth := Display depth. Display newDepth: 1. time := Time millisecondsToRun: [ f := Form extent: 20 @ 20. f fillBlack. aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: 5 destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits]. Display newDepth: depth. ^ time! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! exampleOne "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" | pathClass path displayDepth | displayDepth := Display depth. Display newDepth: 1. (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. Display fillWhite. 1 to: 16 do: [:index | BitBlt exampleAt: (path at: index) rule: index - 1 fillColor: nil]. [Sensor anyButtonPressed] whileFalse: []. Display newDepth: displayDepth. "BitBlt exampleOne"! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! exampleTwo "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." | f aBitBlt displayDepth | "create a small black Form source as a brush. " displayDepth := Display depth. Display newDepth: 1. f := Form extent: 20 @ 20. f fillBlack. "create a BitBlt which will OR gray into the display. " aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: Form over destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. "paint the gray Form on the screen for a while. " [Sensor anyButtonPressed] whileFalse: [aBitBlt destOrigin: Sensor cursorPoint. aBitBlt simulateCopyBits]. Display newDepth: displayDepth. "BitBlt exampleTwo"! ! !BitBlt class methodsFor: 'private' stamp: 'tfel 3/13/2013 09:05'! exampleAt: originPoint rule: rule fillColor: mask "This builds a source and destination form and copies the source to the destination using the specifed rule and mask. It is called from the method named exampleOne. Only works with Display depth of 1" | s d border aBitBlt | border:=Form extent: 32 at 32. border fillBlack. border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). s displayOn: Display at: originPoint. border displayOn: Display at: originPoint rule: Form under. d displayOn: Display at: originPoint + (s width @0). border displayOn: Display at: originPoint + (s width @0) rule: Form under. d displayOn: Display at: originPoint + (s extent // (2 @ 1)). aBitBlt := BitBlt destForm: Display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits. border displayOn: Display at: originPoint + (s extent // (2 @ 1)) rule: Form under. "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! !BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! initialize "self initialize" super initialize. WordSize := 32. WordSize0 := WordSize - 1. RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. AllOnes _ (2 raisedTo: WordSize) - 1. ! ! BitBlt initialize! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta' classVariableNames: 'AllOnes RightMasks WordSize WordSize0' poolDictionaries: '' category: 'Graphics-Support'! \ No newline at end of file +'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 15 March 2013 at 12:52:22 pm'! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta ' classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' poolDictionaries: '' category: 'Graphics-Support'! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path ' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBlt methodsFor: 'private'! clipRange destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - (clipY - destY). simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! !BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! copyBitsAgain self simulateCopyBits.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! calculateOffsets "check if we need to preload buffer (i.e., two words of source needed for first word of destination)" simPreload _ (sourceForm notNil) and: [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. simHDir < 0 ifTrue: [simPreload _ simPreload == false]. "calculate starting offsets" simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). simDestIndex _ simDy * simDestRaster + (simDx // WordSize). "calculate increments from end of 1 line to start of next" simSourceDelta _ (simSourceRaster * simVDir) - (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:28'! checkOverlap | t | "check for possible overlap of source and destination" simHDir _ simVDir _ 1. "defaults for no overlap" (sourceForm == destForm and: [simDy >= simSy]) ifTrue: [simDy > simSy "have to start at bottom" ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] ifFalse: [simDx > simSx "y's are equal, but x's are backward" ifTrue: [simHDir _ -1. simSx _ simSx + simW - 1. "start at right" simDx _ simDx + simW - 1. "and fix up masks" simSkewMask _ simSkewMask bitInvert. t _ simMask1. simMask1 _ simMask2. simMask2 _ t]]]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:53'! computeMasks | startBits endBits | "calculate skeq and edge masks" simDestBits _ destForm bits. simDestRaster _ destForm width - 1 // WordSize + 1. sourceForm notNil ifTrue: [simSourceBits _ sourceForm bits. simSourceRaster _ sourceForm width - 1 // WordSize + 1]. halftoneForm notNil ifTrue: [simHalftoneBits _ halftoneForm bits]. simSkew _ (simSx - simDx) bitAnd: WordSize0. "how many bits source gets skewed to right" startBits _ WordSize - (simDx bitAnd: WordSize0). "how many bits in first word" simMask1 _ RightMasks at: startBits + 1. endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). "how many bits in last word" simMask2 _ (RightMasks at: endBits + 1) bitInvert. simSkewMask _ (simSkew = 0 ifTrue: [0] ifFalse: [RightMasks at: WordSize - simSkew + 1]). "determine number of words stored per line; merge masks if necessary" simW < startBits ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. simMask2 _ 0. simNWords _ 1] ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 12:52'! copyLoop | prevWord thisWord skewWord mergeMask halftoneWord mergeWord newDestWord | 1 to: simH do: "here is the vertical loop" [:i | (halftoneForm notNil) ifTrue: "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" [halftoneWord _ simHalftoneBits at: (1 + ((simDy bitAnd: WordSize0) \\ simHalftoneBits size)). simDy _ simDy + simVDir] ifFalse: [halftoneWord _ AllOnes]. skewWord _ halftoneWord. simPreload ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. "load the 32bit shifter. TODO: check if this is WordSize dependent" simSourceIndex _ simSourceIndex + simHDir] ifFalse: [prevWord _ 0]. mergeMask _ simMask1. 1 to: simNWords do: "here is the inner horizontal loop" [:word | sourceForm notNil "if source is used" ifTrue: [prevWord _ prevWord bitAnd: simSkewMask. "HACK: Modulo access" thisWord _ simSourceBits at: (simSourceIndex \\ simSourceBits size) + 1. "pick up next word" skewWord _ prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert). prevWord _ thisWord. skewWord _ (skewWord bitShift: simSkew) bitOr: (skewWord bitShift: simSkew - WordSize)]. "WordSize-bit rotate" mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (simDestBits at: simDestIndex + 1). newDestWord := ((mergeMask bitAnd: mergeWord) bitOr: (mergeMask bitInvert bitAnd: (simDestBits at: simDestIndex + 1))). newDestWord < 0 ifTrue: [newDestWord := newDestWord bitInvert + 1]. simDestBits at: simDestIndex + 1 put: newDestWord. simSourceIndex _ simSourceIndex + simHDir. simDestIndex _ simDestIndex + simHDir. word = (simNWords - 1) ifTrue: [mergeMask _ simMask2] ifFalse: [mergeMask _ AllOnes]]. simSourceIndex _ simSourceIndex + simSourceDelta. simDestIndex _ simDestIndex + simDestDelta]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 12:50'! merge: srcWord with: dstWord "These are the 16 combination rules." combinationRule = 0 ifTrue: [^ 0]. combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert]. combinationRule = 3 ifTrue: [^ srcWord]. combinationRule = 4 ifTrue: [^ srcWord bitInvert bitAnd: dstWord]. combinationRule = 5 ifTrue: [^ dstWord]. combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. combinationRule = 8 ifTrue: [^ srcWord bitInvert bitAnd: dstWord bitInvert]. combinationRule = 9 ifTrue: [^ srcWord bitInvert bitXor: dstWord]. combinationRule = 10 ifTrue: [^ dstWord bitInvert]. combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert]. combinationRule = 12 ifTrue: [^ srcWord bitInvert]. combinationRule = 13 ifTrue: [^ srcWord bitInvert bitOr: dstWord]. combinationRule = 14 ifTrue: [^ srcWord bitInvert bitOr: dstWord bitInvert]. combinationRule = 15 ifTrue: [^ dstWord bitAnd: AllOnes]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:16'! sanitizeInput destForm unhibernate. sourceForm ifNil: [sourceForm := destForm] ifNotNil: [sourceForm unhibernate]. halftoneForm ifNotNil: [ halftoneForm isForm ifFalse: [halftoneForm := Form new bits: halftoneForm; yourself]. halftoneForm unhibernate]. width ifNil: [width := sourceForm width]. height ifNil: [height := sourceForm height]. self roundVariables.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:20'! simClipRange "clip and adjust source origin and extent appropriately" "first in x" destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. "then in y" destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - clipY - destY. simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:12'! simulateCopyBits self sanitizeInput. self simClipRange. (simW <= 0 or: [simH <= 0]) ifTrue: [^ self]. self computeMasks. self checkOverlap. self calculateOffsets. self copyLoop.! ! !BitBlt class methodsFor: 'benchmarks' stamp: 'tfel 3/13/2013 14:48'! simpleBenchmark | aBitBlt depth f time | depth := Display depth. Display newDepth: 1. time := Time millisecondsToRun: [ f := Form extent: 20 @ 20. f fillBlack. aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: 5 destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits]. Display newDepth: depth. ^ time! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! exampleOne "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" | pathClass path displayDepth | displayDepth := Display depth. Display newDepth: 1. (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. Display fillWhite. 1 to: 16 do: [:index | BitBlt exampleAt: (path at: index) rule: index - 1 fillColor: nil]. [Sensor anyButtonPressed] whileFalse: []. Display newDepth: displayDepth. "BitBlt exampleOne"! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! exampleTwo "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." | f aBitBlt displayDepth | "create a small black Form source as a brush. " displayDepth := Display depth. Display newDepth: 1. f := Form extent: 20 @ 20. f fillBlack. "create a BitBlt which will OR gray into the display. " aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: Form over destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. "paint the gray Form on the screen for a while. " [Sensor anyButtonPressed] whileFalse: [aBitBlt destOrigin: Sensor cursorPoint. aBitBlt simulateCopyBits]. Display newDepth: displayDepth. "BitBlt exampleTwo"! ! !BitBlt class methodsFor: 'private' stamp: 'tfel 3/13/2013 09:05'! exampleAt: originPoint rule: rule fillColor: mask "This builds a source and destination form and copies the source to the destination using the specifed rule and mask. It is called from the method named exampleOne. Only works with Display depth of 1" | s d border aBitBlt | border:=Form extent: 32 at 32. border fillBlack. border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). s displayOn: Display at: originPoint. border displayOn: Display at: originPoint rule: Form under. d displayOn: Display at: originPoint + (s width @0). border displayOn: Display at: originPoint + (s width @0) rule: Form under. d displayOn: Display at: originPoint + (s extent // (2 @ 1)). aBitBlt := BitBlt destForm: Display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits. border displayOn: Display at: originPoint + (s extent // (2 @ 1)) rule: Form under. "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! !BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! initialize "self initialize" super initialize. WordSize := 32. WordSize0 := WordSize - 1. RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. AllOnes _ (2 raisedTo: WordSize) - 1. ! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:50'! initialize super initialize. "World restoreDisplay." (Form extent: 500 at 300 depth: 32) fill: (0 at 0 extent: 500 at 300) fillColor: Color green muchDarker; displayOn: Display at: 0 at 0 rule: Form over.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 12:05'! runTest222: index | s d aBitBlt mask rule simD originPoint display | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). display := (Form extent: Display extent) depth: 1. display fillWhite. aBitBlt := BitBlt destForm: display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: display computeBoundingBox. aBitBlt simulateCopyBits. simD := display deepCopy. aBitBlt copyBits. simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. display displayOn: Display at: originPoint - (10 at 0) rule: Form over. display bits = simD bits ifTrue: [index asString displayAt: originPoint - 20] ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 12:48'! runTest: index | s d aBitBlt mask rule simD originPoint | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). simD := d deepCopy. aBitBlt := BitBlt destForm: simD sourceForm: s fillColor: mask combinationRule: rule destOrigin: 0 at 0 sourceOrigin: 0 @ 0 extent: s extent clipRect: simD computeBoundingBox. aBitBlt simulateCopyBits. aBitBlt := BitBlt destForm: d sourceForm: s fillColor: mask combinationRule: rule destOrigin: 0 at 0 sourceOrigin: 0 @ 0 extent: s extent clipRect: d computeBoundingBox. aBitBlt copyBits. simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. d displayOn: Display at: originPoint - (10 at 0) rule: Form over. d bits = simD bits ifTrue: [index asString displayAt: originPoint - 20] ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:38'! setUp | pathClass | (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. ! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test1 self runTest: 1.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:41'! test10 self runTest: 10.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:39'! test11 self runTest: 11.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:28'! test12 self runTest: 12.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:28'! test13 self runTest: 13.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:29'! test14 self runTest: 14.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:29'! test15 self runTest: 15.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:29'! test16 self runTest: 16.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test2 self runTest: 2.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test3 self runTest: 3.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test4 self runTest: 4.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test5 self runTest: 5.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test6 self runTest: 6.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test7 self runTest: 7.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test8 self runTest: 8.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test9 self runTest: 9.! ! BitBltSimTest removeSelector: #testAllAlphasRgbAdd! BitBltSimTest removeSelector: #testAllAlphasRgbMax! BitBltSimTest removeSelector: #testAllAlphasRgbMin! BitBltSimTest removeSelector: #testAllAlphasRgbMinInvert! BitBltSimTest removeSelector: #testAllAlphasRgbMul! BitBltSimTest removeSelector: #testAllAlphasRgbSub! BitBltSimTest removeSelector: #testAlphaCompositing! BitBltSimTest removeSelector: #testAlphaCompositing2! BitBltSimTest removeSelector: #testBWAdd! BitBltSimTest removeSelector: #testFirst! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBltSimTest reorganize! ('as yet unclassified' initialize runTest222: runTest: setUp test1 test10 test11 test12 test13 test14 test15 test16 test2 test3 test4 test5 test6 test7 test8 test9) ! BitBlt initialize! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta' classVariableNames: 'AllOnes RightMasks WordSize WordSize0' poolDictionaries: '' category: 'Graphics-Support'! \ No newline at end of file From noreply at buildbot.pypy.org Sat Mar 16 13:35:35 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:35 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: just commit all Message-ID: <20130316123535.C6E751C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r183:48484c8a2361 Date: 2013-03-15 18:38 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/48484c8a2361/ Log: just commit all diff --git a/images/mini.image b/images/mini.image index 1bc58a0fd06c4079c4651f707226768f724e405e..a8cfbe28687d27aca4ab2d9dd0f37da338fd475d GIT binary patch [cut] diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -75,8 +75,9 @@ s_new_context = p.s_new_context def c_loop(self, s_context): - padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) - print padding + s_context.short_str() + # if self.max_stack_depth - self.remaining_stack_depth < 10: + # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) + # print padding + s_context.short_str() old_pc = 0 while True: pc = s_context._pc diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -4,10 +4,14 @@ from rpython.rlib.rarithmetic import intmask, r_uint, int_between class ObjSpace(object): + _attrs_ = ["_display", "w_simulateCopyBits"] + def __init__(self): self.classtable = {} self.make_bootstrap_classes() self.make_bootstrap_objects() + self._display = [None] + self.w_simulateCopyBits = [None] def make_bootstrap_classes(self): def define_core_cls(name, w_superclass, w_metaclass): @@ -285,6 +289,17 @@ closure.atput0(i0, copiedValues[i0]) return w_closure + def set_display(self, interp, obj): + self._display[0] = obj + self.w_simulateCopyBits[0] = interp.perform(interp.space.wrap_string("simulateCopyBits"), "asSymbol") + + def w_copyBitsSymbol(self): + return self.w_simulateCopyBits[0] + + def display(self): + return self._display[0] + + def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): from spyvm import model diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -4,6 +4,7 @@ import operator from spyvm import model, shadow from spyvm import constants +from spyvm import display from spyvm.error import PrimitiveFailedError, \ PrimitiveNotYetWrittenError from spyvm import wrapper @@ -545,17 +546,37 @@ @expose_primitive(BITBLT_COPY_BITS, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): + import time + if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15: raise PrimitiveFailedError + + start = time.time() + print "blitting" + interp.perform(w_rcvr, "simulateCopyBits") + print "blitting finshed after %d ms" % int((time.time() - start) * 1000) + + w_display = interp.space.objtable['w_display'] + w_dest_form = w_rcvr.fetch(interp.space, 0) + if w_dest_form.is_same_object(w_display): + w_bits = w_dest_form.fetch(interp.space, 0) + assert isinstance(w_bits, model.W_WordsObject) + bits = w_bits.words + print bits + interp.space.display().blit_bits(bits, 0, len(bits)) # TODO: draw only as necessary # See BlueBook p.356ff - s_bitblt = w_rcvr.as_bitblt_get_shadow(interp.space) - s_bitblt.clip_range() - if s_bitblt.w <= 0 or s_bitblt.h <= 0: - return w_rcvr # null range - s_bitblt.compute_masks() - s_bitblt.check_overlap() - s_bitblt.calculate_offsets() - s_bitblt.copy_loop() + # s_bitblt.clip_range() + # if s_bitblt.w < 0 or s_bitblt.h < 0: + # return w_rcvr # null range + # s_bitblt.compute_masks() + # s_bitblt.check_overlap() + # s_bitblt.calculate_offsets() + # start_index = s_bitblt.dest_index + # if s_bitblt.dest_form.w_self().is_same_object(w_display): + # s_bitblt.copy_loop(interp.space.display()) + # else: + # s_bitblt.copy_loop() + # end_index = s_bitblt.dest_index return w_rcvr @expose_primitive(BE_CURSOR, unwrap_spec=[object]) @@ -570,6 +591,14 @@ raise PrimitiveFailedError # the fields required are bits (a pointer to a Bitmap), width, height, depth interp.space.objtable['w_display'] = w_rcvr + + # XXX: TODO get the initial image TODO: figure out whether we + # should decide the width an report it in the other SCREEN_SIZE + w = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1)) + h = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2)) + d = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) + interp.space.set_display(interp, display.SDLDisplay(w, h, d)) + return w_rcvr @expose_primitive(STRING_REPLACE, unwrap_spec=[object, index1_0, index1_0, object, index1_0]) @@ -673,6 +702,7 @@ VALUE_UNINTERRUPTABLY = 123 LOW_SPACE_SEMAPHORE = 124 SIGNAL_AT_BYTES_LEFT = 125 +DEFER_UPDATES = 126 DRAW_RECTANGLE = 127 @expose_primitive(IMAGE_NAME) @@ -695,9 +725,16 @@ # dont know when the space runs out return w_reciver + at expose_primitive(DEFER_UPDATES, unwrap_spec=[object, object]) +def func(interp, s_frame, w_receiver, w_bool): + if w_bool.is_same_object(interp.space.w_true): + interp.space.display().set_defer_updates() + else: + interp.space.display().set_defer_updates() + @expose_primitive(DRAW_RECTANGLE, unwrap_spec=[object, int, int, int, int]) def func(interp, s_frame, w_rcvr, left, right, top, bottom): - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() raise PrimitiveNotYetWrittenError() @@ -1151,6 +1188,12 @@ CTXT_SIZE = 212 # ___________________________________________________________________________ +# Drawing + +FORCE_DISPLAY_UPDATE = 231 + + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -1052,247 +1052,253 @@ def update(self): pass -class BitBltShadow(AbstractCachingShadow): - _attrs_ = [# From BitBlt - "dest_form", "source_form", "halftone_form", - "combination_rule", "dest_x", "dest_y", "width", - "height", "source_x", "source_y", "clip_x", "clip_y", - "clip_width", "clip_height", "color_map", - # From BitBltSimulation - "w", "h", "sx", "sy", "dx", "dy", - "dest_bits", "dest_raster", "source_bits", "source_raster", - "halftone_bits", "skew", "mask1", "mask2", "skew_mask", - "n_words", "h_dir", "v_dir", "preload", "source_index", - "dest_index", "source_delta", "dest_delta"] +# class BitBltShadow(AbstractCachingShadow): +# _attrs_ = [# From BitBlt +# "dest_form", "source_form", "halftone_form", +# "combination_rule", "dest_x", "dest_y", "width", +# "height", "source_x", "source_y", "clip_x", "clip_y", +# "clip_width", "clip_height", "color_map", +# # From BitBltSimulation +# "w", "h", "sx", "sy", "dx", "dy", +# "dest_bits", "dest_raster", "source_bits", "source_raster", +# "halftone_bits", "skew", "mask1", "mask2", "skew_mask", +# "n_words", "h_dir", "v_dir", "preload", "source_index", +# "dest_index", "source_delta", "dest_delta"] - WordSize = 32 - RightMasks = [0] - for i in xrange(WordSize): - RightMasks.append((2 ** (i + 1)) - 1) - AllOnes = (2 ** WordSize) - 1 +# WordSize = 32 +# RightMasks = [rarithmetic.r_uint(0)] +# for i in xrange(WordSize): +# RightMasks.append(rarithmetic.r_uint((2 ** (i + 1)) - 1)) +# AllOnes = rarithmetic.r_uint((2 ** WordSize) - 1) - def sync_cache(self): - try: - self.dest_form = self.fetch(0).as_form_get_shadow(self.space) - except error.PrimitiveFailedError, e: - self.w_self()._shadow = None - raise e - w_source_form = self.fetch(1) - if w_source_form is self.space.w_nil: - self.source_form = self.dest_form - else: - try: - self.source_form = w_source_form.as_form_get_shadow(self.space) - except error.PrimitiveFailedError, e: - self.w_self()._shadow = None - raise e - w_halftone_form = self.fetch(2) - if w_halftone_form is not self.space.w_nil: - if isinstance(w_halftone_form, model.W_WordsObject): - # Already a bitmap - self.halftone_bits = w_halftone_form.words - else: - self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits - else: - self.halftone_bits = None - self.combination_rule = self.space.unwrap_int(self.fetch(3)) - self.dest_x = self.space.unwrap_int(self.fetch(4)) - self.dest_y = self.space.unwrap_int(self.fetch(5)) - self.width = self.space.unwrap_int(self.fetch(6)) - self.height = self.space.unwrap_int(self.fetch(7)) - self.source_x = self.space.unwrap_int(self.fetch(8)) - self.source_y = self.space.unwrap_int(self.fetch(9)) - self.clip_x = self.space.unwrap_int(self.fetch(10)) - self.clip_y = self.space.unwrap_int(self.fetch(11)) - self.clip_width = self.space.unwrap_int(self.fetch(12)) - self.clip_height = self.space.unwrap_int(self.fetch(13)) - self.color_map = self.fetch(14) +# def sync_cache(self): +# try: +# self.dest_form = self.fetch(0).as_form_get_shadow(self.space) +# except error.PrimitiveFailedError, e: +# self.w_self()._shadow = None +# raise e +# w_source_form = self.fetch(1) +# if w_source_form is self.space.w_nil: +# self.source_form = self.dest_form +# else: +# try: +# self.source_form = w_source_form.as_form_get_shadow(self.space) +# except error.PrimitiveFailedError, e: +# self.w_self()._shadow = None +# raise e +# w_halftone_form = self.fetch(2) +# if w_halftone_form is not self.space.w_nil: +# if isinstance(w_halftone_form, model.W_WordsObject): +# # Already a bitmap +# self.halftone_bits = w_halftone_form.words +# else: +# self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits +# else: +# self.halftone_bits = None +# self.combination_rule = self.space.unwrap_int(self.fetch(3)) +# self.dest_x = self.space.unwrap_int(self.fetch(4)) - 1 +# self.dest_y = self.space.unwrap_int(self.fetch(5)) - 1 +# self.width = self.space.unwrap_int(self.fetch(6)) +# self.height = self.space.unwrap_int(self.fetch(7)) +# self.source_x = self.space.unwrap_int(self.fetch(8)) - 1 +# self.source_y = self.space.unwrap_int(self.fetch(9)) - 1 +# self.clip_x = self.space.unwrap_int(self.fetch(10)) - 1 +# self.clip_y = self.space.unwrap_int(self.fetch(11)) - 1 +# self.clip_width = self.space.unwrap_int(self.fetch(12)) +# self.clip_height = self.space.unwrap_int(self.fetch(13)) +# self.color_map = self.fetch(14) - def clip_range(self): - if self.dest_x >= self.clip_x: - self.sx = self.source_x - self.dx = self.dest_x - self.w = self.width - else: - self.sx = self.source_x + (self.clip_x - self.dest_x) - self.w = self.width - (self.clip_x - self.dest_x) - self.dx = self.clip_x - if self.dx + self.w > self.clip_x + self.clip_width: - self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width)) - if self.dest_x >= self.clip_y: - self.sy = self.source_y - self.dy = self.dest_y - self.h = self.height - else: - self.sy = self.source_y + self.clip_y - self.dest_y - self.h = self.height - (self.clip_y - self.dest_y) - self.dy = self.clip_y - if self.dy + self.h > self.clip_y + self.clip_height: - self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height)) - if self.sx < 0: - self.dx = self.dx - self.sx - self.w = self.w + self.sx - self.sx = 0 - if self.sx + self.w > self.source_form.width: - self.w = self.w - (self.sx + self.w - self.source_form.width) - if self.sy < 0: - self.dy = self.dy - self.sy - self.h = self.h + self.sy - self.sy = 0 - if self.sy + self.h > self.source_form.height: - self.h = self.h - (self.sy + self.h - self.source_form.height) +# def clip_range(self): +# if self.dest_x >= self.clip_x: +# self.sx = self.source_x +# self.dx = self.dest_x +# self.w = self.width +# else: +# self.sx = self.source_x + (self.clip_x - self.dest_x) +# self.w = self.width - (self.clip_x - self.dest_x) +# self.dx = self.clip_x +# if self.dx + self.w > self.clip_x + self.clip_width: +# self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width)) +# if self.dest_x >= self.clip_y: +# self.sy = self.source_y +# self.dy = self.dest_y +# self.h = self.height +# else: +# self.sy = self.source_y + self.clip_y - self.dest_y +# self.h = self.height - (self.clip_y - self.dest_y) +# self.dy = self.clip_y +# if self.dy + self.h > self.clip_y + self.clip_height: +# self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height)) +# if self.sx < 0: +# self.dx = self.dx - self.sx +# self.w = self.w + self.sx +# self.sx = 0 +# if self.sx + self.w > self.source_form.width: +# self.w = self.w - (self.sx + self.w - self.source_form.width) +# if self.sy < 0: +# self.dy = self.dy - self.sy +# self.h = self.h + self.sy +# self.sy = 0 +# if self.sy + self.h > self.source_form.height: +# self.h = self.h - (self.sy + self.h - self.source_form.height) - def compute_masks(self): - self.dest_bits = self.dest_form.bits - self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize + 1 - self.source_bits = self.source_form.bits - self.source_raster = (self.source_form.width - 1) / BitBltShadow.WordSize + 1 - self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1) - start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize - 1)) - self.mask1 = BitBltShadow.RightMasks[start_bits] - end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) & (BitBltShadow.WordSize - 1)) - self.mask2 = ~BitBltShadow.RightMasks[end_bits] - if self.skew == 0: - self.skew_mask = 0 - else: - self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize - self.skew] - if self.w < start_bits: - self.mask1 = self.mask1 & self.mask2 - self.mask2 = 0 - self.n_words = 1 - else: - self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize + 2 +# def compute_masks(self): +# self.dest_bits = self.dest_form.bits +# self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize + 1 +# self.source_bits = self.source_form.bits +# self.source_raster = (self.source_form.width - 1) / BitBltShadow.WordSize + 1 +# self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1) +# start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize - 1)) +# self.mask1 = BitBltShadow.RightMasks[start_bits] +# end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) & (BitBltShadow.WordSize - 1)) +# self.mask2 = ~BitBltShadow.RightMasks[end_bits] +# if self.skew == 0: +# self.skew_mask = rarithmetic.r_uint(0) +# else: +# self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize - self.skew] +# if self.w < start_bits: +# self.mask1 = self.mask1 & self.mask2 +# self.mask2 = 0 +# self.n_words = 1 +# else: +# self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize + 2 - def check_overlap(self): - self.h_dir = 1 - self.v_dir = 1 - if (self.source_form.w_self().is_same_object(self.dest_form.w_self()) and - self.dy >= self.sy): - if self.dy > self.sy: - self.v_dir = -1 - self.sy = self.sy + self.h - 1 - self.dy = self.dy + self.h - 1 - elif self.dx > self.sx: - self.h_dir = -1 - self.sx = self.sx + self.w - 1 - self.dx = self.dx + self.w - 1 - self.skew_mask = ~self.skew_mask - self.mask1, self.mask2 = self.mask2, self.mask1 +# def check_overlap(self): +# self.h_dir = 1 +# self.v_dir = 1 +# if (self.source_form.w_self().is_same_object(self.dest_form.w_self()) and +# self.dy >= self.sy): +# if self.dy > self.sy: +# self.v_dir = -1 +# self.sy = self.sy + self.h - 1 +# self.dy = self.dy + self.h - 1 +# elif self.dx > self.sx: +# self.h_dir = -1 +# self.sx = self.sx + self.w - 1 +# self.dx = self.dx + self.w - 1 +# self.skew_mask = ~self.skew_mask +# self.mask1, self.mask2 = self.mask2, self.mask1 - def calculate_offsets(self): - self.preload = (self.skew_mask != 0 and - self.skew <= (self.sx & (BitBltShadow.WordSize - 1))) - if self.h_dir < 0: - self.preload = not self.preload - self.source_index = self.sy * self.source_raster + self.sx / BitBltShadow.WordSize - self.dest_index = self.dy * self.dest_raster + self.dx / BitBltShadow.WordSize - self.source_delta = ((self.source_raster * - self.v_dir - - (self.n_words + (1 if self.preload else 0))) * - self.h_dir) - self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir +# def calculate_offsets(self): +# self.preload = (self.skew_mask != 0 and +# self.skew <= (self.sx & (BitBltShadow.WordSize - 1))) +# if self.h_dir < 0: +# self.preload = not self.preload +# self.source_index = self.sy * self.source_raster + self.sx / BitBltShadow.WordSize +# self.dest_index = self.dy * self.dest_raster + self.dx / BitBltShadow.WordSize +# self.source_delta = ((self.source_raster * +# self.v_dir - +# (self.n_words + (1 if self.preload else 0))) * +# self.h_dir) +# self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir - def copy_loop(self): - for i in xrange(self.h - 1): - if self.halftone_bits: - halftone_word = self.halftone_bits[(self.dy & (BitBltShadow.WordSize - 1)) % len(self.halftone_bits)] - self.dy = self.dy + self.v_dir - else: - halftone_word = BitBltShadow.AllOnes - skew_word = halftone_word - if self.preload: - prev_word = self.source_bits[self.source_index] - self.source_index = self.source_index + self.h_dir - else: - prev_word = 0 - merge_mask = self.mask1 - for word in xrange(self.n_words - 1): - prev_word = prev_word & self.skew_mask - this_word = self.source_bits[self.source_index] - skew_word = prev_word | (this_word & ~self.skew_mask) - prev_word = this_word - skew_word = (self.bit_shift(skew_word, self.skew) | - self.bit_shift(skew_word, self.skew - 16)) - merge_word = self.merge( - skew_word & halftone_word, - self.dest_bits[self.dest_index] - ) - self.dest_bits[self.dest_index] = ( - (merge_mask & merge_word) | - (~merge_mask & self.dest_bits[self.dest_index]) - ) - self.source_index = self.source_index + self.h_dir - self.dest_index = self.dest_index + self.h_dir - if word == (self.n_words - 1): - merge_mask = self.mask2 - else: - merge_mask = BitBltShadow.AllOnes - self.source_index = self.source_index + self.source_delta - self.dest_index = self.dest_index + self.dest_delta - self.dest_form.replace_bits(self.dest_bits) +# def copy_loop(self, dest_surface=None): +# for i in xrange(self.h): +# if self.halftone_bits: +# halftone_word = self.halftone_bits[(self.dy & (BitBltShadow.WordSize - 1)) % len(self.halftone_bits)] +# self.dy = self.dy + self.v_dir +# else: +# halftone_word = BitBltShadow.AllOnes +# skew_word = halftone_word +# if self.preload: +# prev_word = self.source_bits[self.source_index] +# self.source_index = self.source_index + self.h_dir +# else: +# prev_word = 0 +# merge_mask = self.mask1 +# for word in xrange(self.n_words): +# prev_word = prev_word & self.skew_mask +# this_word = self.source_bits[self.source_index] +# skew_word = prev_word | (this_word & ~self.skew_mask) +# prev_word = this_word +# skew_word = (self.bit_shift(skew_word, self.skew) | +# self.bit_shift(skew_word, self.skew - 16)) +# merge_word = rarithmetic.r_uint(self.merge( +# skew_word & halftone_word, +# self.dest_bits[self.dest_index] +# )) +# __prev = self.dest_bits[self.dest_index] +# __new = ( +# (merge_mask & merge_word) | +# (~merge_mask & self.dest_bits[self.dest_index]) +# ) +# self.dest_bits[self.dest_index] = __new +# if dest_surface and __prev != __new: +# dest_surface.lock() +# dest_surface.draw_word(__new, self.dest_index) +# dest_surface.flip() +# self.source_index = self.source_index + self.h_dir +# self.dest_index = self.dest_index + self.h_dir +# if word == (self.n_words - 1): +# merge_mask = self.mask2 +# else: +# merge_mask = BitBltShadow.AllOnes +# self.source_index = self.source_index + self.source_delta +# self.dest_index = self.dest_index + self.dest_delta +# self.dest_form.replace_bits(self.dest_bits) - def bit_shift(self, target, amount): - if amount > 0: - return target << amount - else: - return target >> -amount +# def bit_shift(self, target, amount): +# if amount > 0: +# return rarithmetic.r_uint(target) << amount +# else: +# return rarithmetic.r_uint(target) >> -amount - def merge(self, source_word, dest_word): - if self.combination_rule == 0: - return 0 - elif self.combination_rule == 1: - return source_word & dest_word - elif self.combination_rule == 2: - return source_word & ~dest_word - elif self.combination_rule == 3: - return source_word - elif self.combination_rule == 4: - return ~source_word & dest_word - elif self.combination_rule == 5: - return dest_word - elif self.combination_rule == 6: - return source_word ^ dest_word - elif self.combination_rule == 7: - return source_word | dest_word - elif self.combination_rule == 8: - return ~source_word & ~dest_word - elif self.combination_rule == 9: - return ~source_word ^ dest_word - elif self.combination_rule == 10: - return ~dest_word - elif self.combination_rule == 11: - return source_word | ~dest_word - elif self.combination_rule == 12: - return ~source_word - elif self.combination_rule == 13: - return ~source_word | dest_word - elif self.combination_rule == 14: - return ~source_word | ~dest_word - elif self.combination_rule == 15: - return BitBltShadow.AllOnes +# def merge(self, source_word, dest_word): +# if self.combination_rule == 0: +# return 0 +# elif self.combination_rule == 1: +# return source_word & dest_word +# elif self.combination_rule == 2: +# return source_word & ~dest_word +# elif self.combination_rule == 3: +# return source_word +# elif self.combination_rule == 4: +# return ~source_word & dest_word +# elif self.combination_rule == 5: +# return dest_word +# elif self.combination_rule == 6: +# return source_word ^ dest_word +# elif self.combination_rule == 7: +# return source_word | dest_word +# elif self.combination_rule == 8: +# return ~source_word & ~dest_word +# elif self.combination_rule == 9: +# return ~source_word ^ dest_word +# elif self.combination_rule == 10: +# return ~dest_word +# elif self.combination_rule == 11: +# return source_word | ~dest_word +# elif self.combination_rule == 12: +# return ~source_word +# elif self.combination_rule == 13: +# return ~source_word | dest_word +# elif self.combination_rule == 14: +# return ~source_word | ~dest_word +# elif self.combination_rule == 15: +# return BitBltShadow.AllOnes -class FormShadow(AbstractCachingShadow): - _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] +# class FormShadow(AbstractCachingShadow): +# _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] - def sync_cache(self): - self.w_bits = self.fetch(0) - if isinstance(self.w_bits, model.W_WordsObject): - self.bits = self.w_bits.words - else: - self.w_self()._shadow = None - raise error.PrimitiveFailedError - self.width = self.space.unwrap_int(self.fetch(1)) - self.height = self.space.unwrap_int(self.fetch(2)) - self.depth = self.space.unwrap_int(self.fetch(3)) - w_offset = self.fetch(4) - if not w_offset is self.space.w_nil: - self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) - self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) +# def sync_cache(self): +# self.w_bits = self.fetch(0) +# if isinstance(self.w_bits, model.W_WordsObject): +# self.bits = self.w_bits.words +# else: +# self.w_self()._shadow = None +# raise error.PrimitiveFailedError +# self.width = self.space.unwrap_int(self.fetch(1)) +# self.height = self.space.unwrap_int(self.fetch(2)) +# self.depth = self.space.unwrap_int(self.fetch(3)) +# w_offset = self.fetch(4) +# if not w_offset is self.space.w_nil: +# self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) - 1 +# self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) - 1 - def replace_bits(self, bits): - if isinstance(self.w_bits, model.W_WordsObject): - self.w_bits.words[:] = bits - else: - self.w_self()._shadow = None - raise error.PrimitiveFailedError +# def replace_bits(self, bits): +# if isinstance(self.w_bits, model.W_WordsObject): +# self.w_bits.words[:] = bits +# else: +# self.w_self()._shadow = None +# raise error.PrimitiveFailedError From noreply at buildbot.pypy.org Sat Mar 16 13:35:37 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:37 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: dump bitblt progress Message-ID: <20130316123537.12D071C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r184:8bdd2f9bebda Date: 2013-03-16 10:33 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8bdd2f9bebda/ Log: dump bitblt progress diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -553,30 +553,34 @@ start = time.time() print "blitting" - interp.perform(w_rcvr, "simulateCopyBits") - print "blitting finshed after %d ms" % int((time.time() - start) * 1000) + # interp.perform(w_rcvr, "simulateCopyBits") w_display = interp.space.objtable['w_display'] - w_dest_form = w_rcvr.fetch(interp.space, 0) - if w_dest_form.is_same_object(w_display): - w_bits = w_dest_form.fetch(interp.space, 0) - assert isinstance(w_bits, model.W_WordsObject) - bits = w_bits.words - print bits - interp.space.display().blit_bits(bits, 0, len(bits)) # TODO: draw only as necessary + # See BlueBook p.356ff - # s_bitblt.clip_range() - # if s_bitblt.w < 0 or s_bitblt.h < 0: - # return w_rcvr # null range - # s_bitblt.compute_masks() - # s_bitblt.check_overlap() - # s_bitblt.calculate_offsets() - # start_index = s_bitblt.dest_index - # if s_bitblt.dest_form.w_self().is_same_object(w_display): - # s_bitblt.copy_loop(interp.space.display()) - # else: - # s_bitblt.copy_loop() - # end_index = s_bitblt.dest_index + s_bitblt = w_rcvr.as_bitblt_get_shadow(interp.space) + s_bitblt.clip_range() + if s_bitblt.w < 0 or s_bitblt.h < 0: + return w_rcvr # null range + s_bitblt.compute_masks() + s_bitblt.check_overlap() + s_bitblt.calculate_offsets() + start_index = s_bitblt.dest_index + if s_bitblt.dest_form.w_self().is_same_object(w_display): + s_bitblt.copy_loop(interp.space.display()) + else: + bits = s_bitblt.copy_loop() + end_index = s_bitblt.dest_index + + # w_dest_form = w_rcvr.fetch(interp.space, 0) + # if w_dest_form.is_same_object(w_display): + # # w_bits = w_dest_form.fetch(interp.space, 0) + # # assert isinstance(w_bits, model.W_WordsObject) + # # bits = w_bits.words + # # print bits + # interp.space.display().blit_bits(bits, start_index, end_index) # TODO: draw only as necessary + + print "blitting finshed after %d ms" % int((time.time() - start) * 1000) return w_rcvr @expose_primitive(BE_CURSOR, unwrap_spec=[object]) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -1052,253 +1052,261 @@ def update(self): pass -# class BitBltShadow(AbstractCachingShadow): -# _attrs_ = [# From BitBlt -# "dest_form", "source_form", "halftone_form", -# "combination_rule", "dest_x", "dest_y", "width", -# "height", "source_x", "source_y", "clip_x", "clip_y", -# "clip_width", "clip_height", "color_map", -# # From BitBltSimulation -# "w", "h", "sx", "sy", "dx", "dy", -# "dest_bits", "dest_raster", "source_bits", "source_raster", -# "halftone_bits", "skew", "mask1", "mask2", "skew_mask", -# "n_words", "h_dir", "v_dir", "preload", "source_index", -# "dest_index", "source_delta", "dest_delta"] +class BitBltShadow(AbstractCachingShadow): + _attrs_ = [# From BitBlt + "dest_form", "source_form", "halftone_form", + "combination_rule", "dest_x", "dest_y", "width", + "height", "source_x", "source_y", "clip_x", "clip_y", + "clip_width", "clip_height", "color_map", + # From BitBltSimulation + "w", "h", "sx", "sy", "dx", "dy", + "dest_bits", "dest_raster", "source_bits", "source_raster", + "halftone_bits", "skew", "mask1", "mask2", "skew_mask", + "n_words", "h_dir", "v_dir", "preload", "source_index", + "dest_index", "source_delta", "dest_delta"] -# WordSize = 32 -# RightMasks = [rarithmetic.r_uint(0)] -# for i in xrange(WordSize): -# RightMasks.append(rarithmetic.r_uint((2 ** (i + 1)) - 1)) -# AllOnes = rarithmetic.r_uint((2 ** WordSize) - 1) + WordSize = 32 + RightMasks = [rarithmetic.r_uint(0)] + for i in xrange(WordSize): + RightMasks.append(rarithmetic.r_uint((2 ** (i + 1)) - 1)) + AllOnes = rarithmetic.r_uint((2 ** WordSize) - 1) -# def sync_cache(self): -# try: -# self.dest_form = self.fetch(0).as_form_get_shadow(self.space) -# except error.PrimitiveFailedError, e: -# self.w_self()._shadow = None -# raise e -# w_source_form = self.fetch(1) -# if w_source_form is self.space.w_nil: -# self.source_form = self.dest_form -# else: -# try: -# self.source_form = w_source_form.as_form_get_shadow(self.space) -# except error.PrimitiveFailedError, e: -# self.w_self()._shadow = None -# raise e -# w_halftone_form = self.fetch(2) -# if w_halftone_form is not self.space.w_nil: -# if isinstance(w_halftone_form, model.W_WordsObject): -# # Already a bitmap -# self.halftone_bits = w_halftone_form.words -# else: -# self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits -# else: -# self.halftone_bits = None -# self.combination_rule = self.space.unwrap_int(self.fetch(3)) -# self.dest_x = self.space.unwrap_int(self.fetch(4)) - 1 -# self.dest_y = self.space.unwrap_int(self.fetch(5)) - 1 -# self.width = self.space.unwrap_int(self.fetch(6)) -# self.height = self.space.unwrap_int(self.fetch(7)) -# self.source_x = self.space.unwrap_int(self.fetch(8)) - 1 -# self.source_y = self.space.unwrap_int(self.fetch(9)) - 1 -# self.clip_x = self.space.unwrap_int(self.fetch(10)) - 1 -# self.clip_y = self.space.unwrap_int(self.fetch(11)) - 1 -# self.clip_width = self.space.unwrap_int(self.fetch(12)) -# self.clip_height = self.space.unwrap_int(self.fetch(13)) -# self.color_map = self.fetch(14) + def sync_cache(self): + try: + w_form = self.fetch(0).as_form_get_shadow(self.space) + assert isinstance(w_form, FormShadow) + self.dest_form = w_form + except error.PrimitiveFailedError, e: + self.w_self()._shadow = None + raise e + w_source_form = self.fetch(1) + if w_source_form is self.space.w_nil: + self.source_form = self.dest_form + else: + try: + w_form = w_source_form.as_form_get_shadow(self.space) + assert isinstance(w_form, FormShadow) + self.source_form = w_form + except error.PrimitiveFailedError, e: + self.w_self()._shadow = None + raise e + w_halftone_form = self.fetch(2) + if w_halftone_form is not self.space.w_nil: + if isinstance(w_halftone_form, model.W_WordsObject): + # Already a bitmap + self.halftone_bits = w_halftone_form.words + else: + self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits + else: + self.halftone_bits = None + self.combination_rule = self.space.unwrap_int(self.fetch(3)) + self.dest_x = self.space.unwrap_int(self.fetch(4)) - 1 + self.dest_y = self.space.unwrap_int(self.fetch(5)) - 1 + self.width = self.space.unwrap_int(self.fetch(6)) + self.height = self.space.unwrap_int(self.fetch(7)) + self.source_x = self.space.unwrap_int(self.fetch(8)) - 1 + self.source_y = self.space.unwrap_int(self.fetch(9)) - 1 + self.clip_x = self.space.unwrap_int(self.fetch(10)) - 1 + self.clip_y = self.space.unwrap_int(self.fetch(11)) - 1 + self.clip_width = self.space.unwrap_int(self.fetch(12)) + self.clip_height = self.space.unwrap_int(self.fetch(13)) + self.color_map = self.fetch(14) -# def clip_range(self): -# if self.dest_x >= self.clip_x: -# self.sx = self.source_x -# self.dx = self.dest_x -# self.w = self.width -# else: -# self.sx = self.source_x + (self.clip_x - self.dest_x) -# self.w = self.width - (self.clip_x - self.dest_x) -# self.dx = self.clip_x -# if self.dx + self.w > self.clip_x + self.clip_width: -# self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width)) -# if self.dest_x >= self.clip_y: -# self.sy = self.source_y -# self.dy = self.dest_y -# self.h = self.height -# else: -# self.sy = self.source_y + self.clip_y - self.dest_y -# self.h = self.height - (self.clip_y - self.dest_y) -# self.dy = self.clip_y -# if self.dy + self.h > self.clip_y + self.clip_height: -# self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height)) -# if self.sx < 0: -# self.dx = self.dx - self.sx -# self.w = self.w + self.sx -# self.sx = 0 -# if self.sx + self.w > self.source_form.width: -# self.w = self.w - (self.sx + self.w - self.source_form.width) -# if self.sy < 0: -# self.dy = self.dy - self.sy -# self.h = self.h + self.sy -# self.sy = 0 -# if self.sy + self.h > self.source_form.height: -# self.h = self.h - (self.sy + self.h - self.source_form.height) + def clip_range(self): + if self.dest_x >= self.clip_x: + self.sx = self.source_x + self.dx = self.dest_x + self.w = self.width + else: + self.sx = self.source_x + (self.clip_x - self.dest_x) + self.w = self.width - (self.clip_x - self.dest_x) + self.dx = self.clip_x + if self.dx + self.w > self.clip_x + self.clip_width: + self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width)) + if self.dest_x >= self.clip_y: + self.sy = self.source_y + self.dy = self.dest_y + self.h = self.height + else: + self.sy = self.source_y + self.clip_y - self.dest_y + self.h = self.height - (self.clip_y - self.dest_y) + self.dy = self.clip_y + if self.dy + self.h > self.clip_y + self.clip_height: + self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height)) + if self.sx < 0: + self.dx = self.dx - self.sx + self.w = self.w + self.sx + self.sx = 0 + if self.sx + self.w > self.source_form.width: + self.w = self.w - (self.sx + self.w - self.source_form.width) + if self.sy < 0: + self.dy = self.dy - self.sy + self.h = self.h + self.sy + self.sy = 0 + if self.sy + self.h > self.source_form.height: + self.h = self.h - (self.sy + self.h - self.source_form.height) -# def compute_masks(self): -# self.dest_bits = self.dest_form.bits -# self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize + 1 -# self.source_bits = self.source_form.bits -# self.source_raster = (self.source_form.width - 1) / BitBltShadow.WordSize + 1 -# self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1) -# start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize - 1)) -# self.mask1 = BitBltShadow.RightMasks[start_bits] -# end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) & (BitBltShadow.WordSize - 1)) -# self.mask2 = ~BitBltShadow.RightMasks[end_bits] -# if self.skew == 0: -# self.skew_mask = rarithmetic.r_uint(0) -# else: -# self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize - self.skew] -# if self.w < start_bits: -# self.mask1 = self.mask1 & self.mask2 -# self.mask2 = 0 -# self.n_words = 1 -# else: -# self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize + 2 + def compute_masks(self): + self.dest_bits = self.dest_form.bits + self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize + 1 + self.source_bits = self.source_form.bits + self.source_raster = (self.source_form.width - 1) / BitBltShadow.WordSize + 1 + self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1) + start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize - 1)) + self.mask1 = BitBltShadow.RightMasks[start_bits] + end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) & (BitBltShadow.WordSize - 1)) + self.mask2 = ~BitBltShadow.RightMasks[end_bits] + if self.skew == 0: + self.skew_mask = rarithmetic.r_uint(0) + else: + self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize - self.skew] + if self.w < start_bits: + self.mask1 = self.mask1 & self.mask2 + self.mask2 = 0 + self.n_words = 1 + else: + self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize + 2 -# def check_overlap(self): -# self.h_dir = 1 -# self.v_dir = 1 -# if (self.source_form.w_self().is_same_object(self.dest_form.w_self()) and -# self.dy >= self.sy): -# if self.dy > self.sy: -# self.v_dir = -1 -# self.sy = self.sy + self.h - 1 -# self.dy = self.dy + self.h - 1 -# elif self.dx > self.sx: -# self.h_dir = -1 -# self.sx = self.sx + self.w - 1 -# self.dx = self.dx + self.w - 1 -# self.skew_mask = ~self.skew_mask -# self.mask1, self.mask2 = self.mask2, self.mask1 + def check_overlap(self): + self.h_dir = 1 + self.v_dir = 1 + if (self.source_form.w_self().is_same_object(self.dest_form.w_self()) and + self.dy >= self.sy): + if self.dy > self.sy: + self.v_dir = -1 + self.sy = self.sy + self.h - 1 + self.dy = self.dy + self.h - 1 + elif self.dx > self.sx: + self.h_dir = -1 + self.sx = self.sx + self.w - 1 + self.dx = self.dx + self.w - 1 + self.skew_mask = ~self.skew_mask + self.mask1, self.mask2 = self.mask2, self.mask1 -# def calculate_offsets(self): -# self.preload = (self.skew_mask != 0 and -# self.skew <= (self.sx & (BitBltShadow.WordSize - 1))) -# if self.h_dir < 0: -# self.preload = not self.preload -# self.source_index = self.sy * self.source_raster + self.sx / BitBltShadow.WordSize -# self.dest_index = self.dy * self.dest_raster + self.dx / BitBltShadow.WordSize -# self.source_delta = ((self.source_raster * -# self.v_dir - -# (self.n_words + (1 if self.preload else 0))) * -# self.h_dir) -# self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir + def calculate_offsets(self): + self.preload = (self.skew_mask != 0 and + self.skew <= (self.sx & (BitBltShadow.WordSize - 1))) + if self.h_dir < 0: + self.preload = not self.preload + self.source_index = self.sy * self.source_raster + self.sx / BitBltShadow.WordSize + self.dest_index = self.dy * self.dest_raster + self.dx / BitBltShadow.WordSize + self.source_delta = ((self.source_raster * + self.v_dir - + (self.n_words + (1 if self.preload else 0))) * + self.h_dir) + self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir -# def copy_loop(self, dest_surface=None): -# for i in xrange(self.h): -# if self.halftone_bits: -# halftone_word = self.halftone_bits[(self.dy & (BitBltShadow.WordSize - 1)) % len(self.halftone_bits)] -# self.dy = self.dy + self.v_dir -# else: -# halftone_word = BitBltShadow.AllOnes -# skew_word = halftone_word -# if self.preload: -# prev_word = self.source_bits[self.source_index] -# self.source_index = self.source_index + self.h_dir -# else: -# prev_word = 0 -# merge_mask = self.mask1 -# for word in xrange(self.n_words): -# prev_word = prev_word & self.skew_mask -# this_word = self.source_bits[self.source_index] -# skew_word = prev_word | (this_word & ~self.skew_mask) -# prev_word = this_word -# skew_word = (self.bit_shift(skew_word, self.skew) | -# self.bit_shift(skew_word, self.skew - 16)) -# merge_word = rarithmetic.r_uint(self.merge( -# skew_word & halftone_word, -# self.dest_bits[self.dest_index] -# )) -# __prev = self.dest_bits[self.dest_index] -# __new = ( -# (merge_mask & merge_word) | -# (~merge_mask & self.dest_bits[self.dest_index]) -# ) -# self.dest_bits[self.dest_index] = __new -# if dest_surface and __prev != __new: -# dest_surface.lock() -# dest_surface.draw_word(__new, self.dest_index) -# dest_surface.flip() -# self.source_index = self.source_index + self.h_dir -# self.dest_index = self.dest_index + self.h_dir -# if word == (self.n_words - 1): -# merge_mask = self.mask2 -# else: -# merge_mask = BitBltShadow.AllOnes -# self.source_index = self.source_index + self.source_delta -# self.dest_index = self.dest_index + self.dest_delta -# self.dest_form.replace_bits(self.dest_bits) + def copy_loop(self, dest_surface=None): + for i in xrange(self.h): + if self.halftone_bits: + halftone_word = self.halftone_bits[(self.dy & (BitBltShadow.WordSize - 1)) % len(self.halftone_bits)] + self.dy = self.dy + self.v_dir + else: + halftone_word = BitBltShadow.AllOnes + skew_word = halftone_word + if self.preload: + prev_word = self.source_bits[self.source_index] + self.source_index = self.source_index + self.h_dir + else: + prev_word = 0 + merge_mask = self.mask1 + for word in xrange(self.n_words): + prev_word = prev_word & self.skew_mask + try: + this_word = self.source_bits[self.source_index] + except IndexError: + this_word = BitBltShadow.AllOnes + skew_word = prev_word | (this_word & ~self.skew_mask) + prev_word = this_word + skew_word = (self.bit_shift(skew_word, self.skew) | + self.bit_shift(skew_word, self.skew - 16)) + merge_word = rarithmetic.r_uint(self.merge( + skew_word & halftone_word, + self.dest_bits[self.dest_index] + )) + __prev = self.dest_bits[self.dest_index] + __new = ( + (merge_mask & merge_word) | + (~merge_mask & self.dest_bits[self.dest_index]) + ) + self.dest_bits[self.dest_index] = __new + if dest_surface and __prev != __new: + dest_surface.lock() + dest_surface.draw_word(__new, self.dest_index) + dest_surface.flip() + self.source_index = self.source_index + self.h_dir + self.dest_index = self.dest_index + self.h_dir + if word == (self.n_words - 2): + merge_mask = self.mask2 + else: + merge_mask = BitBltShadow.AllOnes + self.source_index = self.source_index + self.source_delta + self.dest_index = self.dest_index + self.dest_delta + self.dest_form.replace_bits(self.dest_bits) + return self.dest_bits -# def bit_shift(self, target, amount): -# if amount > 0: -# return rarithmetic.r_uint(target) << amount -# else: -# return rarithmetic.r_uint(target) >> -amount + def bit_shift(self, target, amount): + if amount > 0: + return (rarithmetic.r_uint(target) << amount) & BitBltShadow.AllOnes + else: + return (rarithmetic.r_uint(target) >> -amount) & BitBltShadow.AllOnes -# def merge(self, source_word, dest_word): -# if self.combination_rule == 0: -# return 0 -# elif self.combination_rule == 1: -# return source_word & dest_word -# elif self.combination_rule == 2: -# return source_word & ~dest_word -# elif self.combination_rule == 3: -# return source_word -# elif self.combination_rule == 4: -# return ~source_word & dest_word -# elif self.combination_rule == 5: -# return dest_word -# elif self.combination_rule == 6: -# return source_word ^ dest_word -# elif self.combination_rule == 7: -# return source_word | dest_word -# elif self.combination_rule == 8: -# return ~source_word & ~dest_word -# elif self.combination_rule == 9: -# return ~source_word ^ dest_word -# elif self.combination_rule == 10: -# return ~dest_word -# elif self.combination_rule == 11: -# return source_word | ~dest_word -# elif self.combination_rule == 12: -# return ~source_word -# elif self.combination_rule == 13: -# return ~source_word | dest_word -# elif self.combination_rule == 14: -# return ~source_word | ~dest_word -# elif self.combination_rule == 15: -# return BitBltShadow.AllOnes + def merge(self, source_word, dest_word): + if self.combination_rule == 0: + return 0 + elif self.combination_rule == 1: + return source_word & dest_word + elif self.combination_rule == 2: + return source_word & ~dest_word + elif self.combination_rule == 3: + return source_word + elif self.combination_rule == 4: + return ~source_word & dest_word + elif self.combination_rule == 5: + return dest_word + elif self.combination_rule == 6: + return source_word ^ dest_word + elif self.combination_rule == 7: + return source_word | dest_word + elif self.combination_rule == 8: + return ~source_word & ~dest_word + elif self.combination_rule == 9: + return ~source_word ^ dest_word + elif self.combination_rule == 10: + return ~dest_word + elif self.combination_rule == 11: + return source_word | ~dest_word + elif self.combination_rule == 12: + return ~source_word + elif self.combination_rule == 13: + return ~source_word | dest_word + elif self.combination_rule == 14: + return ~source_word | ~dest_word + elif self.combination_rule == 15: + return dest_word & BitBltShadow.AllOnes -# class FormShadow(AbstractCachingShadow): -# _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] +class FormShadow(AbstractCachingShadow): + # _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] -# def sync_cache(self): -# self.w_bits = self.fetch(0) -# if isinstance(self.w_bits, model.W_WordsObject): -# self.bits = self.w_bits.words -# else: -# self.w_self()._shadow = None -# raise error.PrimitiveFailedError -# self.width = self.space.unwrap_int(self.fetch(1)) -# self.height = self.space.unwrap_int(self.fetch(2)) -# self.depth = self.space.unwrap_int(self.fetch(3)) -# w_offset = self.fetch(4) -# if not w_offset is self.space.w_nil: -# self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) - 1 -# self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) - 1 + def sync_cache(self): + self.w_bits = self.fetch(0) + if isinstance(self.w_bits, model.W_WordsObject): + self.bits = self.w_bits.words + else: + self.w_self()._shadow = None + raise error.PrimitiveFailedError + self.width = self.space.unwrap_int(self.fetch(1)) + self.height = self.space.unwrap_int(self.fetch(2)) + self.depth = self.space.unwrap_int(self.fetch(3)) + w_offset = self.fetch(4) + if not w_offset is self.space.w_nil: + self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) - 1 + self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) - 1 -# def replace_bits(self, bits): -# if isinstance(self.w_bits, model.W_WordsObject): -# self.w_bits.words[:] = bits -# else: -# self.w_self()._shadow = None -# raise error.PrimitiveFailedError + def replace_bits(self, bits): + if isinstance(self.w_bits, model.W_WordsObject): + self.w_bits.words[:] = bits + else: + self.w_self()._shadow = None + raise error.PrimitiveFailedError From noreply at buildbot.pypy.org Sat Mar 16 13:35:38 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:38 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Make sure we create new W_Float objects, too Message-ID: <20130316123538.2CA661C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r185:5bdb7538ffe1 Date: 2013-03-16 10:38 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/5bdb7538ffe1/ Log: Make sure we create new W_Float objects, too diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -71,7 +71,8 @@ WORDS = 2 WEAK_POINTERS = 3 COMPILED_METHOD = 4 - +FLOAT = 5 +DISPLAY_SCREEN = 6 class MethodNotFound(error.SmalltalkException): pass @@ -128,7 +129,10 @@ elif format == 4: self.instance_kind = WEAK_POINTERS elif format == 6: - self.instance_kind = WORDS + if self.space.w_Float.is_same_object(self.w_self()): + self.instance_kind = FLOAT + else: + self.instance_kind = WORDS if self.instsize() != 0: raise ClassShadowError("can't have both words and a non-zero " "base instance size") @@ -201,6 +205,8 @@ w_new = model.W_BytesObject(w_cls, extrasize) elif self.instance_kind == COMPILED_METHOD: w_new = model.W_CompiledMethod(extrasize) + elif self.instance_kind == FLOAT: + w_new = model.W_Float(0) # Squeak gives a random piece of memory else: raise NotImplementedError(self.instance_kind) return w_new diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -343,3 +343,8 @@ assert w_result is not None assert isinstance(w_result, model.W_Float) assert w_result.value == math.pi + +def test_new_float_as_w_float(): + w_result = perform(interp.space.w_Float, "new") + assert w_result is not None + assert isinstance(w_result, model.W_Float) From noreply at buildbot.pypy.org Sat Mar 16 13:35:39 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:39 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: merge default Message-ID: <20130316123539.3FDA91C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r186:ec5c2d502e64 Date: 2013-03-16 10:39 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ec5c2d502e64/ Log: merge default diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -71,7 +71,8 @@ WORDS = 2 WEAK_POINTERS = 3 COMPILED_METHOD = 4 - +FLOAT = 5 +DISPLAY_SCREEN = 6 class MethodNotFound(error.SmalltalkException): pass @@ -128,7 +129,10 @@ elif format == 4: self.instance_kind = WEAK_POINTERS elif format == 6: - self.instance_kind = WORDS + if self.space.w_Float.is_same_object(self.w_self()): + self.instance_kind = FLOAT + else: + self.instance_kind = WORDS if self.instsize() != 0: raise ClassShadowError("can't have both words and a non-zero " "base instance size") @@ -201,6 +205,8 @@ w_new = model.W_BytesObject(w_cls, extrasize) elif self.instance_kind == COMPILED_METHOD: w_new = model.W_CompiledMethod(extrasize) + elif self.instance_kind == FLOAT: + w_new = model.W_Float(0) # Squeak gives a random piece of memory else: raise NotImplementedError(self.instance_kind) return w_new diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -343,3 +343,8 @@ assert w_result is not None assert isinstance(w_result, model.W_Float) assert w_result.value == math.pi + +def test_new_float_as_w_float(): + w_result = perform(interp.space.w_Float, "new") + assert w_result is not None + assert isinstance(w_result, model.W_Float) From noreply at buildbot.pypy.org Sat Mar 16 13:35:40 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:40 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: remove python BitBlt logic, add W_DisplayBitmap as model for the bitmap on the display object Message-ID: <20130316123540.794881C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r187:dbecef62dc1b Date: 2013-03-16 12:24 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/dbecef62dc1b/ Log: remove python BitBlt logic, add W_DisplayBitmap as model for the bitmap on the display object diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -75,9 +75,8 @@ s_new_context = p.s_new_context def c_loop(self, s_context): - # if self.max_stack_depth - self.remaining_stack_depth < 10: - # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) - # print padding + s_context.short_str() + # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) + # print padding + s_context.short_str() old_pc = 0 while True: pc = s_context._pc diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -22,6 +22,8 @@ from rpython.rlib.rarithmetic import intmask, r_uint from rpython.tool.pairtype import extendabletype from rpython.rlib.objectmodel import instantiate +from rpython.rtyper.lltypesystem import lltype, rffi +from rsdl import RSDL, RSDL_helper class W_Object(object): """Root of Squeak model, abstract.""" @@ -421,15 +423,6 @@ def has_shadow(self): return self._shadow is not None - def as_bitblt_get_shadow(self, space): - from spyvm.shadow import BitBltShadow - return self.as_special_get_shadow(space, BitBltShadow) - - def as_form_get_shadow(self, space): - from spyvm.shadow import FormShadow - return self.as_special_get_shadow(space, FormShadow) - - def become(self, w_other): if not isinstance(w_other, W_PointersObject): return False @@ -532,6 +525,94 @@ w_result.words = list(self.words) return w_result +class VersionTag(): + pass + +NATIVE_DEPTH = 32 +class W_DisplayBitmap(W_AbstractObjectWithClassReference): + + _attrs_ = ['pixelbuffer', '_depth', '_size'] + + def __init__(self, w_class, size, depth): + W_AbstractObjectWithClassReference.__init__(self, w_class) + assert depth == 1 # XXX: Only support B/W for now + bytelen = NATIVE_DEPTH / depth * size * 4 + self.pixelbuffer = lltype.malloc(rffi.VOIDP.TO, bytelen, flavor='raw') + self._depth = depth + self._size = size + self.mutate() + + def __del__(self): + lltype.free(self.pixelbuffer, flavor='raw') + + def mutate(self): + self.version = VersionTag() + + def at0(self, space, index0): + return self._at0_pure(space, index0, self.version) + + @jit.elidable + def _at0_pure(self, space, index0, version): + val = self.getword(index0) + print "Get: [%d] => %d" % (index0, val) + return space.wrap_uint(val) + + def atput0(self, space, index0, w_value): + word = space.unwrap_uint(w_value) + print "Set: [%d] => %d" % (index0, word) + self.setword(index0, word) + self.mutate() + + # XXX: Only supports 1-bit to 32-bit conversion for now + @jit.unroll_safe + def getword(self, n): + pixel_per_word = NATIVE_DEPTH / self._depth + word = r_uint(0) + pos = n * pixel_per_word * 4 + for i in xrange(32): + red = self.pixelbuffer[pos] + if red == '\0': # Black + word &= 1 + word <<= 1 + pos += 4 + return word + + @jit.unroll_safe + def setword(self, n, word): + pixel_per_word = NATIVE_DEPTH / self._depth + word = r_uint(0) + pos = n * pixel_per_word * 4 + mask = 1 + mask <<= 31 + for i in xrange(32): + bit = mask & word + if bit == 0: # white + self.pixelbuffer[pos] = '\xff' + self.pixelbuffer[pos + 1] = '\xff' + self.pixelbuffer[pos + 2] = '\xff' + else: + self.pixelbuffer[pos] = '\0' + self.pixelbuffer[pos + 1] = '\0' + self.pixelbuffer[pos + 2] = '\0' + self.pixelbuffer[pos + 3] = '\xff' + mask >>= 1 + pos += 4 + + def size(self): + return self._size + + def invariant(self): + return False + + def clone(self, space): + w_result = W_WordsObject(self.w_class, self._size) + n = 0 + while n < self._size: + w_result.words[n] = self.getword(n) + n += 1 + return w_result + + # XXX Shouldn't compiledmethod have class reference for subclassed compiled # methods? class W_CompiledMethod(W_AbstractObjectWithIdentityHash): diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -11,7 +11,6 @@ self.make_bootstrap_classes() self.make_bootstrap_objects() self._display = [None] - self.w_simulateCopyBits = [None] def make_bootstrap_classes(self): def define_core_cls(name, w_superclass, w_metaclass): @@ -291,10 +290,6 @@ def set_display(self, interp, obj): self._display[0] = obj - self.w_simulateCopyBits[0] = interp.perform(interp.space.wrap_string("simulateCopyBits"), "asSymbol") - - def w_copyBitsSymbol(self): - return self.w_simulateCopyBits[0] def display(self): return self._display[0] diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -546,39 +546,19 @@ @expose_primitive(BITBLT_COPY_BITS, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): - import time - if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15: raise PrimitiveFailedError + import time start = time.time() print "blitting" - # interp.perform(w_rcvr, "simulateCopyBits") - w_display = interp.space.objtable['w_display'] + interp.perform(w_rcvr, "simulateCopyBits") - # See BlueBook p.356ff - s_bitblt = w_rcvr.as_bitblt_get_shadow(interp.space) - s_bitblt.clip_range() - if s_bitblt.w < 0 or s_bitblt.h < 0: - return w_rcvr # null range - s_bitblt.compute_masks() - s_bitblt.check_overlap() - s_bitblt.calculate_offsets() - start_index = s_bitblt.dest_index - if s_bitblt.dest_form.w_self().is_same_object(w_display): - s_bitblt.copy_loop(interp.space.display()) - else: - bits = s_bitblt.copy_loop() - end_index = s_bitblt.dest_index - - # w_dest_form = w_rcvr.fetch(interp.space, 0) - # if w_dest_form.is_same_object(w_display): - # # w_bits = w_dest_form.fetch(interp.space, 0) - # # assert isinstance(w_bits, model.W_WordsObject) - # # bits = w_bits.words - # # print bits - # interp.space.display().blit_bits(bits, start_index, end_index) # TODO: draw only as necessary + w_dest_form = w_rcvr.fetch(interp.space, 0) + if w_dest_form.is_same_object(interp.space.objtable['w_display']): + import pdb; pdb.set_trace() + interp.space.display().blit() print "blitting finshed after %d ms" % int((time.time() - start) * 1000) return w_rcvr @@ -594,15 +574,26 @@ if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 4: raise PrimitiveFailedError # the fields required are bits (a pointer to a Bitmap), width, height, depth - interp.space.objtable['w_display'] = w_rcvr # XXX: TODO get the initial image TODO: figure out whether we # should decide the width an report it in the other SCREEN_SIZE - w = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1)) - h = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2)) - d = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) - interp.space.set_display(interp, display.SDLDisplay(w, h, d)) + w_bitmap = w_rcvr.fetch(interp.space, 0) + assert isinstance(w_bitmap, model.W_WordsObject) or isinstance(w_bitmap, model.W_DisplayBitmap) + width = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1)) + height = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2)) + depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) + w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth) + for idx, word in enumerate(w_bitmap.words): + w_display_bitmap.setword(idx, word) + w_rcvr.store(interp.space, 0, w_display_bitmap) + + sdldisplay = display.SDLDisplay(width, height, depth) + sdldisplay.set_pixelbuffer(w_display_bitmap.pixelbuffer) + sdldisplay.blit() + interp.space.set_display(interp, display) + + interp.space.objtable['w_display'] = w_rcvr return w_rcvr @expose_primitive(STRING_REPLACE, unwrap_spec=[object, index1_0, index1_0, object, index1_0]) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -72,7 +72,6 @@ WEAK_POINTERS = 3 COMPILED_METHOD = 4 FLOAT = 5 -DISPLAY_SCREEN = 6 class MethodNotFound(error.SmalltalkException): pass @@ -1056,263 +1055,3 @@ self.dependent = dependent def update(self): pass - - -class BitBltShadow(AbstractCachingShadow): - _attrs_ = [# From BitBlt - "dest_form", "source_form", "halftone_form", - "combination_rule", "dest_x", "dest_y", "width", - "height", "source_x", "source_y", "clip_x", "clip_y", - "clip_width", "clip_height", "color_map", - # From BitBltSimulation - "w", "h", "sx", "sy", "dx", "dy", - "dest_bits", "dest_raster", "source_bits", "source_raster", - "halftone_bits", "skew", "mask1", "mask2", "skew_mask", - "n_words", "h_dir", "v_dir", "preload", "source_index", - "dest_index", "source_delta", "dest_delta"] - - WordSize = 32 - RightMasks = [rarithmetic.r_uint(0)] - for i in xrange(WordSize): - RightMasks.append(rarithmetic.r_uint((2 ** (i + 1)) - 1)) - AllOnes = rarithmetic.r_uint((2 ** WordSize) - 1) - - def sync_cache(self): - try: - w_form = self.fetch(0).as_form_get_shadow(self.space) - assert isinstance(w_form, FormShadow) - self.dest_form = w_form - except error.PrimitiveFailedError, e: - self.w_self()._shadow = None - raise e - w_source_form = self.fetch(1) - if w_source_form is self.space.w_nil: - self.source_form = self.dest_form - else: - try: - w_form = w_source_form.as_form_get_shadow(self.space) - assert isinstance(w_form, FormShadow) - self.source_form = w_form - except error.PrimitiveFailedError, e: - self.w_self()._shadow = None - raise e - w_halftone_form = self.fetch(2) - if w_halftone_form is not self.space.w_nil: - if isinstance(w_halftone_form, model.W_WordsObject): - # Already a bitmap - self.halftone_bits = w_halftone_form.words - else: - self.halftone_bits = w_halftone_form.as_form_get_shadow(self.space).bits - else: - self.halftone_bits = None - self.combination_rule = self.space.unwrap_int(self.fetch(3)) - self.dest_x = self.space.unwrap_int(self.fetch(4)) - 1 - self.dest_y = self.space.unwrap_int(self.fetch(5)) - 1 - self.width = self.space.unwrap_int(self.fetch(6)) - self.height = self.space.unwrap_int(self.fetch(7)) - self.source_x = self.space.unwrap_int(self.fetch(8)) - 1 - self.source_y = self.space.unwrap_int(self.fetch(9)) - 1 - self.clip_x = self.space.unwrap_int(self.fetch(10)) - 1 - self.clip_y = self.space.unwrap_int(self.fetch(11)) - 1 - self.clip_width = self.space.unwrap_int(self.fetch(12)) - self.clip_height = self.space.unwrap_int(self.fetch(13)) - self.color_map = self.fetch(14) - - def clip_range(self): - if self.dest_x >= self.clip_x: - self.sx = self.source_x - self.dx = self.dest_x - self.w = self.width - else: - self.sx = self.source_x + (self.clip_x - self.dest_x) - self.w = self.width - (self.clip_x - self.dest_x) - self.dx = self.clip_x - if self.dx + self.w > self.clip_x + self.clip_width: - self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width)) - if self.dest_x >= self.clip_y: - self.sy = self.source_y - self.dy = self.dest_y - self.h = self.height - else: - self.sy = self.source_y + self.clip_y - self.dest_y - self.h = self.height - (self.clip_y - self.dest_y) - self.dy = self.clip_y - if self.dy + self.h > self.clip_y + self.clip_height: - self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height)) - if self.sx < 0: - self.dx = self.dx - self.sx - self.w = self.w + self.sx - self.sx = 0 - if self.sx + self.w > self.source_form.width: - self.w = self.w - (self.sx + self.w - self.source_form.width) - if self.sy < 0: - self.dy = self.dy - self.sy - self.h = self.h + self.sy - self.sy = 0 - if self.sy + self.h > self.source_form.height: - self.h = self.h - (self.sy + self.h - self.source_form.height) - - def compute_masks(self): - self.dest_bits = self.dest_form.bits - self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize + 1 - self.source_bits = self.source_form.bits - self.source_raster = (self.source_form.width - 1) / BitBltShadow.WordSize + 1 - self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1) - start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize - 1)) - self.mask1 = BitBltShadow.RightMasks[start_bits] - end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) & (BitBltShadow.WordSize - 1)) - self.mask2 = ~BitBltShadow.RightMasks[end_bits] - if self.skew == 0: - self.skew_mask = rarithmetic.r_uint(0) - else: - self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize - self.skew] - if self.w < start_bits: - self.mask1 = self.mask1 & self.mask2 - self.mask2 = 0 - self.n_words = 1 - else: - self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize + 2 - - def check_overlap(self): - self.h_dir = 1 - self.v_dir = 1 - if (self.source_form.w_self().is_same_object(self.dest_form.w_self()) and - self.dy >= self.sy): - if self.dy > self.sy: - self.v_dir = -1 - self.sy = self.sy + self.h - 1 - self.dy = self.dy + self.h - 1 - elif self.dx > self.sx: - self.h_dir = -1 - self.sx = self.sx + self.w - 1 - self.dx = self.dx + self.w - 1 - self.skew_mask = ~self.skew_mask - self.mask1, self.mask2 = self.mask2, self.mask1 - - def calculate_offsets(self): - self.preload = (self.skew_mask != 0 and - self.skew <= (self.sx & (BitBltShadow.WordSize - 1))) - if self.h_dir < 0: - self.preload = not self.preload - self.source_index = self.sy * self.source_raster + self.sx / BitBltShadow.WordSize - self.dest_index = self.dy * self.dest_raster + self.dx / BitBltShadow.WordSize - self.source_delta = ((self.source_raster * - self.v_dir - - (self.n_words + (1 if self.preload else 0))) * - self.h_dir) - self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir - - def copy_loop(self, dest_surface=None): - for i in xrange(self.h): - if self.halftone_bits: - halftone_word = self.halftone_bits[(self.dy & (BitBltShadow.WordSize - 1)) % len(self.halftone_bits)] - self.dy = self.dy + self.v_dir - else: - halftone_word = BitBltShadow.AllOnes - skew_word = halftone_word - if self.preload: - prev_word = self.source_bits[self.source_index] - self.source_index = self.source_index + self.h_dir - else: - prev_word = 0 - merge_mask = self.mask1 - for word in xrange(self.n_words): - prev_word = prev_word & self.skew_mask - try: - this_word = self.source_bits[self.source_index] - except IndexError: - this_word = BitBltShadow.AllOnes - skew_word = prev_word | (this_word & ~self.skew_mask) - prev_word = this_word - skew_word = (self.bit_shift(skew_word, self.skew) | - self.bit_shift(skew_word, self.skew - 16)) - merge_word = rarithmetic.r_uint(self.merge( - skew_word & halftone_word, - self.dest_bits[self.dest_index] - )) - __prev = self.dest_bits[self.dest_index] - __new = ( - (merge_mask & merge_word) | - (~merge_mask & self.dest_bits[self.dest_index]) - ) - self.dest_bits[self.dest_index] = __new - if dest_surface and __prev != __new: - dest_surface.lock() - dest_surface.draw_word(__new, self.dest_index) - dest_surface.flip() - self.source_index = self.source_index + self.h_dir - self.dest_index = self.dest_index + self.h_dir - if word == (self.n_words - 2): - merge_mask = self.mask2 - else: - merge_mask = BitBltShadow.AllOnes - self.source_index = self.source_index + self.source_delta - self.dest_index = self.dest_index + self.dest_delta - self.dest_form.replace_bits(self.dest_bits) - return self.dest_bits - - def bit_shift(self, target, amount): - if amount > 0: - return (rarithmetic.r_uint(target) << amount) & BitBltShadow.AllOnes - else: - return (rarithmetic.r_uint(target) >> -amount) & BitBltShadow.AllOnes - - def merge(self, source_word, dest_word): - if self.combination_rule == 0: - return 0 - elif self.combination_rule == 1: - return source_word & dest_word - elif self.combination_rule == 2: - return source_word & ~dest_word - elif self.combination_rule == 3: - return source_word - elif self.combination_rule == 4: - return ~source_word & dest_word - elif self.combination_rule == 5: - return dest_word - elif self.combination_rule == 6: - return source_word ^ dest_word - elif self.combination_rule == 7: - return source_word | dest_word - elif self.combination_rule == 8: - return ~source_word & ~dest_word - elif self.combination_rule == 9: - return ~source_word ^ dest_word - elif self.combination_rule == 10: - return ~dest_word - elif self.combination_rule == 11: - return source_word | ~dest_word - elif self.combination_rule == 12: - return ~source_word - elif self.combination_rule == 13: - return ~source_word | dest_word - elif self.combination_rule == 14: - return ~source_word | ~dest_word - elif self.combination_rule == 15: - return dest_word & BitBltShadow.AllOnes - - -class FormShadow(AbstractCachingShadow): - # _attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"] - - def sync_cache(self): - self.w_bits = self.fetch(0) - if isinstance(self.w_bits, model.W_WordsObject): - self.bits = self.w_bits.words - else: - self.w_self()._shadow = None - raise error.PrimitiveFailedError - self.width = self.space.unwrap_int(self.fetch(1)) - self.height = self.space.unwrap_int(self.fetch(2)) - self.depth = self.space.unwrap_int(self.fetch(3)) - w_offset = self.fetch(4) - if not w_offset is self.space.w_nil: - self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) - 1 - self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) - 1 - - def replace_bits(self, bits): - if isinstance(self.w_bits, model.W_WordsObject): - self.w_bits.words[:] = bits - else: - self.w_self()._shadow = None - raise error.PrimitiveFailedError From noreply at buildbot.pypy.org Sat Mar 16 13:35:41 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:41 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Fix translation errors, store the sdldisplay on the DisplayBitmap object Message-ID: <20130316123541.868D71C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r188:25ccd461619c Date: 2013-03-16 13:11 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/25ccd461619c/ Log: Fix translation errors, store the sdldisplay on the DisplayBitmap object diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -530,16 +530,16 @@ NATIVE_DEPTH = 32 class W_DisplayBitmap(W_AbstractObjectWithClassReference): + _attrs_ = ['pixelbuffer', '_depth', '_realsize', 'display', 'version'] - _attrs_ = ['pixelbuffer', '_depth', '_size'] - - def __init__(self, w_class, size, depth): + def __init__(self, w_class, size, depth, display): W_AbstractObjectWithClassReference.__init__(self, w_class) assert depth == 1 # XXX: Only support B/W for now bytelen = NATIVE_DEPTH / depth * size * 4 self.pixelbuffer = lltype.malloc(rffi.VOIDP.TO, bytelen, flavor='raw') self._depth = depth - self._size = size + self._realsize = size + self.display = display self.mutate() def __del__(self): @@ -599,15 +599,15 @@ pos += 4 def size(self): - return self._size + return self._realsize def invariant(self): return False def clone(self, space): - w_result = W_WordsObject(self.w_class, self._size) + w_result = W_WordsObject(self.w_class, self._realsize) n = 0 - while n < self._size: + while n < self._realsize: w_result.words[n] = self.getword(n) n += 1 return w_result diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -4,13 +4,10 @@ from rpython.rlib.rarithmetic import intmask, r_uint, int_between class ObjSpace(object): - _attrs_ = ["_display", "w_simulateCopyBits"] - def __init__(self): self.classtable = {} self.make_bootstrap_classes() self.make_bootstrap_objects() - self._display = [None] def make_bootstrap_classes(self): def define_core_cls(name, w_superclass, w_metaclass): @@ -288,12 +285,6 @@ closure.atput0(i0, copiedValues[i0]) return w_closure - def set_display(self, interp, obj): - self._display[0] = obj - - def display(self): - return self._display[0] - def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -557,8 +557,9 @@ w_dest_form = w_rcvr.fetch(interp.space, 0) if w_dest_form.is_same_object(interp.space.objtable['w_display']): - import pdb; pdb.set_trace() - interp.space.display().blit() + w_bitmap = w_dest_form.fetch(interp.space, 0) + assert isinstance(w_bitmap, model.W_DisplayBitmap) + w_bitmap.display.blit() print "blitting finshed after %d ms" % int((time.time() - start) * 1000) return w_rcvr @@ -578,20 +579,31 @@ # XXX: TODO get the initial image TODO: figure out whether we # should decide the width an report it in the other SCREEN_SIZE w_bitmap = w_rcvr.fetch(interp.space, 0) - assert isinstance(w_bitmap, model.W_WordsObject) or isinstance(w_bitmap, model.W_DisplayBitmap) width = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1)) height = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2)) depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) - w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth) - for idx, word in enumerate(w_bitmap.words): - w_display_bitmap.setword(idx, word) - w_rcvr.store(interp.space, 0, w_display_bitmap) + w_prev_display = interp.space.objtable['w_display'] + w_prev_bitmap = None + if w_prev_display: + w_prev_bitmap = w_prev_display.fetch(interp.space, 0) + if isinstance(w_prev_bitmap, model.W_DisplayBitmap): + sdldisplay = w_prev_bitmap.display + else: + sdldisplay = display.SDLDisplay() + sdldisplay.set_video_mode(width, height, depth) - sdldisplay = display.SDLDisplay(width, height, depth) + if isinstance(w_bitmap, model.W_WordsObject): + w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, display) + for idx, word in enumerate(w_bitmap.words): + w_display_bitmap.setword(idx, word) + w_rcvr.store(interp.space, 0, w_display_bitmap) + else: + assert isinstance(w_bitmap, model.W_DisplayBitmap) + w_display_bitmap = w_bitmap + sdldisplay.set_pixelbuffer(w_display_bitmap.pixelbuffer) sdldisplay.blit() - interp.space.set_display(interp, display) interp.space.objtable['w_display'] = w_rcvr return w_rcvr @@ -722,10 +734,7 @@ @expose_primitive(DEFER_UPDATES, unwrap_spec=[object, object]) def func(interp, s_frame, w_receiver, w_bool): - if w_bool.is_same_object(interp.space.w_true): - interp.space.display().set_defer_updates() - else: - interp.space.display().set_defer_updates() + raise PrimitiveNotYetWrittenError() @expose_primitive(DRAW_RECTANGLE, unwrap_spec=[object, int, int, int, int]) def func(interp, s_frame, w_rcvr, left, right, top, bottom): From noreply at buildbot.pypy.org Sat Mar 16 13:35:42 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 13:35:42 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: make sure we only create one sdldisplay Message-ID: <20130316123542.A7FA31C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r189:33cd4e103d40 Date: 2013-03-16 13:14 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/33cd4e103d40/ Log: make sure we only create one sdldisplay diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -594,12 +594,13 @@ sdldisplay.set_video_mode(width, height, depth) if isinstance(w_bitmap, model.W_WordsObject): - w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, display) + w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, sdldisplay) for idx, word in enumerate(w_bitmap.words): w_display_bitmap.setword(idx, word) w_rcvr.store(interp.space, 0, w_display_bitmap) else: assert isinstance(w_bitmap, model.W_DisplayBitmap) + assert w_bitmap.display is sdldisplay w_display_bitmap = w_bitmap sdldisplay.set_pixelbuffer(w_display_bitmap.pixelbuffer) From noreply at buildbot.pypy.org Sat Mar 16 16:00:16 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 16:00:16 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: fix setword/getword on W_Bitmap Message-ID: <20130316150016.02A0C1C0204@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r190:617434096d25 Date: 2013-03-16 14:00 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/617434096d25/ Log: fix setword/getword on W_Bitmap diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -554,12 +554,10 @@ @jit.elidable def _at0_pure(self, space, index0, version): val = self.getword(index0) - print "Get: [%d] => %d" % (index0, val) return space.wrap_uint(val) def atput0(self, space, index0, w_value): word = space.unwrap_uint(w_value) - print "Set: [%d] => %d" % (index0, word) self.setword(index0, word) self.mutate() @@ -572,7 +570,7 @@ for i in xrange(32): red = self.pixelbuffer[pos] if red == '\0': # Black - word &= 1 + word |= r_uint(1) word <<= 1 pos += 4 return word @@ -580,9 +578,8 @@ @jit.unroll_safe def setword(self, n, word): pixel_per_word = NATIVE_DEPTH / self._depth - word = r_uint(0) pos = n * pixel_per_word * 4 - mask = 1 + mask = r_uint(1) mask <<= 31 for i in xrange(32): bit = mask & word diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -549,10 +549,6 @@ if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15: raise PrimitiveFailedError - import time - start = time.time() - print "blitting" - interp.perform(w_rcvr, "simulateCopyBits") w_dest_form = w_rcvr.fetch(interp.space, 0) @@ -561,7 +557,6 @@ assert isinstance(w_bitmap, model.W_DisplayBitmap) w_bitmap.display.blit() - print "blitting finshed after %d ms" % int((time.time() - start) * 1000) return w_rcvr @expose_primitive(BE_CURSOR, unwrap_spec=[object]) @@ -584,25 +579,28 @@ depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) w_prev_display = interp.space.objtable['w_display'] - w_prev_bitmap = None + sdldisplay = None + if w_prev_display: w_prev_bitmap = w_prev_display.fetch(interp.space, 0) - if isinstance(w_prev_bitmap, model.W_DisplayBitmap): - sdldisplay = w_prev_bitmap.display - else: + if isinstance(w_prev_bitmap, model.W_DisplayBitmap): + sdldisplay = w_prev_bitmap.display + + if isinstance(w_bitmap, model.W_DisplayBitmap): + assert (sdldisplay is None) or (sdldisplay is w_bitmap.display) + sdldisplay = w_bitmap.display + w_display_bitmap = w_bitmap + + if not sdldisplay: sdldisplay = display.SDLDisplay() - sdldisplay.set_video_mode(width, height, depth) if isinstance(w_bitmap, model.W_WordsObject): w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, sdldisplay) for idx, word in enumerate(w_bitmap.words): w_display_bitmap.setword(idx, word) w_rcvr.store(interp.space, 0, w_display_bitmap) - else: - assert isinstance(w_bitmap, model.W_DisplayBitmap) - assert w_bitmap.display is sdldisplay - w_display_bitmap = w_bitmap + sdldisplay.set_video_mode(width, height, depth) sdldisplay.set_pixelbuffer(w_display_bitmap.pixelbuffer) sdldisplay.blit() From noreply at buildbot.pypy.org Sat Mar 16 16:00:17 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 16:00:17 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: clarify this logic Message-ID: <20130316150017.2AA051C1047@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r191:df7f762c1037 Date: 2013-03-16 14:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/df7f762c1037/ Log: clarify this logic diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -578,9 +578,9 @@ height = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2)) depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) - w_prev_display = interp.space.objtable['w_display'] sdldisplay = None + w_prev_display = interp.space.objtable['w_display'] if w_prev_display: w_prev_bitmap = w_prev_display.fetch(interp.space, 0) if isinstance(w_prev_bitmap, model.W_DisplayBitmap): @@ -590,11 +590,10 @@ assert (sdldisplay is None) or (sdldisplay is w_bitmap.display) sdldisplay = w_bitmap.display w_display_bitmap = w_bitmap - - if not sdldisplay: - sdldisplay = display.SDLDisplay() - - if isinstance(w_bitmap, model.W_WordsObject): + else: + assert isinstance(w_bitmap, model.W_WordsObject) + if not sdldisplay: + sdldisplay = display.SDLDisplay() w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, sdldisplay) for idx, word in enumerate(w_bitmap.words): w_display_bitmap.setword(idx, word) From noreply at buildbot.pypy.org Sat Mar 16 16:00:18 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 16:00:18 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: flush to screen through bitmap Message-ID: <20130316150018.3A6901C0204@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r192:2d3bb103a935 Date: 2013-03-16 14:36 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2d3bb103a935/ Log: flush to screen through bitmap diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -595,6 +595,13 @@ mask >>= 1 pos += 4 + def flush_to_screen(self): + self._flush_to_screen_if_dirty(self.version) + + @jit.elidable + def _flush_to_screen_if_dirty(self, version): + self.display.blit() + def size(self): return self._realsize diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -555,7 +555,7 @@ if w_dest_form.is_same_object(interp.space.objtable['w_display']): w_bitmap = w_dest_form.fetch(interp.space, 0) assert isinstance(w_bitmap, model.W_DisplayBitmap) - w_bitmap.display.blit() + w_bitmap.flush_to_screen() return w_rcvr From noreply at buildbot.pypy.org Sat Mar 16 16:00:19 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 16:00:19 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: implement FORCE_DISPLAY_UPDATE Message-ID: <20130316150019.494431C0204@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r193:fe671af7e394 Date: 2013-03-16 14:37 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/fe671af7e394/ Log: implement FORCE_DISPLAY_UPDATE diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -1194,6 +1194,15 @@ FORCE_DISPLAY_UPDATE = 231 + at expose_primitive(FORCE_DISPLAY_UPDATE, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + w_prev_display = interp.space.objtable['w_display'] + assert w_prev_display + w_prev_bitmap = w_prev_display.fetch(interp.space, 0) + assert isinstance(w_prev_bitmap, model.W_DisplayBitmap) + w_prev_bitmap.flush_to_screen() + return w_rcvr + # ___________________________________________________________________________ # PrimitiveLoadInstVar From noreply at buildbot.pypy.org Sat Mar 16 16:00:20 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 16:00:20 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: remove elidables, instead mark what is immutable and we're fine Message-ID: <20130316150020.60D7F1C0204@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r194:d7c70e2844bb Date: 2013-03-16 14:42 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d7c70e2844bb/ Log: remove elidables, instead mark what is immutable and we're fine diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -525,12 +525,10 @@ w_result.words = list(self.words) return w_result -class VersionTag(): - pass - NATIVE_DEPTH = 32 class W_DisplayBitmap(W_AbstractObjectWithClassReference): - _attrs_ = ['pixelbuffer', '_depth', '_realsize', 'display', 'version'] + _attrs_ = ['pixelbuffer', '_depth', '_realsize', 'display'] + _immutable_fields_ = ['_depth', '_realsize', 'display'] def __init__(self, w_class, size, depth, display): W_AbstractObjectWithClassReference.__init__(self, w_class) @@ -540,26 +538,17 @@ self._depth = depth self._realsize = size self.display = display - self.mutate() def __del__(self): lltype.free(self.pixelbuffer, flavor='raw') - def mutate(self): - self.version = VersionTag() - def at0(self, space, index0): - return self._at0_pure(space, index0, self.version) - - @jit.elidable - def _at0_pure(self, space, index0, version): val = self.getword(index0) return space.wrap_uint(val) def atput0(self, space, index0, w_value): word = space.unwrap_uint(w_value) self.setword(index0, word) - self.mutate() # XXX: Only supports 1-bit to 32-bit conversion for now @jit.unroll_safe @@ -596,10 +585,6 @@ pos += 4 def flush_to_screen(self): - self._flush_to_screen_if_dirty(self.version) - - @jit.elidable - def _flush_to_screen_if_dirty(self, version): self.display.blit() def size(self): From noreply at buildbot.pypy.org Sat Mar 16 18:03:16 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sat, 16 Mar 2013 18:03:16 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: add a mini image that has the bluebook bitblt code for debugging Message-ID: <20130316170316.A40441C1047@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r195:675a5eacf39b Date: 2013-03-16 17:57 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/675a5eacf39b/ Log: add a mini image that has the bluebook bitblt code for debugging diff --git a/images/minibluebookdebug.image b/images/minibluebookdebug.image new file mode 100644 index 0000000000000000000000000000000000000000..7b6c3b1b62a5489daec16ba35442c7f80b796917 GIT binary patch [cut] From noreply at buildbot.pypy.org Sat Mar 16 19:39:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Mar 2013 19:39:54 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130316183954.24C841C3A85@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62369:00f94fe08f9a Date: 2013-03-16 14:38 -0400 http://bitbucket.org/pypy/pypy/changeset/00f94fe08f9a/ Log: fix whatsnew 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 @@ -86,3 +86,8 @@ .. branch: vendor-rename Remove minor verison number from lib-python dirs to simplify stdlib upgrades. + +.. branch: jitframe-on-heap +Moves optimized JIT frames from stack to heap. As a side effect it enables +stackless to work well with the JIT on PyPy. Also removes a bunch of code from +the GC which fixes cannot find gc roots. From noreply at buildbot.pypy.org Sat Mar 16 20:06:05 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 16 Mar 2013 20:06:05 +0100 (CET) Subject: [pypy-commit] pypy default: (fijal, alex): fix a crash in the JIT when memory locations are more than 4GB apart Message-ID: <20130316190605.E1B641C0CA3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62370:f82ae0daaeb6 Date: 2013-03-16 12:05 -0700 http://bitbucket.org/pypy/pypy/changeset/f82ae0daaeb6/ Log: (fijal, alex): fix a crash in the JIT when memory locations are more than 4GB apart diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -240,7 +240,7 @@ propagate_exception_descr = rffi.cast(lltype.Signed, cast_instance_to_gcref(self.cpu.propagate_exception_descr)) ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mc.MOV_bi(ofs, propagate_exception_descr) + self.mc.MOV(RawEbpLoc(ofs), imm(propagate_exception_descr)) self.mc.MOV_rr(eax.value, ebp.value) # self._call_footer() From noreply at buildbot.pypy.org Sat Mar 16 20:06:07 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 16 Mar 2013 20:06:07 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130316190607.99AF61C0CA3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62371:bc17f27ce628 Date: 2013-03-16 12:05 -0700 http://bitbucket.org/pypy/pypy/changeset/bc17f27ce628/ Log: merged upstream 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 @@ -86,3 +86,8 @@ .. branch: vendor-rename Remove minor verison number from lib-python dirs to simplify stdlib upgrades. + +.. branch: jitframe-on-heap +Moves optimized JIT frames from stack to heap. As a side effect it enables +stackless to work well with the JIT on PyPy. Also removes a bunch of code from +the GC which fixes cannot find gc roots. From noreply at buildbot.pypy.org Sat Mar 16 20:21:55 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 16 Mar 2013 20:21:55 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): fix for mmap on OSX: mmap requires either MAP_SHARED or MAP_PRIVATE be massed Message-ID: <20130316192155.2F4961C0204@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62372:c1212ae53dc9 Date: 2013-03-16 12:21 -0700 http://bitbucket.org/pypy/pypy/changeset/c1212ae53dc9/ Log: (alex, fijal): fix for mmap on OSX: mmap requires either MAP_SHARED or MAP_PRIVATE be massed diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -680,6 +680,9 @@ else: m.fd = os.dup(fd) + if sys.platform == "darwin" and not flags & MAP_SHARED: + flags |= MAP_PRIVATE + # XXX if we use hintp below in alloc, the NonConstant # is necessary since we want a general version of c_mmap # to be annotated with a non-constant pointer. From noreply at buildbot.pypy.org Sat Mar 16 22:28:02 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 16 Mar 2013 22:28:02 +0100 (CET) Subject: [pypy-commit] pypy default: Fix translation. Message-ID: <20130316212802.BC7791C0CA3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62373:46b9ff612805 Date: 2013-03-16 14:27 -0700 http://bitbucket.org/pypy/pypy/changeset/46b9ff612805/ Log: Fix translation. diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -13,6 +13,7 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" _LINUX = "linux" in sys.platform +_DARWIN = sys.platform == "darwin" _64BIT = "64bit" in platform.architecture()[0] _ARM = platform.machine().startswith('arm') _PPC = platform.machine().startswith('ppc') @@ -680,7 +681,7 @@ else: m.fd = os.dup(fd) - if sys.platform == "darwin" and not flags & MAP_SHARED: + if _DARWIN and not flags & MAP_SHARED: flags |= MAP_PRIVATE # XXX if we use hintp below in alloc, the NonConstant From noreply at buildbot.pypy.org Sat Mar 16 22:51:50 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 16 Mar 2013 22:51:50 +0100 (CET) Subject: [pypy-commit] pypy default: Don't disable the JIT when a trace func is enabled. Message-ID: <20130316215150.16EEA1C0204@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62374:250b7b22adf8 Date: 2013-03-16 14:51 -0700 http://bitbucket.org/pypy/pypy/changeset/250b7b22adf8/ Log: Don't disable the JIT when a trace func is enabled. diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -22,6 +22,7 @@ 'lastblock', 'is_being_profiled', 'w_globals', + 'w_f_trace', ] JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE'] @@ -37,9 +38,6 @@ def set_jitcell_at(newcell, next_instr, is_being_profiled, bytecode): bytecode.jit_cells[next_instr, is_being_profiled] = newcell -def confirm_enter_jit(next_instr, is_being_profiled, bytecode, frame, ec): - return (frame.w_f_trace is None and - ec.w_tracefunc is None) def can_never_inline(next_instr, is_being_profiled, bytecode): return False @@ -55,7 +53,6 @@ pypyjitdriver = PyPyJitDriver(get_printable_location = get_printable_location, get_jitcell_at = get_jitcell_at, set_jitcell_at = set_jitcell_at, - confirm_enter_jit = confirm_enter_jit, can_never_inline = can_never_inline, should_unroll_one_iteration = should_unroll_one_iteration, From noreply at buildbot.pypy.org Sat Mar 16 22:52:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Mar 2013 22:52:35 +0100 (CET) Subject: [pypy-commit] pypy default: remove untested hack in rmmap that creates inconsistent behavior (mmap always requires SHARED or PRIVATE) Message-ID: <20130316215235.9BEA31C0204@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62375:1cbecc1dd793 Date: 2013-03-16 14:45 -0700 http://bitbucket.org/pypy/pypy/changeset/1cbecc1dd793/ Log: remove untested hack in rmmap that creates inconsistent behavior (mmap always requires SHARED or PRIVATE) diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -13,7 +13,6 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" _LINUX = "linux" in sys.platform -_DARWIN = sys.platform == "darwin" _64BIT = "64bit" in platform.architecture()[0] _ARM = platform.machine().startswith('arm') _PPC = platform.machine().startswith('ppc') @@ -681,9 +680,6 @@ else: m.fd = os.dup(fd) - if _DARWIN and not flags & MAP_SHARED: - flags |= MAP_PRIVATE - # XXX if we use hintp below in alloc, the NonConstant # is necessary since we want a general version of c_mmap # to be annotated with a non-constant pointer. From noreply at buildbot.pypy.org Sat Mar 16 22:52:36 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Mar 2013 22:52:36 +0100 (CET) Subject: [pypy-commit] pypy default: try to fix do_allocation_in_far_regions on POSIXes besides linux Message-ID: <20130316215236.E77D81C0204@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62376:c812aa205fdf Date: 2013-03-16 14:51 -0700 http://bitbucket.org/pypy/pypy/changeset/c812aa205fdf/ Log: try to fix do_allocation_in_far_regions on POSIXes besides linux diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -44,7 +44,6 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" -_LINUX = "linux" in sys.platform _64BIT = "64bit" in host_platform.architecture()[0] @@ -70,7 +69,7 @@ return ctype() def do_allocation_in_far_regions(): - """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on Linux, + """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on POSIX, which helps test this module for address values that are signed or unsigned. @@ -87,18 +86,20 @@ if _64BIT: PIECESIZE = 0x80000000 else: - if _LINUX: + if _POSIX: PIECESIZE = 0x10000000 else: PIECESIZE = 0x08000000 PIECES = 10 flags = (0,) - if _LINUX: + if _POSIX: flags = (rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS|rmmap.MAP_NORESERVE, rmmap.PROT_READ|rmmap.PROT_WRITE) - if _MS_WINDOWS: + elif _MS_WINDOWS: flags = (rmmap.MEM_RESERVE,) # XXX seems not to work + else: + assert False # should always generate flags m = rmmap.mmap(-1, PIECES * PIECESIZE, *flags) m.close = lambda : None # leak instead of giving a spurious # error at CPython's shutdown From noreply at buildbot.pypy.org Sun Mar 17 02:24:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 17 Mar 2013 02:24:51 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup rmmap.py Message-ID: <20130317012451.8A32D1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62377:55ade758e2d9 Date: 2013-03-16 21:23 -0400 http://bitbucket.org/pypy/pypy/changeset/55ade758e2d9/ Log: cleanup rmmap.py diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -1,6 +1,5 @@ - from rpython.rtyper.tool import rffi_platform -from rpython.rtyper.lltypesystem import rffi, lltype, llmemory +from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rposix from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.nonconst import NonConstant @@ -12,10 +11,7 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" -_LINUX = "linux" in sys.platform _64BIT = "64bit" in platform.architecture()[0] -_ARM = platform.machine().startswith('arm') -_PPC = platform.machine().startswith('ppc') _CYGWIN = "cygwin" == sys.platform class RValueError(Exception): @@ -30,7 +26,7 @@ if _POSIX: includes += ['unistd.h', 'sys/mman.h'] elif _MS_WINDOWS: - includes += ['winsock2.h','windows.h'] + includes += ['winsock2.h', 'windows.h'] class CConfig: _compilation_info_ = ExternalCompilationInfo( @@ -78,7 +74,7 @@ from rpython.rlib.rwin32 import NULL_HANDLE, INVALID_HANDLE_VALUE from rpython.rlib.rwin32 import DWORD, WORD, DWORD_PTR, LPDWORD from rpython.rlib.rwin32 import BOOL, LPVOID, LPCSTR, SIZE_T - from rpython.rlib.rwin32 import INT, LONG, PLONG + from rpython.rlib.rwin32 import LONG, PLONG # export the constants inside and outside. see __init__.py cConfig = rffi_platform.configure(CConfig) @@ -128,7 +124,7 @@ if _POSIX: has_mremap = cConfig['has_mremap'] c_mmap, c_mmap_safe = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, - rffi.INT, off_t], PTR, macro=True) + rffi.INT, off_t], PTR, macro=True) # 'mmap' on linux32 is a macro that calls 'mmap64' _, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT) c_msync, _ = external('msync', [PTR, size_t, rffi.INT], rffi.INT) @@ -138,7 +134,7 @@ # this one is always safe _pagesize = rffi_platform.getintegerfunctionresult('getpagesize', - includes=includes) + includes=includes) _get_allocation_granularity = _get_page_size = lambda: _pagesize elif _MS_WINDOWS: @@ -150,13 +146,13 @@ 'SYSINFO_STRUCT', ("wProcessorArchitecture", WORD), ("wReserved", WORD), - ) + ) SYSINFO_UNION = rffi.CStruct( 'union SYSINFO_UNION', ("dwOemId", DWORD), ("_struct_", SYSINFO_STRUCT), - ) + ) # sorry, I can't find a way to insert the above # because the union field has no name SYSTEM_INFO = rffi_platform.Struct( @@ -209,7 +205,6 @@ VirtualFree = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) - def _get_page_size(): try: si = rffi.make(SYSTEM_INFO) @@ -493,14 +488,6 @@ # this is not checked return res elif _POSIX: -## XXX why is this code here? There is no equivalent in CPython -## if _LINUX: -## # alignment of the address -## value = cast(self.data, c_void_p).value -## aligned_value = value & ~(PAGESIZE - 1) -## # the size should be increased too. otherwise the final -## # part is not "msynced" -## new_size = size + value & (PAGESIZE - 1) res = c_msync(start, size, MS_SYNC) if res == -1: errno = rposix.get_errno() @@ -515,7 +502,7 @@ # check boundings if (src < 0 or dest < 0 or count < 0 or - src + count > self.size or dest + count > self.size): + src + count > self.size or dest + count > self.size): raise RValueError("source or destination out of range") datasrc = self.getptr(src) @@ -567,10 +554,9 @@ SetEndOfFile(self.file_handle) # create another mapping object and remap the file view res = CreateFileMapping(self.file_handle, NULL, PAGE_READWRITE, - newsize_high, newsize_low, self.tagname) + newsize_high, newsize_low, self.tagname) self.map_handle = res - dwErrCode = 0 if self.map_handle: data = MapViewOfFile(self.map_handle, FILE_MAP_WRITE, offset_high, offset_low, newsize) @@ -603,7 +589,7 @@ if len(value) != 1: raise RValueError("mmap assignment must be " - "single-character string") + "single-character string") if index < 0: index += self.size self.data[index] = value[0] @@ -614,12 +600,12 @@ if _POSIX: def mmap(fileno, length, flags=MAP_SHARED, - prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0): + prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0): fd = fileno # check access is not there when flags and prot are there - if access != _ACCESS_DEFAULT and ((flags != MAP_SHARED) or\ + if access != _ACCESS_DEFAULT and ((flags != MAP_SHARED) or (prot != (PROT_WRITE | PROT_READ))): raise RValueError("mmap can't specify both access and flags, prot.") @@ -771,8 +757,8 @@ pass # ignore non-seeking files and errors and trust map_size else: if not high and low <= sys.maxint: - size = low - else: + size = low + else: # not so sure if the signed/unsigned strictness is a good idea: high = rffi.cast(lltype.Unsigned, high) low = rffi.cast(lltype.Unsigned, low) @@ -866,7 +852,7 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT|MEM_RESERVE, + res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError From noreply at buildbot.pypy.org Sun Mar 17 04:59:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 17 Mar 2013 04:59:21 +0100 (CET) Subject: [pypy-commit] pypy default: create/use sqlite.connection.do_all_statements helper Message-ID: <20130317035921.916611C0204@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62378:397124a47858 Date: 2013-03-16 22:18 -0400 http://bitbucket.org/pypy/pypy/changeset/397124a47858/ Log: create/use sqlite.connection.do_all_statements helper diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -394,10 +394,7 @@ def close(self): self._check_thread() - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._finalize() + self.__do_all_statements(Statement._finalize, True) if self._db: ret = _lib.sqlite3_close(self._db) @@ -477,6 +474,18 @@ self.__statements = [ref for ref in self.__statements if ref() is not None] + def __do_all_statements(self, action, reset_cursors): + for weakref in self.__statements: + statement = weakref() + if statement is not None: + action(statement) + + if reset_cursors: + for weakref in self._cursors: + cursor = weakref() + if cursor is not None: + cursor._reset = True + @_check_thread_wrap @_check_closed_wrap def __call__(self, sql): @@ -528,10 +537,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() + self.__do_all_statements(Statement._reset, False) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, @@ -552,15 +558,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() - - for cursor_ref in self._cursors: - cursor = cursor_ref() - if cursor: - cursor._reset = True + self.__do_all_statements(Statement._reset, True) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, @@ -883,7 +881,6 @@ self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False - return self @__check_cursor_wrap @@ -921,9 +918,10 @@ if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement) if rc == _lib.SQLITE_OK: - return self + break else: raise self.__connection._get_exception(rc) + rc = _lib.sqlite3_finalize(statement) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) From noreply at buildbot.pypy.org Sun Mar 17 04:59:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 17 Mar 2013 04:59:22 +0100 (CET) Subject: [pypy-commit] pypy default: sqlite: clear cursor weakrefs periodically like statement weakrefs Message-ID: <20130317035922.E2DC91C0204@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62379:061b9919d6c7 Date: 2013-03-16 23:29 -0400 http://bitbucket.org/pypy/pypy/changeset/061b9919d6c7/ Log: sqlite: clear cursor weakrefs periodically like statement weakrefs diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -364,9 +364,10 @@ self._in_transaction = False self.isolation_level = isolation_level - self._cursors = [] + self.__cursors = [] + self.__cursors_counter = 0 self.__statements = [] - self.__statement_counter = 0 + self.__statements_counter = 0 self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} @@ -466,13 +467,21 @@ exc.error_code = error_code return exc + def _remember_cursor(self, cursor): + self.__cursors.append(weakref.ref(cursor)) + self.__cursors_counter += 1 + if self.__cursors_counter < 200: + return + self.__cursors_counter = 0 + self.__cursors = [r for r in self.__cursors if r() is not None] + def _remember_statement(self, statement): self.__statements.append(weakref.ref(statement)) - self.__statement_counter += 1 - - if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements - if ref() is not None] + self.__statements_counter += 1 + if self.__statements_counter < 200: + return + self.__statements_counter = 0 + self.__statements = [r for r in self.__statements if r() is not None] def __do_all_statements(self, action, reset_cursors): for weakref in self.__statements: @@ -481,7 +490,7 @@ action(statement) if reset_cursors: - for weakref in self._cursors: + for weakref in self.__cursors: cursor = weakref() if cursor is not None: cursor._reset = True @@ -785,14 +794,9 @@ __statement = None def __init__(self, con): - self.__initialized = True - self.__connection = con - if not isinstance(con, Connection): raise TypeError - con._check_thread() - con._check_closed() - con._cursors.append(weakref.ref(self)) + self.__connection = con self.arraysize = 1 self.row_factory = None @@ -802,11 +806,12 @@ self.__description = None self.__rowcount = -1 + con._check_thread() + con._remember_cursor(self) + + self.__initialized = True + def __del__(self): - try: - self.__connection._cursors.remove(weakref.ref(self)) - except (AttributeError, ValueError): - pass if self.__statement: self.__statement._reset() @@ -998,6 +1003,7 @@ def __init__(self, connection, sql): self.__con = connection + self.__con._remember_statement(self) if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") @@ -1025,10 +1031,9 @@ ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(sql)) self._kind = Statement._DQL - if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) - self.__con._remember_statement(self) + sql = sql.value.decode('utf-8') if _check_remaining_sql(sql): raise Warning("You can only execute one statement at a time.") From noreply at buildbot.pypy.org Sun Mar 17 04:59:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 17 Mar 2013 04:59:24 +0100 (CET) Subject: [pypy-commit] pypy default: call con.close() to cleanup after test Message-ID: <20130317035924.303ED1C0204@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62380:3dd4799bc8c3 Date: 2013-03-16 23:58 -0400 http://bitbucket.org/pypy/pypy/changeset/3dd4799bc8c3/ Log: call con.close() to cleanup after test 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 @@ -159,6 +159,7 @@ con.commit() except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") + con.close() def test_statement_arg_checking(): con = _sqlite3.connect(':memory:') @@ -194,3 +195,4 @@ with pytest.raises(ValueError) as e: con.execute('insert into foo(x) values (?)', 2) assert str(e.value) == 'parameters are of unsupported type' + con.close() From noreply at buildbot.pypy.org Sun Mar 17 16:38:44 2013 From: noreply at buildbot.pypy.org (timfel) Date: Sun, 17 Mar 2013 16:38:44 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Use bitInver32 instead of bitInvert, this fixes BitBltSim tests and examples in miniimage. Message-ID: <20130317153844.AB1291C03B2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r196:df393bec4673 Date: 2013-03-17 16:37 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/df393bec4673/ Log: Use bitInver32 instead of bitInvert, this fixes BitBltSim tests and examples in miniimage. diff --git a/BitBltSim.19.cs b/BitBltSim.19.cs new file mode 100644 --- /dev/null +++ b/BitBltSim.19.cs @@ -0,0 +1,1 @@ +'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 17 March 2013 at 4:20:53 pm'! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug ' classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' poolDictionaries: '' category: 'Graphics-Support'! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path ' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBlt methodsFor: 'private'! clipRange destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - (clipY - destY). simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! !BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! copyBitsAgain self simulateCopyBits.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! calculateOffsets "check if we need to preload buffer (i.e., two words of source needed for first word of destination)" simPreload _ (sourceForm notNil) and: [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. simHDir < 0 ifTrue: [simPreload _ simPreload == false]. "calculate starting offsets" simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). simDestIndex _ simDy * simDestRaster + (simDx // WordSize). "calculate increments from end of 1 line to start of next" simSourceDelta _ (simSourceRaster * simVDir) - (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! checkOverlap | t | "check for possible overlap of source and destination" simHDir _ simVDir _ 1. "defaults for no overlap" (sourceForm == destForm and: [simDy >= simSy]) ifTrue: [simDy > simSy "have to start at bottom" ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] ifFalse: [simDx > simSx "y's are equal, but x's are backward" ifTrue: [simHDir _ -1. simSx _ simSx + simW - 1. "start at right" simDx _ simDx + simW - 1. "and fix up masks" simSkewMask _ simSkewMask bitInvert32. t _ simMask1. simMask1 _ simMask2. simMask2 _ t]]]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! computeMasks | startBits endBits | "calculate skeq and edge masks" simDestBits _ destForm bits. simDestRaster _ destForm width - 1 // WordSize + 1. sourceForm notNil ifTrue: [simSourceBits _ sourceForm bits. simSourceRaster _ sourceForm width - 1 // WordSize + 1]. halftoneForm notNil ifTrue: [simHalftoneBits _ halftoneForm bits]. simSkew _ (simSx - simDx) bitAnd: WordSize0. "how many bits source gets skewed to right" startBits _ WordSize - (simDx bitAnd: WordSize0). "how many bits in first word" simMask1 _ RightMasks at: startBits + 1. endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). "how many bits in last word" simMask2 _ (RightMasks at: endBits + 1) bitInvert32. simSkewMask _ (simSkew = 0 ifTrue: [0] ifFalse: [RightMasks at: WordSize - simSkew + 1]). "determine number of words stored per line; merge masks if necessary" simW < startBits ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. simMask2 _ 0. simNWords _ 1] ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! copyLoop | prevWord thisWord skewWord mergeMask halftoneWord mergeWord | 1 to: simH do: "here is the vertical loop" [:i | (halftoneForm notNil) ifTrue: "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" [halftoneWord _ simHalftoneBits at: (1 + ((simDy bitAnd: WordSize0) \\ simHalftoneBits size)). simDy _ simDy + simVDir] ifFalse: [halftoneWord _ AllOnes]. skewWord _ halftoneWord. simPreload ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. "load the 32bit shifter. TODO: check if this is WordSize dependent" simSourceIndex _ simSourceIndex + simHDir] ifFalse: [prevWord _ 0]. mergeMask _ simMask1. 1 to: simNWords do: "here is the inner horizontal loop" [:word | sourceForm notNil "if source is used" ifTrue: [prevWord _ prevWord bitAnd: simSkewMask. thisWord := simSourceIndex >= simSourceBits size ifTrue: [AllOnes] "XXX: Change from BB: Ignore out-of bounds" ifFalse: [simSourceBits at: simSourceIndex + 1]. "pick up next word" skewWord _ prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert32). prevWord _ thisWord. "Change from BB: bitAnd: AllOnes to stay in word bounds" skewWord _ ((skewWord bitShift: simSkew) bitAnd: AllOnes) bitOr: (skewWord bitShift: simSkew - WordSize)]. "WordSize-bit rotate" mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (simDestBits at: simDestIndex + 1). simDestBits at: simDestIndex + 1 put: ((mergeMask bitAnd: mergeWord) bitOr: (mergeMask bitInvert32 bitAnd: (simDestBits at: simDestIndex + 1))). simSourceIndex _ simSourceIndex + simHDir. simDestIndex _ simDestIndex + simHDir. word = (simNWords - 1) ifTrue: [mergeMask _ simMask2] ifFalse: [mergeMask _ AllOnes]]. simSourceIndex _ simSourceIndex + simSourceDelta. simDestIndex _ simDestIndex + simDestDelta]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! merge: srcWord with: dstWord "These are the 16 combination rules." combinationRule = 0 ifTrue: [^ 0]. combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert32]. combinationRule = 3 ifTrue: [^ srcWord]. combinationRule = 4 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord]. combinationRule = 5 ifTrue: [^ dstWord]. combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. combinationRule = 8 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord bitInvert32]. combinationRule = 9 ifTrue: [^ srcWord bitInvert32 bitXor: dstWord]. combinationRule = 10 ifTrue: [^ dstWord bitInvert32]. combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert32]. combinationRule = 12 ifTrue: [^ srcWord bitInvert32]. combinationRule = 13 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord]. combinationRule = 14 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord bitInvert]. combinationRule = 15 ifTrue: [^ dstWord]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 14:49'! sanitizeInput destForm unhibernate. sourceForm ifNil: [sourceForm := destForm] ifNotNil: [sourceForm unhibernate]. halftoneForm ifNotNil: [ (halftoneForm isKindOf: Form) ifFalse: [halftoneForm := Form new bits: halftoneForm; yourself]. halftoneForm unhibernate]. width ifNil: [width := sourceForm width]. height ifNil: [height := sourceForm height].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 13:04'! simClipRange "clip and adjust source origin and extent appropriately" "first in x" destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. "then in y" destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - clipY - destY. simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:31'! simDebug: aString simInDebug == true ifFalse: [simInDebug := true. aString displayAt: 10 at 10. 1 to: 10000000 do: [:i |]. simInDebug := false]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:30'! simulateCopyBits self simDebug: Time now asString. self sanitizeInput. self simClipRange. (simW <= 0 or: [simH <= 0]) ifTrue: [^ self]. self computeMasks. self checkOverlap. self calculateOffsets. self copyLoop.! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! exampleOne "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" | pathClass path displayDepth | displayDepth := Display depth. Display newDepth: 1. (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. Display fillWhite. 1 to: 16 do: [:index | BitBlt exampleAt: (path at: index) rule: index - 1 fillColor: nil]. [Sensor anyButtonPressed] whileFalse: []. Display newDepth: displayDepth. "BitBlt exampleOne"! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! exampleTwo "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." | f aBitBlt displayDepth | "create a small black Form source as a brush. " displayDepth := Display depth. Display newDepth: 1. f := Form extent: 20 @ 20. f fillBlack. "create a BitBlt which will OR gray into the display. " aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: Form over destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. "paint the gray Form on the screen for a while. " [Sensor anyButtonPressed] whileFalse: [aBitBlt destOrigin: Sensor cursorPoint. aBitBlt simulateCopyBits]. Display newDepth: displayDepth. "BitBlt exampleTwo"! ! !BitBlt class methodsFor: 'private' stamp: 'tfel 3/15/2013 14:32'! exampleAt: originPoint rule: rule fillColor: mask "This builds a source and destination form and copies the source to the destination using the specifed rule and mask. It is called from the method named exampleOne. Only works with Display depth of 1" | s d border aBitBlt | border:=Form extent: 32 at 32. border fillBlack. border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). s displayOn: Display at: originPoint. border displayOn: Display at: originPoint rule: Form under. d displayOn: Display at: originPoint + (s width @0). border displayOn: Display at: originPoint + (s width @0) rule: Form under. d displayOn: Display at: originPoint + (s extent // (2 @ 1)). aBitBlt := BitBlt destForm: Display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits. border displayOn: Display at: originPoint + (s extent // (2 @ 1)) rule: Form under. "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! !BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! initialize "self initialize" super initialize. WordSize := 32. WordSize0 := WordSize - 1. RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. AllOnes _ (2 raisedTo: WordSize) - 1. ! ! !BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! destForm "black top half, white bottom half" | bitmap | bitmap := Bitmap new: 32. #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) withIndexDo: [:word :idx | bitmap at: idx put: word]. ^ (Form extent: 32 at 32 depth: 1) bits: bitmap; yourself! ! !BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! sourceForm "white form with black rect in the middle" | bitmap | bitmap := Bitmap new: 32. #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) withIndexDo: [:word :idx | bitmap at: idx put: word]. ^ (Form extent: 32 at 32 depth: 1) bits: bitmap; yourself! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test1 self runTest: 1.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:41'! test10 self runTest: 10.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:39'! test11 self runTest: 11.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! test12 self runTest: 12.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! test13 self runTest: 13.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! test14 self runTest: 14.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! test15 self runTest: 15.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! test16 self runTest: 16.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test2 self runTest: 2.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test3 self runTest: 3.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test4 self runTest: 4.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test5 self runTest: 5.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test6 self runTest: 6.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test7 self runTest: 7.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test8 self runTest: 8.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test9 self runTest: 9.! ! !BitBltSimTest methodsFor: 'test data' stamp: 'tfel 3/15/2013 14:43'! bitsForTest: index | results | results := #( #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ). ^ results at: index! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/17/2013 16:18'! runTest: index "self runTestVisual: index" "to show something" self runTestLarge: index "to test non-aligned stuff" "self runTestDark: index" "to run without blitting primitive, against saved data" ! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:37'! runTestDark: index | s d rule | rule := index - 1. s := self sourceForm. d := self destForm. (BitBlt destForm: d sourceForm: s fillColor: nil combinationRule: rule destOrigin: 0 at 0 sourceOrigin: 0 at 0 extent: s extent clipRect: (0 at 0 extent: d extent)) simulateCopyBits. self assert: d bits asArray = (self bitsForTest: index). ! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:30'! runTestLarge: index | s d aBitBlt mask rule simD originPoint destOrigin | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 500 at 500. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). destOrigin := originPoint + (s extent // (2 @ 1)). simD := d deepCopy. aBitBlt := BitBlt destForm: simD sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: simD computeBoundingBox. aBitBlt simulateCopyBits. aBitBlt := BitBlt destForm: d sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: d computeBoundingBox. aBitBlt copyBits. self assert: [d bits = simD bits]. ! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:43'! runTestVisual: index | s d aBitBlt mask rule simD originPoint destOrigin | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). destOrigin := 0 @ 0. simD := d deepCopy. aBitBlt := BitBlt destForm: simD sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: simD computeBoundingBox. aBitBlt simulateCopyBits. aBitBlt := BitBlt destForm: d sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: d computeBoundingBox. aBitBlt copyBits. simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. d displayOn: Display at: originPoint - (10 at 0) rule: Form over. d bits = simD bits ifTrue: [index asString displayAt: originPoint - 20] ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! !BitBltSimTest methodsFor: 'initialize-release' stamp: 'tfel 3/15/2013 14:38'! initialize super initialize. "World restoreDisplay." "(Form extent: 500 at 300 depth: 32) fill: (0 at 0 extent: 500 at 300) fillColor: Color green muchDarker; displayOn: Display at: 0 at 0 rule: Form over."! ! !BitBltSimTest methodsFor: 'running' stamp: 'tfel 3/15/2013 11:38'! setUp | pathClass | (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. ! ! !BitBltSimTest class methodsFor: 'as yet unclassified' stamp: 'tfel 3/17/2013 16:08'! runAllTestsBlind 1 to: 16 do: [:idx | self new setUp; runTestDark: idx].! ! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBltSimTest reorganize! ('sourceForm' destForm sourceForm) ('testing' test1 test10 test11 test12 test13 test14 test15 test16 test2 test3 test4 test5 test6 test7 test8 test9) ('test data' bitsForTest:) ('running-modes' runTest: runTestDark: runTestLarge: runTestVisual:) ('initialize-release' initialize) ('running' setUp) ! BitBlt initialize! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug' classVariableNames: 'AllOnes RightMasks WordSize WordSize0' poolDictionaries: '' category: 'Graphics-Support'! \ No newline at end of file diff --git a/images/minibluebookdebug.image b/images/minibluebookdebug.image index 7b6c3b1b62a5489daec16ba35442c7f80b796917..216c8fee57511e58f50f6757a635bdaad0672d2b GIT binary patch [cut] From noreply at buildbot.pypy.org Sun Mar 17 17:46:29 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Mar 2013 17:46:29 +0100 (CET) Subject: [pypy-commit] pypy fast-newarray: (exarkun, fijal) Make rewrite emit a new operation called malloc_nursery_varsize Message-ID: <20130317164629.DA99F1C0635@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: fast-newarray Changeset: r62381:02b837da85cc Date: 2013-03-17 09:46 -0700 http://bitbucket.org/pypy/pypy/changeset/02b837da85cc/ Log: (exarkun, fijal) Make rewrite emit a new operation called malloc_nursery_varsize diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -9,18 +9,24 @@ from rpython.jit.metainterp.history import JitCellToken class GcRewriterAssembler(object): - # This class performs the following rewrites on the list of operations: - # - # - Remove the DEBUG_MERGE_POINTs. - # - # - Turn all NEW_xxx to either a CALL_MALLOC_GC, or a CALL_MALLOC_NURSERY - # followed by SETFIELDs in order to initialize their GC fields. The - # two advantages of CALL_MALLOC_NURSERY is that it inlines the common - # path, and we need only one such operation to allocate several blocks - # of memory at once. - # - # - Add COND_CALLs to the write barrier before SETFIELD_GC and - # SETARRAYITEM_GC operations. + """ This class performs the following rewrites on the list of operations: + + - Remove the DEBUG_MERGE_POINTs. + + - Turn all NEW_xxx to either a CALL_MALLOC_GC, or a CALL_MALLOC_NURSERY + followed by SETFIELDs in order to initialize their GC fields. The + two advantages of CALL_MALLOC_NURSERY is that it inlines the common + path, and we need only one such operation to allocate several blocks + of memory at once. + + - Add COND_CALLs to the write barrier before SETFIELD_GC and + SETARRAYITEM_GC operations. + + recent_mallocs contains a dictionary of variable -> None. If a variable + is in the dictionary, next setfields can be called without a write barrier, + because the variable got allocated after the last potentially collecting + resop + """ _previous_size = -1 _op_malloc_nursery = None @@ -32,7 +38,7 @@ self.cpu = cpu self.newops = [] self.known_lengths = {} - self.recent_mallocs = {} # set of variables + self.recent_mallocs = {} def rewrite(self, operations): # we can only remember one malloc since the next malloc can possibly @@ -119,6 +125,12 @@ pass # total_size is still -1 elif arraydescr.itemsize == 0: total_size = arraydescr.basesize + elif (self.gc_ll_descr.can_use_nursery_malloc(1) and + self.gen_malloc_nursery_varsize(arraydescr.itemsize, + v_length, op.result, arraydescr)): + self.gen_initialize_tid(op.result, arraydescr.tid) + self.gen_initialize_len(op.result, v_length, arraydescr.lendescr) + return if (total_size >= 0 and self.gen_malloc_nursery(total_size, op.result)): self.gen_initialize_tid(op.result, arraydescr.tid) @@ -152,7 +164,7 @@ size_box, descr=descrs.jfi_frame_size) self.newops.append(op0) - self.gen_malloc_nursery_varsize(size_box, frame, is_small=True) + self.gen_malloc_nursery_varsize_small(size_box, frame) self.gen_initialize_tid(frame, descrs.arraydescr.tid) length_box = history.BoxInt() op1 = ResOperation(rop.GETFIELD_GC, [history.ConstInt(frame_info)], @@ -281,10 +293,25 @@ self._gen_call_malloc_gc([ConstInt(addr), v_num_elem], v_result, self.gc_ll_descr.malloc_unicode_descr) - def gen_malloc_nursery_varsize(self, sizebox, v_result, is_small=False): + def gen_malloc_nursery_varsize(self, itemsize, v_length, v_result, + arraydescr): + """ itemsize is an int, v_length and v_result are boxes + """ + if (arraydescr.basesize != self.gc_ll_descr.standard_array_basesize + or arraydescr.lendescr.offset != + self.gc_ll_descr.standard_array_length_ofs): + return False + self.emitting_an_operation_that_can_collect() + op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE, + [ConstInt(itemsize), v_length], + v_result) + self.newops.append(op) + self.recent_mallocs[v_result] = None + return True + + def gen_malloc_nursery_varsize_small(self, sizebox, v_result): """ Generate CALL_MALLOC_NURSERY_VARSIZE_SMALL """ - assert is_small self.emitting_an_operation_that_can_collect() op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE_SMALL, [sizebox], diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -85,6 +85,7 @@ signedframedescr = self.cpu.signedframedescr floatframedescr = self.cpu.floatframedescr casmdescr.compiled_loop_token = clt + tzdescr = None # noone cares # namespace.update(locals()) # @@ -107,7 +108,7 @@ class BaseFakeCPU(object): JITFRAME_FIXED_SIZE = 0 - + def __init__(self): self.tracker = FakeTracker() self._cache = {} @@ -121,7 +122,7 @@ def unpack_arraydescr_size(self, d): return 0, d.itemsize, 0 - + def arraydescrof(self, ARRAY): try: return self._cache[ARRAY] @@ -129,7 +130,7 @@ r = ArrayDescr(1, 2, FieldDescr('len', 0, 0, 0), 0) self._cache[ARRAY] = r return r - + def fielddescrof(self, STRUCT, fname): key = (STRUCT, fname) try: @@ -407,9 +408,9 @@ jump(i0) """, """ [i0] - p0 = call_malloc_gc(ConstClass(malloc_array), 1, \ - %(bdescr.tid)d, i0, \ - descr=malloc_array_descr) + p0 = call_malloc_nursery_varsize(1, i0) + setfield_gc(p0, %(bdescr.tid)d, descr=tiddescr) + setfield_gc(p0, i0, descr=blendescr) jump(i0) """) diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py --- a/rpython/jit/metainterp/executor.py +++ b/rpython/jit/metainterp/executor.py @@ -354,6 +354,7 @@ rop.QUASIIMMUT_FIELD, rop.CALL_MALLOC_GC, rop.CALL_MALLOC_NURSERY, + rop.CALL_MALLOC_NURSERY_VARSIZE, rop.CALL_MALLOC_NURSERY_VARSIZE_SMALL, rop.LABEL, ): # list of opcodes never executed by pyjitpl diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -529,6 +529,7 @@ 'CALL_PURE/*d', # removed before it's passed to the backend 'CALL_MALLOC_GC/*d', # like CALL, but NULL => propagate MemoryError 'CALL_MALLOC_NURSERY/1', # nursery malloc, const number of bytes, zeroed + 'CALL_MALLOC_NURSERY_VARSIZE/2', 'CALL_MALLOC_NURSERY_VARSIZE_SMALL/1', # nursery malloc, non-const number of bytes, zeroed # note that the number of bytes must be well known to be small enough diff --git a/rpython/jit/tool/oparser.py b/rpython/jit/tool/oparser.py --- a/rpython/jit/tool/oparser.py +++ b/rpython/jit/tool/oparser.py @@ -106,6 +106,8 @@ tt = self.model.TargetToken(token) self._consts[poss_descr] = tt return tt + else: + raise def box_for_var(self, elem): try: From noreply at buildbot.pypy.org Sun Mar 17 18:13:24 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Mar 2013 18:13:24 +0100 (CET) Subject: [pypy-commit] pypy default: Removed duplication of DEBUG_COUTNER struct from ARM. Message-ID: <20130317171324.4C55B1C0635@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62382:7a552b444eff Date: 2013-03-17 10:13 -0700 http://bitbucket.org/pypy/pypy/changeset/7a552b444eff/ Log: Removed duplication of DEBUG_COUTNER struct from ARM. Also organized imports. diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1,43 +1,30 @@ from __future__ import with_statement + import os + +from rpython.jit.backend.arm import conditions as c, registers as r +from rpython.jit.backend.arm.arch import (WORD, DOUBLE_WORD, FUNC_ALIGN, + JITFRAME_FIXED_SIZE) +from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder +from rpython.jit.backend.arm.locations import imm, StackLocation +from rpython.jit.backend.arm.opassembler import ResOpAssembler +from rpython.jit.backend.arm.regalloc import (Regalloc, + CoreRegisterManager, check_imm_arg, VFPRegisterManager, + operations as regalloc_operations, + operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.arm.helper.assembler import saved_registers -from rpython.jit.backend.arm import conditions as c -from rpython.jit.backend.arm import registers as r -from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, FUNC_ALIGN, \ - N_REGISTERS_SAVED_BY_MALLOC, \ - JITFRAME_FIXED_SIZE -from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder -from rpython.jit.backend.arm.locations import get_fp_offset, imm, StackLocation -from rpython.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, - CoreRegisterManager, check_imm_arg, - VFPRegisterManager, - operations as regalloc_operations, - operations_with_guard as regalloc_operations_with_guard) +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken -from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT -from rpython.jit.metainterp.history import BoxInt, ConstInt +from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT, BoxInt, ConstInt from rpython.jit.metainterp.resoperation import rop, ResOperation -from rpython.rlib import rgc -from rpython.rlib.objectmodel import we_are_translated, specialize +from rpython.rlib.debug import debug_print, debug_start, debug_stop +from rpython.rlib.jit import AsmInfo +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref -from rpython.rtyper.lltypesystem import lltype, rffi, llmemory -from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.jit.backend.arm.opassembler import ResOpAssembler -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints, fatalerror) -from rpython.rlib.jit import AsmInfo -from rpython.rlib.objectmodel import compute_unique_id -from rpython.rlib.rarithmetic import intmask, r_uint - - -DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), - ('type', lltype.Char), # 'b'ridge, 'l'abel or - # 'e'ntry point - ('number', lltype.Signed)) +from rpython.rtyper.lltypesystem import lltype, rffi class AssemblerARM(ResOpAssembler): @@ -278,7 +265,7 @@ mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) mc.LDR_ri(r.r0.value, r.r0.value) mc.TST_rr(r.r0.value, r.r0.value) - # restore registers and return + # restore registers and return # We check for c.EQ here, meaning all bits zero in this case mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value], cond=c.EQ) # @@ -602,7 +589,7 @@ self.mc.LDR_ri(r.lr.value, r.lr.value) # ldr lr, *lengh # calculate ofs self.mc.SUB_rr(r.ip.value, r.ip.value, r.sp.value) # SUB ip, current - # if ofs + # if ofs self.mc.CMP_rr(r.ip.value, r.lr.value) # CMP ip, lr self.mc.BL(self.stack_check_slowpath, c=c.HI) # call if ip > lr # @@ -758,7 +745,6 @@ self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), expected_size=expected_size) - def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. @@ -952,7 +938,7 @@ effectinfo = op.getdescr().get_extra_info() oopspecindex = effectinfo.oopspecindex asm_llong_operations[oopspecindex](self, op, arglocs, regalloc, fcond) - return fcond + return fcond def regalloc_emit_math(self, op, arglocs, fcond, regalloc): effectinfo = op.getdescr().get_extra_info() @@ -1075,7 +1061,6 @@ assert 0, 'unsupported case' def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL): - pushed = False if loc.is_reg(): assert prev_loc.type != FLOAT, 'trying to load from an \ incompatible location into a core register' @@ -1299,7 +1284,6 @@ self.store_reg(mc, r.ip, r.fp, ofs) - def not_implemented(msg): os.write(2, '[ARM/asm] %s\n' % msg) raise NotImplementedError(msg) diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,4 +1,3 @@ - from rpython.rlib import rgc from rpython.rlib.rarithmetic import r_uint from rpython.jit.backend.llsupport.symbolic import WORD @@ -7,8 +6,16 @@ from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype from rpython.jit.backend.llsupport.memcpy import memcpy_fn -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints) +from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints + + +DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', + # 'b'ridge, 'l'abel or # 'e'ntry point + ('i', lltype.Signed), + ('type', lltype.Char), + ('number', lltype.Signed) +) + class GuardToken(object): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1,7 +1,8 @@ +import sys +import os -import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe -from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler +from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler, DEBUG_COUNTER from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt @@ -34,17 +35,15 @@ from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import compute_unique_id + # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, # better safe than sorry CALL_ALIGN = 16 // WORD + def align_stack_words(words): return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) -DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), - ('type', lltype.Char), # 'b'ridge, 'l'abel or - # 'e'ntry point - ('number', lltype.Signed)) class Assembler386(BaseAssembler): _regalloc = None From noreply at buildbot.pypy.org Sun Mar 17 18:18:03 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Mar 2013 18:18:03 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal) removed duplication in assembler backends Message-ID: <20130317171803.85C001C138A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62383:4160eabbd660 Date: 2013-03-17 10:17 -0700 http://bitbucket.org/pypy/pypy/changeset/4160eabbd660/ Log: (alex, fijal) removed duplication in assembler backends diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -17,8 +17,8 @@ from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT, BoxInt, ConstInt -from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT +from rpython.jit.metainterp.resoperation import rop from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rlib.jit import AsmInfo from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id @@ -108,18 +108,6 @@ self.loop_run_counters.append(struct) return struct - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) - @specialize.argtype(1) def _inject_debugging_code(self, looptoken, operations, tp, number): if self._debug: diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,12 +1,14 @@ +from rpython.jit.backend.llsupport import jitframe +from rpython.jit.backend.llsupport.memcpy import memcpy_fn +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.metainterp.history import (INT, REF, FLOAT, JitCellToken, + ConstInt, BoxInt) +from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib import rgc +from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints from rpython.rlib.rarithmetic import r_uint -from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.backend.llsupport import jitframe -from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.jit.backend.llsupport.memcpy import memcpy_fn -from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', @@ -210,3 +212,15 @@ # XXX here should be emitted guard_not_forced, but due # to incompatibilities in how it's done, we leave it for the # caller to deal with + + def _append_debugging_code(self, operations, tp, number, token): + counter = self._register_counter(tp, number, token) + c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) + box = BoxInt() + box2 = BoxInt() + ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], + box, descr=self.debug_counter_descr), + ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), + ResOperation(rop.SETFIELD_RAW, [c_adr, box2], + None, descr=self.debug_counter_descr)] + operations.extend(ops) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -5,7 +5,7 @@ from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler, DEBUG_COUNTER from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap -from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt +from rpython.jit.metainterp.history import Const, Box from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop @@ -24,7 +24,7 @@ imm0, imm1, FloatImmedLoc, RawEbpLoc, RawEspLoc) from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.backend.x86 import rx86, codebuf -from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.x86 import support from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rlib import rgc @@ -746,18 +746,6 @@ targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) - @specialize.argtype(1) def _inject_debugging_code(self, looptoken, operations, tp, number): if self._debug: From noreply at buildbot.pypy.org Sun Mar 17 18:39:22 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Mar 2013 18:39:22 +0100 (CET) Subject: [pypy-commit] pypy asm-backend-dupe-removal: (alex, fijal): start refactoring to remove duplication Message-ID: <20130317173922.D5A8C1C03B2@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: asm-backend-dupe-removal Changeset: r62384:9d2f1acf5a83 Date: 2013-03-17 10:38 -0700 http://bitbucket.org/pypy/pypy/changeset/9d2f1acf5a83/ Log: (alex, fijal): start refactoring to remove duplication diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -108,26 +108,6 @@ self.loop_run_counters.append(struct) return struct - @specialize.argtype(1) - def _inject_debugging_code(self, looptoken, operations, tp, number): - if self._debug: - # before doing anything, let's increase a counter - s = 0 - for op in operations: - s += op.getopnum() - looptoken._arm_debug_checksum = s - - newoperations = [] - self._append_debugging_code(newoperations, tp, number, - None) - for op in operations: - newoperations.append(op) - if op.getopnum() == rop.LABEL: - self._append_debugging_code(newoperations, 'l', number, - op.getdescr()) - operations = newoperations - return operations - @staticmethod def _release_gil_shadowstack(): before = rffi.aroundstate.before diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,9 +1,7 @@ from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.llsupport.memcpy import memcpy_fn from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.metainterp.history import (INT, REF, FLOAT, JitCellToken, - ConstInt, BoxInt) -from rpython.jit.metainterp.resoperation import ResOperation, rop +from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken from rpython.rlib import rgc from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints from rpython.rlib.rarithmetic import r_uint @@ -212,15 +210,3 @@ # XXX here should be emitted guard_not_forced, but due # to incompatibilities in how it's done, we leave it for the # caller to deal with - - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -106,9 +106,9 @@ rgc._make_sure_does_not_move(llref) gcrefs_output_list.append(llref) - def rewrite_assembler(self, cpu, operations, gcrefs_output_list): + def rewrite_assembler(self, cpu, operations, looptoken, tp, number, gcrefs_output_list): rewriter = GcRewriterAssembler(self, cpu) - newops = rewriter.rewrite(operations) + newops = rewriter.rewrite(operations, looptoken, tp, number) # record all GCREFs, because the GC (or Boehm) cannot see them and # keep them alive if they end up as constants in the assembler for op in newops: diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -1,12 +1,12 @@ +from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.codewriter import heaptracker +from rpython.jit.metainterp import history +from rpython.jit.metainterp.resoperation import ResOperation, rop +from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxPtr, ConstPtr, JitCellToken from rpython.rlib.rarithmetic import ovfcheck -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.jit.metainterp import history -from rpython.jit.metainterp.history import ConstInt, BoxPtr, ConstPtr -from rpython.jit.metainterp.resoperation import ResOperation, rop -from rpython.jit.codewriter import heaptracker -from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr -from rpython.jit.metainterp.history import JitCellToken +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + class GcRewriterAssembler(object): # This class performs the following rewrites on the list of operations: @@ -34,16 +34,19 @@ self.known_lengths = {} self.recent_mallocs = {} # set of variables - def rewrite(self, operations): + def rewrite(self, operations, looptoken, tp, number): # we can only remember one malloc since the next malloc can possibly # collect; but we can try to collapse several known-size mallocs into # one, both for performance and to reduce the number of write # barriers. We do this on each "basic block" of operations, which in # this case means between CALLs or unknown-size mallocs. # + self._append_debugging_code(looptoken, tp, number) for op in operations: if op.getopnum() == rop.DEBUG_MERGE_POINT: continue + if op.getopnum() == rop.LABEL: + self._append_debugging_code(looptoken, 'l', number) # ---------- turn NEWxxx into CALL_MALLOC_xxx ---------- if op.is_malloc(): self.handle_malloc_operation(op) @@ -72,7 +75,18 @@ self.newops.append(op) return self.newops - # ---------- + def _append_debugging_code(self, token, tp, number): + if self.debug: + counter = self._register_counter(tp, number, token) + c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) + box = BoxInt() + box2 = BoxInt() + ops = [ + ResOperation(rop.GETFIELD_RAW, [c_adr], box, descr=self.debug_counter_descr), + ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), + ResOperation(rop.SETFIELD_RAW, [c_adr, box2], None, descr=self.debug_counter_descr) + ] + self.newops.extend(ops) def handle_malloc_operation(self, op): opnum = op.getopnum() diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -22,7 +22,7 @@ r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG, RegLoc, FrameLoc, ConstFloatLoc, ImmedLoc, AddressLoc, imm, imm0, imm1, FloatImmedLoc, RawEbpLoc, RawEspLoc) -from rpython.rlib.objectmodel import we_are_translated, specialize +from rpython.rlib.objectmodel import we_are_translated from rpython.jit.backend.x86 import rx86, codebuf from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.x86 import support @@ -447,10 +447,10 @@ self._release_gil_asmgcc) reacqgil_func = llhelper(self._CLOSESTACK_FUNC, self._reacquire_gil_asmgcc) - self.releasegil_addr = self.cpu.cast_ptr_to_int(releasegil_func) + self.releasegil_addr = self.cpu.cast_ptr_to_int(releasegil_func) self.reacqgil_addr = self.cpu.cast_ptr_to_int(reacqgil_func) - def assemble_loop(self, loopname, inputargs, operations, looptoken, log): + def assemble_loop(self, loopname, inputargs, operations, looptoken): '''adds the following attributes to looptoken: _ll_function_addr (address of the generated func, as an int) _ll_loop_code (debug: addr of the start of the ResOps) @@ -475,10 +475,6 @@ clt.allgcrefs = [] clt.frame_info.clear() # for now - if log: - operations = self._inject_debugging_code(looptoken, operations, - 'e', looptoken.number) - regalloc = RegAlloc(self, self.cpu.translate_support_code) # self._call_header_with_stack_check() @@ -746,24 +742,6 @@ targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None - @specialize.argtype(1) - def _inject_debugging_code(self, looptoken, operations, tp, number): - if self._debug: - s = 0 - for op in operations: - s += op.getopnum() - - newoperations = [] - self._append_debugging_code(newoperations, tp, number, - None) - for op in operations: - newoperations.append(op) - if op.getopnum() == rop.LABEL: - self._append_debugging_code(newoperations, 'l', number, - op.getdescr()) - operations = newoperations - return operations - def _assemble(self, regalloc, inputargs, operations): self._regalloc = regalloc regalloc.compute_hint_frame_locations(operations) 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 @@ -132,8 +132,8 @@ for _i, _reg in enumerate(gpr_reg_mgr_cls.all_regs): gpr_reg_mgr_cls.all_reg_indexes[_reg.value] = _i + class RegAlloc(BaseRegalloc): - def __init__(self, assembler, translate_support_code=False): assert isinstance(translate_support_code, bool) # variables that have place in register @@ -143,25 +143,25 @@ self.jump_target_descr = None self.final_jump_op = None - def _prepare(self, inputargs, operations, allgcrefs): + def _prepare(self, inputargs, operations, allgcrefs, tp, number): cpu = self.assembler.cpu self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field()) - operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, - allgcrefs) + operations = cpu.gc_ll_descr.rewrite_assembler( + cpu, operations, self.assembler.current_clt, tp, number, allgcrefs + ) # compute longevity of variables - longevity, last_real_usage = compute_vars_longevity( - inputargs, operations) + longevity, last_real_usage = compute_vars_longevity(inputargs, operations) self.longevity = longevity self.last_real_usage = last_real_usage self.rm = gpr_reg_mgr_cls(self.longevity, - frame_manager = self.fm, - assembler = self.assembler) - self.xrm = xmm_reg_mgr_cls(self.longevity, frame_manager = self.fm, - assembler = self.assembler) + frame_manager=self.fm, + assembler=self.assembler) + self.xrm = xmm_reg_mgr_cls(self.longevity, frame_manager=self.fm, + assembler=self.assembler) return operations def prepare_loop(self, inputargs, operations, looptoken, allgcrefs): - operations = self._prepare(inputargs, operations, allgcrefs) + operations = self._prepare(inputargs, operations, allgcrefs, 'e', looptoken.number) self._set_initial_bindings(inputargs, looptoken) # note: we need to make a copy of inputargs because possibly_free_vars # is also used on op args, which is a non-resizable list diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -88,9 +88,9 @@ lines = machine_code_dump(data, addr, self.backend_name, label_list) print ''.join(lines) - def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, name=''): return self.assembler.assemble_loop(name, inputargs, operations, - looptoken, log=log) + looptoken) def compile_bridge(self, faildescr, inputargs, operations, original_loop_token, log=True): From noreply at buildbot.pypy.org Sun Mar 17 18:55:35 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Mar 2013 18:55:35 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, armin, fijal): remove unused nonsense Message-ID: <20130317175535.6FC541C0635@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62385:4f4f2e97fef7 Date: 2013-03-17 10:55 -0700 http://bitbucket.org/pypy/pypy/changeset/4f4f2e97fef7/ Log: (alex, armin, fijal): remove unused nonsense diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -29,7 +29,6 @@ if self.sthread is not None: raise geterror(self.space, "continulet already __init__ialized") sthread = build_sthread(self.space) - #workaround_disable_jit(sthread) # # hackish: build the frame "by hand", passing it the correct arguments space = self.space @@ -72,8 +71,7 @@ global_state.clear() raise geterror(self.space, "continulet already finished") self.check_sthread() - #workaround_disable_jit(self.sthread) - # + global_state.origin = self if to is None: # simple switch: going to self.h @@ -266,16 +264,6 @@ sthread = ec.stacklet_thread = SThread(space, ec) return sthread -def workaround_disable_jit(sthread): - # A bad workaround to kill the JIT anywhere in this thread. - # This forces all the frames. It's a bad workaround because - # it takes O(depth) time, and it will cause some "abort: - # vable escape" in the JIT. The goal is to prevent any frame - # from being still virtuals, because the JIT generates code - # to un-virtualizable them "on demand" by loading values based - # on FORCE_TOKEN, which is an address in the stack. - sthread.ec.force_all_frames() - # ____________________________________________________________ def permute(space, args_w): From noreply at buildbot.pypy.org Sun Mar 17 18:58:58 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Mar 2013 18:58:58 +0100 (CET) Subject: [pypy-commit] pypy default: Small cleanup Message-ID: <20130317175859.00EDA1C138A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62386:701326293cc2 Date: 2013-03-17 10:58 -0700 http://bitbucket.org/pypy/pypy/changeset/701326293cc2/ Log: Small cleanup diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -1,11 +1,13 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter import function, pycode, pyframe -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.astcompiler import consts from rpython.rlib import jit from rpython.tool.uid import uid +from pypy.interpreter import function, pycode, pyframe +from pypy.interpreter.astcompiler import consts +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule + + class Cell(Wrappable): "A simple container for a wrapped value." @@ -20,7 +22,7 @@ def get(self): if self.w_value is None: - raise ValueError, "get() from an empty cell" + raise ValueError("get() from an empty cell") return self.w_value def set(self, w_value): @@ -28,9 +30,9 @@ def delete(self): if self.w_value is None: - raise ValueError, "delete() on an empty cell" + raise ValueError("delete() on an empty cell") self.w_value = None - + def descr__cmp__(self, space, w_other): other = space.interpclass_w(w_other) if not isinstance(other, Cell): @@ -46,10 +48,10 @@ return space.cmp(self.w_value, other.w_value) def descr__reduce__(self, space): - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('cell_new') - if self.w_value is None: #when would this happen? + if self.w_value is None: # when would this happen? return space.newtuple([new_inst, space.newtuple([])]) tup = [self.w_value] return space.newtuple([new_inst, space.newtuple([]), @@ -57,7 +59,7 @@ def descr__setstate__(self, space, w_state): self.w_value = space.getitem(w_state, space.wrap(0)) - + def __repr__(self): """ representation for debugging purposes """ if self.w_value is None: @@ -74,10 +76,9 @@ raise OperationError(space.w_ValueError, space.wrap("Cell is empty")) - super_initialize_frame_scopes = pyframe.PyFrame.initialize_frame_scopes -super_fast2locals = pyframe.PyFrame.fast2locals -super_locals2fast = pyframe.PyFrame.locals2fast +super_fast2locals = pyframe.PyFrame.fast2locals +super_locals2fast = pyframe.PyFrame.locals2fast class __extend__(pyframe.PyFrame): @@ -132,7 +133,7 @@ def fast2locals(self): super_fast2locals(self) # cellvars are values exported to inner scopes - # freevars are values coming from outer scopes + # freevars are values coming from outer scopes freevarnames = list(self.pycode.co_cellvars) if self.pycode.co_flags & consts.CO_OPTIMIZED: freevarnames.extend(self.pycode.co_freevars) @@ -197,11 +198,11 @@ except ValueError: varname = self.getfreevarname(varindex) if self.iscellvar(varindex): - message = "local variable '%s' referenced before assignment"%varname + message = "local variable '%s' referenced before assignment" % varname w_exc_type = self.space.w_UnboundLocalError else: message = ("free variable '%s' referenced before assignment" - " in enclosing scope"%varname) + " in enclosing scope" % varname) w_exc_type = self.space.w_NameError raise OperationError(w_exc_type, self.space.wrap(message)) else: From noreply at buildbot.pypy.org Sun Mar 17 19:23:40 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Mar 2013 19:23:40 +0100 (CET) Subject: [pypy-commit] pypy default: some cleanup Message-ID: <20130317182340.031C01C0635@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62387:ca2784f3146d Date: 2013-03-17 11:23 -0700 http://bitbucket.org/pypy/pypy/changeset/ca2784f3146d/ Log: some cleanup diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -1,7 +1,14 @@ -import os, sys +import cStringIO +import os +import sys +import traceback +from errno import EINTR + from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated -from errno import EINTR + +from pypy.interpreter import debug + AUTO_DEBUG = os.getenv('PYPY_DEBUG') RECORD_INTERPLEVEL_TRACEBACK = True @@ -61,7 +68,7 @@ if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -95,7 +102,8 @@ def print_application_traceback(self, space, file=None): "NOT_RPYTHON: Dump a standard application-level traceback." - if file is None: file = sys.stderr + if file is None: + file = sys.stderr self.print_app_tb_only(file) print >> file, self.errorstr(space) @@ -130,8 +138,8 @@ def print_detailed_traceback(self, space=None, file=None): """NOT_RPYTHON: Dump a nice detailed interpreter- and application-level traceback, useful to debug the interpreter.""" - import traceback, cStringIO - if file is None: file = sys.stderr + if file is None: + file = sys.stderr f = cStringIO.StringIO() for i in range(len(self.debug_excs)-1, -1, -1): print >> f, "Traceback (interpreter-level):" @@ -144,7 +152,6 @@ self.print_app_tb_only(file) print >> file, '(application-level)', self.errorstr(space) if AUTO_DEBUG: - import debug debug.fire(self) @jit.unroll_safe @@ -174,7 +181,7 @@ # ("string", ...) ("string", ...) deprecated # (inst, None) (inst.__class__, inst) no # - w_type = self.w_type + w_type = self.w_type w_value = self.get_w_value(space) while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -211,7 +218,7 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type + self.w_type = w_type self._w_value = w_value def _exception_getclass(self, space, w_inst): @@ -327,7 +334,7 @@ from rpython.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(enumerate(attrs)) - # + class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): self.setup(w_type) @@ -336,6 +343,7 @@ for i, attr in entries: setattr(self, attr, args[i]) assert w_type is not None + def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: From noreply at buildbot.pypy.org Sun Mar 17 19:23:58 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 17 Mar 2013 19:23:58 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: fix translation Message-ID: <20130317182358.D7CD11C0635@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: str-dtype-improvement Changeset: r62388:214de91f0dae Date: 2013-03-17 00:31 -0700 http://bitbucket.org/pypy/pypy/changeset/214de91f0dae/ Log: fix translation 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 @@ -278,7 +278,7 @@ dtype.coerce(space, w_value)) def convert_to(self, dtype): - assert dtype.fields == self.dtype.fields + # TODO actually perform the conversion, this requires a space arg return self class W_CharacterBox(W_FlexibleBox): 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind and dt1.fields == dt2.fields: + if dt1.kind == dt2.kind and dt2.is_flexible_type(): return dt2 # Everything promotes to float, and bool promotes to everything. @@ -438,18 +438,16 @@ # For those operations that get here (concatenate, stack), # flexible types take precedence over numeric type if dt2.is_record_type(): - if dt1.fields == dt2.fields: - #record types require an exact match - return dt2 - return None + #TODO record types require an exact match + return dt2 if dt1.is_str_or_unicode(): if dt2.num == 18: size = max(dt2.itemtype.get_element_size(), dt1.itemtype.get_element_size()) - return interp_dtype.new_string_type(size) + return interp_dtype.new_string_dtype(space, size) size = max(dt2.itemtype.get_element_size(), dt1.itemtype.get_element_size()) - return interp_dtype.new_unitype_type(size) + return interp_dtype.new_unicode_dtype(space, size) return dt2 else: # increase to the next signed type From noreply at buildbot.pypy.org Sun Mar 17 19:24:00 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 17 Mar 2013 19:24:00 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: whoops Message-ID: <20130317182400.26A951C0635@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62389:5c6294722df9 Date: 2013-03-17 17:56 +0200 http://bitbucket.org/pypy/pypy/changeset/5c6294722df9/ Log: whoops 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind and dt2.is_flexible_type(): + if dt1.kind == dt2.kind and not dt2.is_flexible_type(): return dt2 # Everything promotes to float, and bool promotes to everything. From noreply at buildbot.pypy.org Sun Mar 17 19:24:01 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 17 Mar 2013 19:24:01 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: intrusively fix record field matching Message-ID: <20130317182401.56F191C0635@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62390:f793000f4f09 Date: 2013-03-17 18:52 +0200 http://bitbucket.org/pypy/pypy/changeset/f793000f4f09/ Log: intrusively fix record field matching diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,6 +116,17 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + a_dt = arr.get_dtype() + if dtype.is_record_type() and a_dt.is_record_type(): + #Record types must match + for f in dtype.fields: + if f not in a_dt.fields or \ + dtype.fields[f] != a_dt.fields[f]: + raise OperationError(space.w_TypeError, + space.wrap("record type mismatch")) + elif dtype.is_record_type() or a_dt.is_record_type(): + raise OperationError(space.w_TypeError, + space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: 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 @@ -278,7 +278,7 @@ dtype.coerce(space, w_value)) def convert_to(self, dtype): - # TODO actually perform the conversion, this requires a space arg + # if we reach here, the record fields are guarenteed to match. return self class W_CharacterBox(W_FlexibleBox): 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 @@ -438,7 +438,6 @@ # For those operations that get here (concatenate, stack), # flexible types take precedence over numeric type if dt2.is_record_type(): - #TODO record types require an exact match return dt2 if dt1.is_str_or_unicode(): if dt2.num == 18: From noreply at buildbot.pypy.org Sun Mar 17 21:45:55 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 17 Mar 2013 21:45:55 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: implement convert_from for str arrays only Message-ID: <20130317204555.D104D1C138A@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62391:aaadf6eca9d9 Date: 2013-03-17 13:45 -0700 http://bitbucket.org/pypy/pypy/changeset/aaadf6eca9d9/ Log: implement convert_from for str arrays only diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -47,13 +47,10 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return - if self.dtype.is_str_or_unicode(): - raise OperationError(space.w_NotImplementedError, space.wrap( - "concatenate(%s) not implemented yet" % self.dtype)) shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy() - loop.setslice(shape, self, impl) + impl = impl.copy(space) + loop.setslice(space, shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -244,12 +241,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self): + def copy(self, space): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.get_shape(), impl, self) + return loop.setslice(space, self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -284,7 +281,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "astype(%s) not implemented yet" % self.dtype)) else: - loop.setslice(new_arr.get_shape(), new_arr.implementation, self) + loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -47,7 +47,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self): + def copy(self, space): scalar = Scalar(self.dtype) scalar.value = self.value return scalar 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 @@ -71,6 +71,8 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) + def convert_from(self, space, box): + return self.itemtype.convert_from(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -252,7 +252,7 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy()) + return W_NDimArray(self.implementation.copy(space)) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) 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 @@ -65,26 +65,32 @@ obj_iter.next() return out -setslice_driver = jit.JitDriver(name='numpy_setslice', +setslice_driver1 = jit.JitDriver(name='numpy_setslice1', greens = ['shapelen', 'dtype'], - reds = ['target', 'source', 'target_iter', - 'source_iter']) + reds = 'auto') +setslice_driver2 = jit.JitDriver(name='numpy_setslice2', + greens = ['shapelen', 'dtype'], + reds = 'auto') -def setslice(shape, target, source): +def setslice(space, shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) source_iter = source.create_iter(shape) dtype = target.dtype shapelen = len(shape) - while not target_iter.done(): - setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, - target=target, source=source, - target_iter=target_iter, - source_iter=source_iter) - target_iter.setitem(source_iter.getitem().convert_to(dtype)) - target_iter.next() - source_iter.next() + if dtype.is_str_or_unicode(): + while not target_iter.done(): + setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(dtype.convert_from(space, source_iter.getitem())) + target_iter.next() + source_iter.next() + else: + while not target_iter.done(): + setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(source_iter.getitem().convert_to(dtype)) + target_iter.next() + source_iter.next() return target reduce_driver = jit.JitDriver(name='numpy_reduce', 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 @@ -1480,13 +1480,10 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() - try: - a = concatenate((array([1]), array(['abc']))) - assert a.dtype == 'S3' - a = concatenate((array([]), array(['abc']))) - assert a[0] == 'abc' - except NotImplementedError: - skip('cannot concatenate numeric with string') + a = concatenate((array([1]), array(['abc']))) + assert str(a.dtype) == '|S3' + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' def test_record_concatenate(self): # only an exact match can succeed 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 @@ -1627,6 +1627,7 @@ def get_size(self): return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1642,7 +1643,7 @@ @jit.unroll_safe def store(self, arr, i, offset, box): assert isinstance(box, interp_boxes.W_StringBox) - for k in range(min(self.size, box.arr.size-offset)): + for k in range(min(self.size - i, box.arr.size-offset)): arr.storage[k + i] = box.arr.storage[k + offset] def read(self, arr, i, offset, dtype=None): @@ -1675,6 +1676,20 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) + def convert_from(self, space, mydtype, box): + if box.get_dtype(space).is_str_or_unicode(): + arg = box.get_dtype(space).itemtype.to_str(box) + else: + w_arg = box.descr_str(space) + arg = space.str_w(space.str(w_arg)) + arr = VoidBoxStorage(self.size, mydtype) + i = 0 + for i in range(min(len(arg), self.size)): + arr.storage[i] = arg[i] + for j in range(i + 1, self.size): + arr.storage[j] = '\x00' + return interp_boxes.W_StringBox(arr, 0, arr.dtype) + class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Sun Mar 17 21:55:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Mar 2013 21:55:04 +0100 (CET) Subject: [pypy-commit] pypy fast-newarray: fix for stuff being too far apart Message-ID: <20130317205504.679811C138A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: fast-newarray Changeset: r62392:a117a5262e7c Date: 2013-03-17 12:21 -0700 http://bitbucket.org/pypy/pypy/changeset/a117a5262e7c/ Log: fix for stuff being too far apart 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 @@ -29,11 +29,11 @@ return r[r.find('1'):] class TestRegallocGcIntegration(BaseTestRegalloc): - + cpu = CPU(None, None) cpu.gc_ll_descr = GcLLDescr_boehm(None, None, None) cpu.setup_once() - + S = lltype.GcForwardReference() S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), ('int', lltype.Signed))) @@ -229,7 +229,7 @@ p1 = call_malloc_nursery_varsize_small(i1) p2 = call_malloc_nursery_varsize_small(i2) guard_true(i0) [p0, p1, p2] - ''' + ''' self.interpret(ops, [16, 32, 16]) # check the returned pointers gc_ll_descr = self.cpu.gc_ll_descr @@ -292,7 +292,7 @@ s = bin(x[0]).count('1') + bin(x[1]).count('1') assert s == 16 # all but two registers + some stuff on stack - + self.cpu = self.getcpu(check) S1 = lltype.GcStruct('S1') S2 = lltype.GcStruct('S2', ('s0', lltype.Ptr(S1)), @@ -358,7 +358,7 @@ class MockShadowStackRootMap(object): is_shadow_stack = True - + def __init__(self): TP = rffi.CArray(lltype.Signed) self.stack = lltype.malloc(TP, 10, flavor='raw') @@ -367,7 +367,7 @@ self.stack_addr[0] = rffi.cast(lltype.Signed, self.stack) def __del__(self): - lltype.free(self.stack_addr, flavor='raw') + lltype.free(self.stack_addr, flavor='raw') lltype.free(self.stack, flavor='raw') def register_asm_addr(self, start, mark): @@ -379,7 +379,7 @@ class WriteBarrierDescr(AbstractDescr): jit_wb_cards_set = 0 jit_wb_if_flag_singlebyte = 1 - + def __init__(self, gc_ll_descr): def write_barrier(frame): gc_ll_descr.write_barrier_on_frame_called = frame @@ -505,7 +505,7 @@ for nursery in self.all_nurseries: lltype.free(nursery, flavor='raw', track_allocation=False) lltype.free(self.nursery_ptrs, flavor='raw') - + def unpack_gcmap(frame): res = [] val = 0 @@ -538,10 +538,10 @@ def test_shadowstack_call(self): cpu = self.cpu cpu.gc_ll_descr.init_nursery(100) - cpu.setup_once() + cpu.setup_once() S = self.S frames = [] - + def check(i): assert cpu.gc_ll_descr.gcrootmap.stack[0] == i frame = rffi.cast(JITFRAMEPTR, i) @@ -664,6 +664,9 @@ assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame + def test_malloc_nursery_varsize(self): + xxx + def test_call_release_gil(self): # note that we can't test floats here because when untranslated # people actually wreck xmm registers @@ -683,11 +686,11 @@ assert bin(frame.jf_gcmap[0]).count('1') == 7 assert x == 1 return 2 - + FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, - EffectInfo.MOST_GENERAL) + EffectInfo.MOST_GENERAL) loop = self.parse(""" [i0, p1, p2, p3, p4, p5, p6, p7] p0 = force_token() @@ -709,7 +712,7 @@ def test_call_may_force_gcmap(self): cpu = self.cpu - + def f(frame, arg, x): assert not arg assert frame.jf_gcmap[0] & 31 == 0 @@ -753,7 +756,7 @@ def test_call_gcmap_no_guard(self): cpu = self.cpu - + def f(frame, arg, x): assert not arg assert frame.jf_gcmap[0] & 31 == 0 diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2234,7 +2234,7 @@ def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mc.CMP_mi((eax.value, ofs), value) + self.mc.CMP(mem(eax, ofs), imm(value)) # patched later self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' return self.mc.get_relative_pos() From noreply at buildbot.pypy.org Sun Mar 17 21:55:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Mar 2013 21:55:05 +0100 (CET) Subject: [pypy-commit] pypy default: fix for default too Message-ID: <20130317205505.A75C61C138A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62393:5652b0748b56 Date: 2013-03-17 12:22 -0700 http://bitbucket.org/pypy/pypy/changeset/5652b0748b56/ Log: fix for default too diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2234,7 +2234,7 @@ def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mc.CMP_mi((eax.value, ofs), value) + self.mc.CMP(mem(eax, ofs), imm(value)) # patched later self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' return self.mc.get_relative_pos() From noreply at buildbot.pypy.org Sun Mar 17 21:55:07 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Mar 2013 21:55:07 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130317205507.604261C138A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62394:def044ae69a4 Date: 2013-03-17 13:54 -0700 http://bitbucket.org/pypy/pypy/changeset/def044ae69a4/ Log: merge diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -364,9 +364,10 @@ self._in_transaction = False self.isolation_level = isolation_level - self._cursors = [] + self.__cursors = [] + self.__cursors_counter = 0 self.__statements = [] - self.__statement_counter = 0 + self.__statements_counter = 0 self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} @@ -394,10 +395,7 @@ def close(self): self._check_thread() - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._finalize() + self.__do_all_statements(Statement._finalize, True) if self._db: ret = _lib.sqlite3_close(self._db) @@ -469,13 +467,33 @@ exc.error_code = error_code return exc + def _remember_cursor(self, cursor): + self.__cursors.append(weakref.ref(cursor)) + self.__cursors_counter += 1 + if self.__cursors_counter < 200: + return + self.__cursors_counter = 0 + self.__cursors = [r for r in self.__cursors if r() is not None] + def _remember_statement(self, statement): self.__statements.append(weakref.ref(statement)) - self.__statement_counter += 1 + self.__statements_counter += 1 + if self.__statements_counter < 200: + return + self.__statements_counter = 0 + self.__statements = [r for r in self.__statements if r() is not None] - if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements - if ref() is not None] + def __do_all_statements(self, action, reset_cursors): + for weakref in self.__statements: + statement = weakref() + if statement is not None: + action(statement) + + if reset_cursors: + for weakref in self.__cursors: + cursor = weakref() + if cursor is not None: + cursor._reset = True @_check_thread_wrap @_check_closed_wrap @@ -528,10 +546,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() + self.__do_all_statements(Statement._reset, False) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, @@ -552,15 +567,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() - - for cursor_ref in self._cursors: - cursor = cursor_ref() - if cursor: - cursor._reset = True + self.__do_all_statements(Statement._reset, True) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, @@ -787,14 +794,9 @@ __statement = None def __init__(self, con): - self.__initialized = True - self.__connection = con - if not isinstance(con, Connection): raise TypeError - con._check_thread() - con._check_closed() - con._cursors.append(weakref.ref(self)) + self.__connection = con self.arraysize = 1 self.row_factory = None @@ -804,11 +806,12 @@ self.__description = None self.__rowcount = -1 + con._check_thread() + con._remember_cursor(self) + + self.__initialized = True + def __del__(self): - try: - self.__connection._cursors.remove(weakref.ref(self)) - except (AttributeError, ValueError): - pass if self.__statement: self.__statement._reset() @@ -883,7 +886,6 @@ self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False - return self @__check_cursor_wrap @@ -921,9 +923,10 @@ if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement) if rc == _lib.SQLITE_OK: - return self + break else: raise self.__connection._get_exception(rc) + rc = _lib.sqlite3_finalize(statement) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -1000,6 +1003,7 @@ def __init__(self, connection, sql): self.__con = connection + self.__con._remember_statement(self) if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") @@ -1027,10 +1031,9 @@ ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(sql)) self._kind = Statement._DQL - if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) - self.__con._remember_statement(self) + sql = sql.value.decode('utf-8') if _check_remaining_sql(sql): raise Warning("You can only execute one statement at a time.") 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 @@ -86,3 +86,8 @@ .. branch: vendor-rename Remove minor verison number from lib-python dirs to simplify stdlib upgrades. + +.. branch: jitframe-on-heap +Moves optimized JIT frames from stack to heap. As a side effect it enables +stackless to work well with the JIT on PyPy. Also removes a bunch of code from +the GC which fixes cannot find gc roots. diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -1,7 +1,14 @@ -import os, sys +import cStringIO +import os +import sys +import traceback +from errno import EINTR + from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated -from errno import EINTR + +from pypy.interpreter import debug + AUTO_DEBUG = os.getenv('PYPY_DEBUG') RECORD_INTERPLEVEL_TRACEBACK = True @@ -61,7 +68,7 @@ if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -95,7 +102,8 @@ def print_application_traceback(self, space, file=None): "NOT_RPYTHON: Dump a standard application-level traceback." - if file is None: file = sys.stderr + if file is None: + file = sys.stderr self.print_app_tb_only(file) print >> file, self.errorstr(space) @@ -130,8 +138,8 @@ def print_detailed_traceback(self, space=None, file=None): """NOT_RPYTHON: Dump a nice detailed interpreter- and application-level traceback, useful to debug the interpreter.""" - import traceback, cStringIO - if file is None: file = sys.stderr + if file is None: + file = sys.stderr f = cStringIO.StringIO() for i in range(len(self.debug_excs)-1, -1, -1): print >> f, "Traceback (interpreter-level):" @@ -144,7 +152,6 @@ self.print_app_tb_only(file) print >> file, '(application-level)', self.errorstr(space) if AUTO_DEBUG: - import debug debug.fire(self) @jit.unroll_safe @@ -174,7 +181,7 @@ # ("string", ...) ("string", ...) deprecated # (inst, None) (inst.__class__, inst) no # - w_type = self.w_type + w_type = self.w_type w_value = self.get_w_value(space) while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -211,7 +218,7 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type + self.w_type = w_type self._w_value = w_value def _exception_getclass(self, space, w_inst): @@ -327,7 +334,7 @@ from rpython.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(enumerate(attrs)) - # + class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): self.setup(w_type) @@ -336,6 +343,7 @@ for i, attr in entries: setattr(self, attr, args[i]) assert w_type is not None + def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -1,11 +1,13 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter import function, pycode, pyframe -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.astcompiler import consts from rpython.rlib import jit from rpython.tool.uid import uid +from pypy.interpreter import function, pycode, pyframe +from pypy.interpreter.astcompiler import consts +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule + + class Cell(Wrappable): "A simple container for a wrapped value." @@ -20,7 +22,7 @@ def get(self): if self.w_value is None: - raise ValueError, "get() from an empty cell" + raise ValueError("get() from an empty cell") return self.w_value def set(self, w_value): @@ -28,9 +30,9 @@ def delete(self): if self.w_value is None: - raise ValueError, "delete() on an empty cell" + raise ValueError("delete() on an empty cell") self.w_value = None - + def descr__cmp__(self, space, w_other): other = space.interpclass_w(w_other) if not isinstance(other, Cell): @@ -46,10 +48,10 @@ return space.cmp(self.w_value, other.w_value) def descr__reduce__(self, space): - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('cell_new') - if self.w_value is None: #when would this happen? + if self.w_value is None: # when would this happen? return space.newtuple([new_inst, space.newtuple([])]) tup = [self.w_value] return space.newtuple([new_inst, space.newtuple([]), @@ -57,7 +59,7 @@ def descr__setstate__(self, space, w_state): self.w_value = space.getitem(w_state, space.wrap(0)) - + def __repr__(self): """ representation for debugging purposes """ if self.w_value is None: @@ -74,10 +76,9 @@ raise OperationError(space.w_ValueError, space.wrap("Cell is empty")) - super_initialize_frame_scopes = pyframe.PyFrame.initialize_frame_scopes -super_fast2locals = pyframe.PyFrame.fast2locals -super_locals2fast = pyframe.PyFrame.locals2fast +super_fast2locals = pyframe.PyFrame.fast2locals +super_locals2fast = pyframe.PyFrame.locals2fast class __extend__(pyframe.PyFrame): @@ -132,7 +133,7 @@ def fast2locals(self): super_fast2locals(self) # cellvars are values exported to inner scopes - # freevars are values coming from outer scopes + # freevars are values coming from outer scopes freevarnames = list(self.pycode.co_cellvars) if self.pycode.co_flags & consts.CO_OPTIMIZED: freevarnames.extend(self.pycode.co_freevars) @@ -197,11 +198,11 @@ except ValueError: varname = self.getfreevarname(varindex) if self.iscellvar(varindex): - message = "local variable '%s' referenced before assignment"%varname + message = "local variable '%s' referenced before assignment" % varname w_exc_type = self.space.w_UnboundLocalError else: message = ("free variable '%s' referenced before assignment" - " in enclosing scope"%varname) + " in enclosing scope" % varname) w_exc_type = self.space.w_NameError raise OperationError(w_exc_type, self.space.wrap(message)) else: diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -29,7 +29,6 @@ if self.sthread is not None: raise geterror(self.space, "continulet already __init__ialized") sthread = build_sthread(self.space) - #workaround_disable_jit(sthread) # # hackish: build the frame "by hand", passing it the correct arguments space = self.space @@ -72,8 +71,7 @@ global_state.clear() raise geterror(self.space, "continulet already finished") self.check_sthread() - #workaround_disable_jit(self.sthread) - # + global_state.origin = self if to is None: # simple switch: going to self.h @@ -266,16 +264,6 @@ sthread = ec.stacklet_thread = SThread(space, ec) return sthread -def workaround_disable_jit(sthread): - # A bad workaround to kill the JIT anywhere in this thread. - # This forces all the frames. It's a bad workaround because - # it takes O(depth) time, and it will cause some "abort: - # vable escape" in the JIT. The goal is to prevent any frame - # from being still virtuals, because the JIT generates code - # to un-virtualizable them "on demand" by loading values based - # on FORCE_TOKEN, which is an address in the stack. - sthread.ec.force_all_frames() - # ____________________________________________________________ def permute(space, args_w): diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -22,6 +22,7 @@ 'lastblock', 'is_being_profiled', 'w_globals', + 'w_f_trace', ] JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE'] @@ -37,9 +38,6 @@ def set_jitcell_at(newcell, next_instr, is_being_profiled, bytecode): bytecode.jit_cells[next_instr, is_being_profiled] = newcell -def confirm_enter_jit(next_instr, is_being_profiled, bytecode, frame, ec): - return (frame.w_f_trace is None and - ec.w_tracefunc is None) def can_never_inline(next_instr, is_being_profiled, bytecode): return False @@ -55,7 +53,6 @@ pypyjitdriver = PyPyJitDriver(get_printable_location = get_printable_location, get_jitcell_at = get_jitcell_at, set_jitcell_at = set_jitcell_at, - confirm_enter_jit = confirm_enter_jit, can_never_inline = can_never_inline, should_unroll_one_iteration = should_unroll_one_iteration, 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 @@ -159,6 +159,7 @@ con.commit() except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") + con.close() def test_statement_arg_checking(): con = _sqlite3.connect(':memory:') @@ -194,3 +195,4 @@ with pytest.raises(ValueError) as e: con.execute('insert into foo(x) values (?)', 2) assert str(e.value) == 'parameters are of unsupported type' + con.close() diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1,43 +1,30 @@ from __future__ import with_statement + import os + +from rpython.jit.backend.arm import conditions as c, registers as r +from rpython.jit.backend.arm.arch import (WORD, DOUBLE_WORD, FUNC_ALIGN, + JITFRAME_FIXED_SIZE) +from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder +from rpython.jit.backend.arm.locations import imm, StackLocation +from rpython.jit.backend.arm.opassembler import ResOpAssembler +from rpython.jit.backend.arm.regalloc import (Regalloc, + CoreRegisterManager, check_imm_arg, VFPRegisterManager, + operations as regalloc_operations, + operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.arm.helper.assembler import saved_registers -from rpython.jit.backend.arm import conditions as c -from rpython.jit.backend.arm import registers as r -from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, FUNC_ALIGN, \ - N_REGISTERS_SAVED_BY_MALLOC, \ - JITFRAME_FIXED_SIZE -from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder -from rpython.jit.backend.arm.locations import get_fp_offset, imm, StackLocation -from rpython.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, - CoreRegisterManager, check_imm_arg, - VFPRegisterManager, - operations as regalloc_operations, - operations_with_guard as regalloc_operations_with_guard) +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken -from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT -from rpython.jit.metainterp.history import BoxInt, ConstInt -from rpython.jit.metainterp.resoperation import rop, ResOperation -from rpython.rlib import rgc -from rpython.rlib.objectmodel import we_are_translated, specialize +from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT +from rpython.jit.metainterp.resoperation import rop +from rpython.rlib.debug import debug_print, debug_start, debug_stop +from rpython.rlib.jit import AsmInfo +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref -from rpython.rtyper.lltypesystem import lltype, rffi, llmemory -from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.jit.backend.arm.opassembler import ResOpAssembler -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints, fatalerror) -from rpython.rlib.jit import AsmInfo -from rpython.rlib.objectmodel import compute_unique_id -from rpython.rlib.rarithmetic import intmask, r_uint - - -DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), - ('type', lltype.Char), # 'b'ridge, 'l'abel or - # 'e'ntry point - ('number', lltype.Signed)) +from rpython.rtyper.lltypesystem import lltype, rffi class AssemblerARM(ResOpAssembler): @@ -121,18 +108,6 @@ self.loop_run_counters.append(struct) return struct - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) - @specialize.argtype(1) def _inject_debugging_code(self, looptoken, operations, tp, number): if self._debug: @@ -278,7 +253,7 @@ mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) mc.LDR_ri(r.r0.value, r.r0.value) mc.TST_rr(r.r0.value, r.r0.value) - # restore registers and return + # restore registers and return # We check for c.EQ here, meaning all bits zero in this case mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value], cond=c.EQ) # @@ -602,7 +577,7 @@ self.mc.LDR_ri(r.lr.value, r.lr.value) # ldr lr, *lengh # calculate ofs self.mc.SUB_rr(r.ip.value, r.ip.value, r.sp.value) # SUB ip, current - # if ofs + # if ofs self.mc.CMP_rr(r.ip.value, r.lr.value) # CMP ip, lr self.mc.BL(self.stack_check_slowpath, c=c.HI) # call if ip > lr # @@ -758,7 +733,6 @@ self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), expected_size=expected_size) - def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. @@ -952,7 +926,7 @@ effectinfo = op.getdescr().get_extra_info() oopspecindex = effectinfo.oopspecindex asm_llong_operations[oopspecindex](self, op, arglocs, regalloc, fcond) - return fcond + return fcond def regalloc_emit_math(self, op, arglocs, fcond, regalloc): effectinfo = op.getdescr().get_extra_info() @@ -1075,7 +1049,6 @@ assert 0, 'unsupported case' def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL): - pushed = False if loc.is_reg(): assert prev_loc.type != FLOAT, 'trying to load from an \ incompatible location into a core register' @@ -1299,7 +1272,6 @@ self.store_reg(mc, r.ip, r.fp, ofs) - def not_implemented(msg): os.write(2, '[ARM/asm] %s\n' % msg) raise NotImplementedError(msg) diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,14 +1,23 @@ - +from rpython.jit.backend.llsupport import jitframe +from rpython.jit.backend.llsupport.memcpy import memcpy_fn +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.metainterp.history import (INT, REF, FLOAT, JitCellToken, + ConstInt, BoxInt) +from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib import rgc +from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints from rpython.rlib.rarithmetic import r_uint -from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.backend.llsupport import jitframe -from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.jit.backend.llsupport.memcpy import memcpy_fn -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints) + + +DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', + # 'b'ridge, 'l'abel or # 'e'ntry point + ('i', lltype.Signed), + ('type', lltype.Char), + ('number', lltype.Signed) +) + class GuardToken(object): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, @@ -203,3 +212,15 @@ # XXX here should be emitted guard_not_forced, but due # to incompatibilities in how it's done, we leave it for the # caller to deal with + + def _append_debugging_code(self, operations, tp, number, token): + counter = self._register_counter(tp, number, token) + c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) + box = BoxInt() + box2 = BoxInt() + ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], + box, descr=self.debug_counter_descr), + ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), + ResOperation(rop.SETFIELD_RAW, [c_adr, box2], + None, descr=self.debug_counter_descr)] + operations.extend(ops) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1,10 +1,11 @@ +import sys +import os -import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe -from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler +from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler, DEBUG_COUNTER from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap -from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt +from rpython.jit.metainterp.history import Const, Box from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop @@ -23,7 +24,7 @@ imm0, imm1, FloatImmedLoc, RawEbpLoc, RawEspLoc) from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.backend.x86 import rx86, codebuf -from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.x86 import support from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rlib import rgc @@ -34,17 +35,15 @@ from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import compute_unique_id + # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, # better safe than sorry CALL_ALIGN = 16 // WORD + def align_stack_words(words): return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) -DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), - ('type', lltype.Char), # 'b'ridge, 'l'abel or - # 'e'ntry point - ('number', lltype.Signed)) class Assembler386(BaseAssembler): _regalloc = None @@ -240,7 +239,7 @@ propagate_exception_descr = rffi.cast(lltype.Signed, cast_instance_to_gcref(self.cpu.propagate_exception_descr)) ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mc.MOV_bi(ofs, propagate_exception_descr) + self.mc.MOV(RawEbpLoc(ofs), imm(propagate_exception_descr)) self.mc.MOV_rr(eax.value, ebp.value) # self._call_footer() @@ -747,18 +746,6 @@ targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) - @specialize.argtype(1) def _inject_debugging_code(self, looptoken, operations, tp, number): if self._debug: diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -1,6 +1,5 @@ - from rpython.rtyper.tool import rffi_platform -from rpython.rtyper.lltypesystem import rffi, lltype, llmemory +from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rposix from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.nonconst import NonConstant @@ -12,10 +11,7 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" -_LINUX = "linux" in sys.platform _64BIT = "64bit" in platform.architecture()[0] -_ARM = platform.machine().startswith('arm') -_PPC = platform.machine().startswith('ppc') _CYGWIN = "cygwin" == sys.platform class RValueError(Exception): @@ -30,7 +26,7 @@ if _POSIX: includes += ['unistd.h', 'sys/mman.h'] elif _MS_WINDOWS: - includes += ['winsock2.h','windows.h'] + includes += ['winsock2.h', 'windows.h'] class CConfig: _compilation_info_ = ExternalCompilationInfo( @@ -78,7 +74,7 @@ from rpython.rlib.rwin32 import NULL_HANDLE, INVALID_HANDLE_VALUE from rpython.rlib.rwin32 import DWORD, WORD, DWORD_PTR, LPDWORD from rpython.rlib.rwin32 import BOOL, LPVOID, LPCSTR, SIZE_T - from rpython.rlib.rwin32 import INT, LONG, PLONG + from rpython.rlib.rwin32 import LONG, PLONG # export the constants inside and outside. see __init__.py cConfig = rffi_platform.configure(CConfig) @@ -128,7 +124,7 @@ if _POSIX: has_mremap = cConfig['has_mremap'] c_mmap, c_mmap_safe = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, - rffi.INT, off_t], PTR, macro=True) + rffi.INT, off_t], PTR, macro=True) # 'mmap' on linux32 is a macro that calls 'mmap64' _, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT) c_msync, _ = external('msync', [PTR, size_t, rffi.INT], rffi.INT) @@ -138,7 +134,7 @@ # this one is always safe _pagesize = rffi_platform.getintegerfunctionresult('getpagesize', - includes=includes) + includes=includes) _get_allocation_granularity = _get_page_size = lambda: _pagesize elif _MS_WINDOWS: @@ -150,13 +146,13 @@ 'SYSINFO_STRUCT', ("wProcessorArchitecture", WORD), ("wReserved", WORD), - ) + ) SYSINFO_UNION = rffi.CStruct( 'union SYSINFO_UNION', ("dwOemId", DWORD), ("_struct_", SYSINFO_STRUCT), - ) + ) # sorry, I can't find a way to insert the above # because the union field has no name SYSTEM_INFO = rffi_platform.Struct( @@ -209,7 +205,6 @@ VirtualFree = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) - def _get_page_size(): try: si = rffi.make(SYSTEM_INFO) @@ -493,14 +488,6 @@ # this is not checked return res elif _POSIX: -## XXX why is this code here? There is no equivalent in CPython -## if _LINUX: -## # alignment of the address -## value = cast(self.data, c_void_p).value -## aligned_value = value & ~(PAGESIZE - 1) -## # the size should be increased too. otherwise the final -## # part is not "msynced" -## new_size = size + value & (PAGESIZE - 1) res = c_msync(start, size, MS_SYNC) if res == -1: errno = rposix.get_errno() @@ -515,7 +502,7 @@ # check boundings if (src < 0 or dest < 0 or count < 0 or - src + count > self.size or dest + count > self.size): + src + count > self.size or dest + count > self.size): raise RValueError("source or destination out of range") datasrc = self.getptr(src) @@ -567,10 +554,9 @@ SetEndOfFile(self.file_handle) # create another mapping object and remap the file view res = CreateFileMapping(self.file_handle, NULL, PAGE_READWRITE, - newsize_high, newsize_low, self.tagname) + newsize_high, newsize_low, self.tagname) self.map_handle = res - dwErrCode = 0 if self.map_handle: data = MapViewOfFile(self.map_handle, FILE_MAP_WRITE, offset_high, offset_low, newsize) @@ -603,7 +589,7 @@ if len(value) != 1: raise RValueError("mmap assignment must be " - "single-character string") + "single-character string") if index < 0: index += self.size self.data[index] = value[0] @@ -614,12 +600,12 @@ if _POSIX: def mmap(fileno, length, flags=MAP_SHARED, - prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0): + prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0): fd = fileno # check access is not there when flags and prot are there - if access != _ACCESS_DEFAULT and ((flags != MAP_SHARED) or\ + if access != _ACCESS_DEFAULT and ((flags != MAP_SHARED) or (prot != (PROT_WRITE | PROT_READ))): raise RValueError("mmap can't specify both access and flags, prot.") @@ -771,8 +757,8 @@ pass # ignore non-seeking files and errors and trust map_size else: if not high and low <= sys.maxint: - size = low - else: + size = low + else: # not so sure if the signed/unsigned strictness is a good idea: high = rffi.cast(lltype.Unsigned, high) low = rffi.cast(lltype.Unsigned, low) @@ -866,7 +852,7 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT|MEM_RESERVE, + res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -44,7 +44,6 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" -_LINUX = "linux" in sys.platform _64BIT = "64bit" in host_platform.architecture()[0] @@ -70,7 +69,7 @@ return ctype() def do_allocation_in_far_regions(): - """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on Linux, + """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on POSIX, which helps test this module for address values that are signed or unsigned. @@ -87,18 +86,20 @@ if _64BIT: PIECESIZE = 0x80000000 else: - if _LINUX: + if _POSIX: PIECESIZE = 0x10000000 else: PIECESIZE = 0x08000000 PIECES = 10 flags = (0,) - if _LINUX: + if _POSIX: flags = (rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS|rmmap.MAP_NORESERVE, rmmap.PROT_READ|rmmap.PROT_WRITE) - if _MS_WINDOWS: + elif _MS_WINDOWS: flags = (rmmap.MEM_RESERVE,) # XXX seems not to work + else: + assert False # should always generate flags m = rmmap.mmap(-1, PIECES * PIECESIZE, *flags) m.close = lambda : None # leak instead of giving a spurious # error at CPython's shutdown From noreply at buildbot.pypy.org Sun Mar 17 22:03:27 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sun, 17 Mar 2013 22:03:27 +0100 (CET) Subject: [pypy-commit] pypy default: add an "any" type to rlib.types. It's kind of necessary for a lot of practical Message-ID: <20130317210327.6DD821C138A@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62395:3d242f84ac48 Date: 2013-03-17 22:00 +0100 http://bitbucket.org/pypy/pypy/changeset/3d242f84ac48/ Log: add an "any" type to rlib.types. It's kind of necessary for a lot of practical uses, e.g. when a PBC (like the object space) is involved. diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -306,8 +306,10 @@ result = schedule(graph, inputcells) signature = getattr(self.pyobj, '_signature_', None) if signature: - result = enforce_signature_return(self, signature[1], result) - self.bookkeeper.annotator.addpendingblock(graph, graph.returnblock, [result]) + sigresult = enforce_signature_return(self, signature[1], result) + if sigresult is not None: + self.bookkeeper.annotator.addpendingblock(graph, graph.returnblock, [sigresult]) + result = sigresult # Some specializations may break the invariant of returning # annotations that are always more general than the previous time. # We restore it here: diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -132,11 +132,13 @@ inputcells[:] = args_s def finish_type(paramtype, bookkeeper, func): - from rpython.rlib.types import SelfTypeMarker + from rpython.rlib.types import SelfTypeMarker, AnyTypeMarker if isinstance(paramtype, SomeObject): return paramtype elif isinstance(paramtype, SelfTypeMarker): raise Exception("%r argument declared as annotation.types.self(); class needs decorator rlib.signature.finishsigs()" % (func,)) + elif isinstance(paramtype, AnyTypeMarker): + return None else: return paramtype(bookkeeper) @@ -144,15 +146,20 @@ assert len(paramtypes) == len(actualtypes) params_s = [finish_type(paramtype, funcdesc.bookkeeper, funcdesc.pyobj) for paramtype in paramtypes] for i, (s_param, s_actual) in enumerate(zip(params_s, actualtypes)): + if s_param is None: # can be anything + continue if not s_param.contains(s_actual): raise Exception("%r argument %d:\n" "expected %s,\n" " got %s" % (funcdesc, i+1, s_param, s_actual)) - actualtypes[:] = params_s + for i, s_param in enumerate(params_s): + if s_param is None: + continue + actualtypes[i] = s_param def enforce_signature_return(funcdesc, sigtype, inferredtype): s_sigret = finish_type(sigtype, funcdesc.bookkeeper, funcdesc.pyobj) - if not s_sigret.contains(inferredtype): + if s_sigret is not None and not s_sigret.contains(inferredtype): raise Exception("%r return value:\n" "expected %s,\n" " got %s" % (funcdesc, s_sigret, inferredtype)) diff --git a/rpython/rlib/test/test_signature.py b/rpython/rlib/test/test_signature.py --- a/rpython/rlib/test/test_signature.py +++ b/rpython/rlib/test/test_signature.py @@ -248,3 +248,39 @@ exc = py.test.raises(Exception, annotate_at, C.incomplete_sig_meth).value assert 'incomplete_sig_meth' in repr(exc.args) assert 'finishsigs' in repr(exc.args) + +def test_any_as_argument(): + @signature(types.any(), types.int(), returns=types.float()) + def f(x, y): + return x + y + @signature(types.int(), returns=types.float()) + def g(x): + return f(x, x) + sig = getsig(g) + assert sig == [model.SomeInteger(), model.SomeFloat()] + + @signature(types.float(), returns=types.float()) + def g(x): + return f(x, 4) + sig = getsig(g) + assert sig == [model.SomeFloat(), model.SomeFloat()] + + @signature(types.str(), returns=types.int()) + def cannot_add_string(x): + return f(x, 2) + exc = py.test.raises(Exception, annotate_at, cannot_add_string).value + assert 'Blocked block' in repr(exc.args) + +def test_return_any(): + @signature(types.int(), returns=types.any()) + def f(x): + return x + sig = getsig(f) + assert sig == [model.SomeInteger(), model.SomeInteger()] + + @signature(types.str(), returns=types.any()) + def cannot_add_string(x): + return f(3) + x + exc = py.test.raises(Exception, annotate_at, cannot_add_string).value + assert 'Blocked block' in repr(exc.args) + assert 'cannot_add_string' in repr(exc.args) diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py --- a/rpython/rlib/types.py +++ b/rpython/rlib/types.py @@ -63,3 +63,10 @@ def self(): return SelfTypeMarker() + + +class AnyTypeMarker(object): + pass + +def any(): + return AnyTypeMarker() From noreply at buildbot.pypy.org Mon Mar 18 08:44:08 2013 From: noreply at buildbot.pypy.org (Karl Ramm) Date: Mon, 18 Mar 2013 08:44:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: python3 ssl constructor actually raises ValueError on illegal protocol Message-ID: <20130318074408.8C1741C04AB@cobra.cs.uni-duesseldorf.de> Author: Karl Ramm Branch: py3k Changeset: r62396:979b3dd2b1a5 Date: 2013-03-18 01:51 -0400 http://bitbucket.org/pypy/pypy/changeset/979b3dd2b1a5/ Log: python3 ssl constructor actually raises ValueError on illegal protocol diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -116,7 +116,8 @@ elif protocol == PY_SSL_VERSION_SSL23: method = libssl_SSLv23_method() else: - raise ssl_error(space, "invalid SSL protocol version") + raise OperationError( + space.w_ValueError, space.wrap("invalid protocol version")) self.__init__(method) if not self.ctx: raise ssl_error(space, "failed to allocate SSL context") From noreply at buildbot.pypy.org Mon Mar 18 08:46:23 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Mar 2013 08:46:23 +0100 (CET) Subject: [pypy-commit] pypy py3k: test 979b3dd2b1a5 for ValueErrors Message-ID: <20130318074623.833D01C03B2@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62397:383f13f771fe Date: 2013-03-18 00:45 -0700 http://bitbucket.org/pypy/pypy/changeset/383f13f771fe/ Log: test 979b3dd2b1a5 for ValueErrors diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -199,6 +199,11 @@ ctx.load_verify_locations(self.keycert) ctx.load_verify_locations(cafile=self.keycert, capath=None) + def test_constructor(self): + import _ssl + raises(ValueError, _ssl._SSLContext, -1) + raises(ValueError, _ssl._SSLContext, 42) + SSL_CERTIFICATE = """ -----BEGIN CERTIFICATE----- From noreply at buildbot.pypy.org Mon Mar 18 13:58:52 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:52 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: support 32bit large integers in bit operations Message-ID: <20130318125852.17C3A1C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r197:27c34fed4f35 Date: 2013-03-18 09:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/27c34fed4f35/ Log: support 32bit large integers in bit operations diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -11,6 +11,11 @@ from rpython.rlib import rarithmetic, rfloat, unroll, jit + +# for 32bit unwrap spec +uint = object() + + def assert_bounds(n0, minimum, maximum): if not minimum <= n0 < maximum: raise PrimitiveFailedError() @@ -96,6 +101,11 @@ w_arg = s_frame.peek(index) if spec is int: args += (interp.space.unwrap_int(w_arg), ) + elif spec is uint: + if isinstance(w_arg, model.W_SmallInteger): + args += (interp.space.unwrap_int(w_arg), ) + else: + args += (interp.space.unwrap_uint(w_arg), ) elif spec is index1_0: args += (interp.space.unwrap_int(w_arg)-1, ) elif spec is float: @@ -174,10 +184,10 @@ } for (code,op) in bitwise_binary_ops.items(): def make_func(op): - @expose_primitive(code, unwrap_spec=[int, int]) + @expose_primitive(code, unwrap_spec=[uint, uint]) def func(interp, s_frame, receiver, argument): - res = op(receiver, argument) - return interp.space.wrap_int(res) + res = abs(op(receiver, argument)) + return interp.space.wrap_uint(res) make_func(op) # #/ -- return the result of a division, only succeed if the division is exact From noreply at buildbot.pypy.org Mon Mar 18 13:58:53 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:53 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: use r_uint Message-ID: <20130318125853.4B9A21C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r198:29557f677cae Date: 2013-03-18 10:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/29557f677cae/ Log: use r_uint diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -10,10 +10,7 @@ from spyvm import wrapper from rpython.rlib import rarithmetic, rfloat, unroll, jit - - -# for 32bit unwrap spec -uint = object() +from rpython.rlib.rarithmetic import r_uint def assert_bounds(n0, minimum, maximum): @@ -101,9 +98,9 @@ w_arg = s_frame.peek(index) if spec is int: args += (interp.space.unwrap_int(w_arg), ) - elif spec is uint: + elif spec is r_uint: if isinstance(w_arg, model.W_SmallInteger): - args += (interp.space.unwrap_int(w_arg), ) + args += (r_uint(interp.space.unwrap_int(w_arg)), ) else: args += (interp.space.unwrap_uint(w_arg), ) elif spec is index1_0: @@ -184,7 +181,7 @@ } for (code,op) in bitwise_binary_ops.items(): def make_func(op): - @expose_primitive(code, unwrap_spec=[uint, uint]) + @expose_primitive(code, unwrap_spec=[r_uint, r_uint]) def func(interp, s_frame, receiver, argument): res = abs(op(receiver, argument)) return interp.space.wrap_uint(res) From noreply at buildbot.pypy.org Mon Mar 18 13:58:54 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:54 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Backed out changeset 29557f677cae Message-ID: <20130318125854.65E611C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r199:632038529d5c Date: 2013-03-18 10:38 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/632038529d5c/ Log: Backed out changeset 29557f677cae diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -10,7 +10,10 @@ from spyvm import wrapper from rpython.rlib import rarithmetic, rfloat, unroll, jit -from rpython.rlib.rarithmetic import r_uint + + +# for 32bit unwrap spec +uint = object() def assert_bounds(n0, minimum, maximum): @@ -98,9 +101,9 @@ w_arg = s_frame.peek(index) if spec is int: args += (interp.space.unwrap_int(w_arg), ) - elif spec is r_uint: + elif spec is uint: if isinstance(w_arg, model.W_SmallInteger): - args += (r_uint(interp.space.unwrap_int(w_arg)), ) + args += (interp.space.unwrap_int(w_arg), ) else: args += (interp.space.unwrap_uint(w_arg), ) elif spec is index1_0: @@ -181,7 +184,7 @@ } for (code,op) in bitwise_binary_ops.items(): def make_func(op): - @expose_primitive(code, unwrap_spec=[r_uint, r_uint]) + @expose_primitive(code, unwrap_spec=[uint, uint]) def func(interp, s_frame, receiver, argument): res = abs(op(receiver, argument)) return interp.space.wrap_uint(res) From noreply at buildbot.pypy.org Mon Mar 18 13:58:55 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:55 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: back out of 32bit unsinged bit operations, doesn't translate correctly Message-ID: <20130318125855.869611C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r200:cb7b0e997b1e Date: 2013-03-18 10:39 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/cb7b0e997b1e/ Log: back out of 32bit unsinged bit operations, doesn't translate correctly diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -11,11 +11,6 @@ from rpython.rlib import rarithmetic, rfloat, unroll, jit - -# for 32bit unwrap spec -uint = object() - - def assert_bounds(n0, minimum, maximum): if not minimum <= n0 < maximum: raise PrimitiveFailedError() @@ -101,11 +96,6 @@ w_arg = s_frame.peek(index) if spec is int: args += (interp.space.unwrap_int(w_arg), ) - elif spec is uint: - if isinstance(w_arg, model.W_SmallInteger): - args += (interp.space.unwrap_int(w_arg), ) - else: - args += (interp.space.unwrap_uint(w_arg), ) elif spec is index1_0: args += (interp.space.unwrap_int(w_arg)-1, ) elif spec is float: @@ -184,10 +174,10 @@ } for (code,op) in bitwise_binary_ops.items(): def make_func(op): - @expose_primitive(code, unwrap_spec=[uint, uint]) + @expose_primitive(code, unwrap_spec=[int, int]) def func(interp, s_frame, receiver, argument): - res = abs(op(receiver, argument)) - return interp.space.wrap_uint(res) + res = op(receiver, argument) + return interp.space.wrap_int(res) make_func(op) # #/ -- return the result of a division, only succeed if the division is exact From noreply at buildbot.pypy.org Mon Mar 18 13:58:56 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:56 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: fix translation by making W_Float a subclass of AbstractObjectWithIdentityHash Message-ID: <20130318125856.906E41C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r201:3e9d7888fc4d Date: 2013-03-18 11:02 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/3e9d7888fc4d/ Log: fix translation by making W_Float a subclass of AbstractObjectWithIdentityHash diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -2,9 +2,9 @@ Squeak model. W_Object - W_SmallInteger - W_Float + W_SmallInteger W_AbstractObjectWithIdentityHash + W_Float W_AbstractObjectWithClassReference W_PointersObject W_BytesObject @@ -21,7 +21,7 @@ from rpython.rlib import rrandom, objectmodel, jit from rpython.rlib.rarithmetic import intmask, r_uint from rpython.tool.pairtype import extendabletype -from rpython.rlib.objectmodel import instantiate +from rpython.rlib.objectmodel import instantiate, compute_hash from rpython.rtyper.lltypesystem import lltype, rffi from rsdl import RSDL, RSDL_helper @@ -154,7 +154,33 @@ def clone(self, space): return self -class W_Float(W_Object): +class W_AbstractObjectWithIdentityHash(W_Object): + """Object with explicit hash (ie all except small + ints and floats).""" + _attrs_ = ['hash'] + + #XXX maybe this is too extreme, but it's very random + hash_generator = rrandom.Random() + UNASSIGNED_HASH = sys.maxint + + hash = UNASSIGNED_HASH # default value + + def setchar(self, n0, character): + raise NotImplementedError() + + def gethash(self): + if self.hash == self.UNASSIGNED_HASH: + self.hash = hash = intmask(self.hash_generator.genrand32()) // 2 + return hash + return self.hash + + def invariant(self): + return isinstance(self.hash, int) + + def _become(self, w_other): + self.hash, w_other.hash = w_other.hash, self.hash + +class W_Float(W_AbstractObjectWithIdentityHash): """Boxed float value.""" _attrs_ = ['value'] @@ -172,11 +198,15 @@ return space.w_Float def gethash(self): - return 41 # XXX check this + return compute_hash(self.value) def invariant(self): - return self.value is not None # XXX but later: - #return isinstance(self.value, float) + return isinstance(self.value, float) + + def _become(self, w_other): + self.value, w_other.value = w_other.value, self.value + W_AbstractObjectWithIdentityHash._become(self, w_other) + def __repr__(self): return "W_Float(%f)" % self.value @@ -228,33 +258,6 @@ r = ((r >> 32) << 32) | uint self.value = float_unpack(r, 8) - -class W_AbstractObjectWithIdentityHash(W_Object): - """Object with explicit hash (ie all except small - ints and floats).""" - _attrs_ = ['hash'] - - #XXX maybe this is too extreme, but it's very random - hash_generator = rrandom.Random() - UNASSIGNED_HASH = sys.maxint - - hash = UNASSIGNED_HASH # default value - - def setchar(self, n0, character): - raise NotImplementedError() - - def gethash(self): - if self.hash == self.UNASSIGNED_HASH: - self.hash = hash = intmask(self.hash_generator.genrand32()) // 2 - return hash - return self.hash - - def invariant(self): - return isinstance(self.hash, int) - - def _become(self, w_other): - self.hash, w_other.hash = w_other.hash, self.hash - class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash): """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" From noreply at buildbot.pypy.org Mon Mar 18 13:58:57 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:57 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: expose Message class and doesNotUnderstand: symbol from special objects array Message-ID: <20130318125857.A2EA31C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r202:a56c1ebcec7d Date: 2013-03-18 13:01 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a56c1ebcec7d/ Log: expose Message class and doesNotUnderstand: symbol from special objects array diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -114,7 +114,7 @@ "BlockClosure" : SO_BLOCKCLOSURE_CLASS, "Point" : SO_POINT_CLASS, "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS, -# "Message" : SO_MESSAGE_CLASS, + "Message" : SO_MESSAGE_CLASS, "CompiledMethod" : SO_COMPILEDMETHOD_CLASS, "Semaphore" : SO_SEMAPHORE_CLASS, "Character" : SO_CHARACTER_CLASS, @@ -134,6 +134,7 @@ "special_selectors": SO_SPECIAL_SELECTORS_ARRAY, "smalltalkdict" : SO_SMALLTALK, "display" : SO_DISPLAY_OBJECT, + "doesNotUnderstand" : SO_DOES_NOT_UNDERSTAND, "interrupt_semaphore" : SO_USER_INTERRUPT_SEMAPHORE, } diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -87,6 +87,7 @@ define_cls("w_SmallInteger", "w_Integer") define_cls("w_LargePositiveInteger", "w_Integer", format=shadow.BYTES) define_cls("w_Float", "w_Number", format=shadow.BYTES) + define_cls("w_Message", "w_Object") define_cls("w_Collection", "w_Object") define_cls("w_SequenceableCollection", "w_Collection") define_cls("w_ArrayedCollection", "w_SequenceableCollection") diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -131,6 +131,8 @@ assert str(w) == "Point class" w = image.special(constants.SO_LARGEPOSITIVEINTEGER_CLASS) assert str(w) == "LargePositiveInteger class" + w = image.special(constants.SO_MESSAGE_CLASS) + assert str(w) == "Message class" # to be continued @@ -348,3 +350,17 @@ w_result = perform(interp.space.w_Float, "new") assert w_result is not None assert isinstance(w_result, model.W_Float) + +def test_doesNotUnderstand(): + w_dnu = interp.space.objtable["w_doesNotUnderstand"] + assert isinstance(w_dnu, model.W_BytesObject) + assert w_dnu.as_string() == "doesNotUnderstand:" + +def test_Message(): + w_message_cls = interp.space.w_Message + assert w_message_cls is interp.space.classtable["w_Message"] + assert isinstance(w_message_cls, model.W_PointersObject) + s_message_cls = w_message_cls.as_class_get_shadow(interp.space) + assert s_message_cls.getname() == "Message class" + w_message = s_message_cls.new() + assert isinstance(w_message, model.W_PointersObject) From noreply at buildbot.pypy.org Mon Mar 18 13:58:59 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:58:59 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: add test for DNU Message-ID: <20130318125859.229961C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r203:4e4cba5617f0 Date: 2013-03-18 13:12 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4e4cba5617f0/ Log: add test for DNU diff --git a/images/running-something-mini.image b/images/running-something-mini.image index e87374dba659882613fccb6486bb1da78b5e7fde..c748b0833b7ac5f4885ffd1f49a1d5a37df6b00f GIT binary patch [cut] diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -1,5 +1,5 @@ import py -from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow +from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow, MethodNotFound from spyvm import model, constants, primitives, conftest, wrapper from spyvm.tool.bitmanipulation import splitter @@ -287,9 +287,23 @@ interp._last_indent, w_selector.as_string(), receiver, [self.peek(argcount-1-i) for i in range(argcount)]) assert argcount >= 0 - s_method = receiverclassshadow.lookup(w_selector) - # XXX catch MethodNotFound here and send doesNotUnderstand: - # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. + try: + s_method = receiverclassshadow.lookup(w_selector) + except MethodNotFound: + arguments = self.pop_and_return_n(argcount) + s_message_class = self.space.classtable["w_Message"].as_class_get_shadow(self.space) + w_message = s_message_class.new() + w_message.store(self.space, 0, w_selector) + w_message.store(self.space, 1, self.space.wrap_list(arguments)) + try: + s_method = receiverclassshadow.lookup(self.space.objtable["w_doesNotUnderstand"]) + except MethodNotFound: + print "Missing doesDoesNotUnderstand in hierarchy of %s" % receiverclassshadow.getname() + raise + s_frame = s_method.create_frame(self.space, receiver, [w_message], self) + self.pop() + return interp.stack_frame(s_frame) + code = s_method.primitive() if code: # the primitive pushes the result (if any) onto the stack itself diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -356,6 +356,13 @@ assert isinstance(w_dnu, model.W_BytesObject) assert w_dnu.as_string() == "doesNotUnderstand:" +def test_run_doesNotUnderstand(): + from spyvm.test import test_miniimage + setup_module(test_miniimage, filename='running-something-mini.image') + w_result = test_miniimage.interp.perform(test_miniimage.interp.space.wrap_int(0), "runningADNU") + assert isinstance(w_result, model.W_BytesObject) + assert w_result.as_string() == "foobarThis:doesNotExist:('pypy' 'heya' )" + def test_Message(): w_message_cls = interp.space.w_Message assert w_message_cls is interp.space.classtable["w_Message"] From noreply at buildbot.pypy.org Mon Mar 18 13:59:00 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:59:00 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: add test for float hashes Message-ID: <20130318125900.36EEE1C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r204:417623e21afb Date: 2013-03-18 13:14 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/417623e21afb/ Log: add test for float hashes diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -260,3 +260,9 @@ assert math.isnan(target.value) else: assert target.value == f + +def test_float_hash(): + target = model.W_Float(1.1) + assert target.gethash() == model.W_Float(1.1).gethash() + target.store(space, 0, space.wrap_int(42)) + assert target.gethash() != model.W_Float(1.1).gethash() From noreply at buildbot.pypy.org Mon Mar 18 13:59:01 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:59:01 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: add tests for BE_DISPLAY and the DisplayBitmap object Message-ID: <20130318125901.517761C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r205:058fd41f1539 Date: 2013-03-18 13:39 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/058fd41f1539/ Log: add tests for BE_DISPLAY and the DisplayBitmap object diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -560,10 +560,10 @@ word = r_uint(0) pos = n * pixel_per_word * 4 for i in xrange(32): + word <<= 1 red = self.pixelbuffer[pos] if red == '\0': # Black word |= r_uint(1) - word <<= 1 pos += 4 return word diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -266,3 +266,26 @@ assert target.gethash() == model.W_Float(1.1).gethash() target.store(space, 0, space.wrap_int(42)) assert target.gethash() != model.W_Float(1.1).gethash() + +def test_display_bitmap(): + target = model.W_DisplayBitmap(space.w_Array, 100, 1, None) + target.setword(0, 0xFF00) + assert bin(target.getword(0)) == bin(0xFF00) + target.setword(0, 0x00FF00FF) + assert bin(target.getword(0)) == bin(0x00FF00FF) + target.setword(0, 0xFF00FF00) + assert bin(target.getword(0)) == bin(0xFF00FF00) + for i in xrange(32): + if (i + 1) % 4 == 0: + assert target.pixelbuffer[i] == "\xff" + else: + assert target.pixelbuffer[i] == "\x00" + for i in xrange(32, 64): + assert target.pixelbuffer[i] == "\xff" + for i in xrange(64, 96): + if (i + 1) % 4 == 0: + assert target.pixelbuffer[i] == "\xff" + else: + assert target.pixelbuffer[i] == "\x00" + for i in xrange(96, 128): + assert target.pixelbuffer[i] == "\xff" diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -3,7 +3,7 @@ import math from spyvm.primitives import prim_table, PrimitiveFailedError from spyvm import model, shadow, interpreter -from spyvm import constants, primitives, objspace, wrapper +from spyvm import constants, primitives, objspace, wrapper, display from rpython.rlib.rfloat import INFINITY, NAN, isinf, isnan @@ -610,6 +610,39 @@ assert w_2.getclass(space) is space.w_Array assert w_1 is not w_2 +def test_primitive_be_display(): + assert space.objtable["w_display"] is None + mock_display = model.W_PointersObject(space.w_Point, 4) + w_wordbmp = model.W_WordsObject(space.w_Array, 100) + mock_display.store(space, 0, w_wordbmp) # bitmap + mock_display.store(space, 1, space.wrap_int(32)) # width + mock_display.store(space, 2, space.wrap_int(10)) # height + mock_display.store(space, 3, space.wrap_int(1)) # depth + prim(primitives.BE_DISPLAY, [mock_display]) + assert space.objtable["w_display"] is mock_display + w_bitmap = mock_display.fetch(space, 0) + assert w_bitmap is not w_wordbmp + assert isinstance(w_bitmap, model.W_DisplayBitmap) + sdldisplay = w_bitmap.display + assert isinstance(sdldisplay, display.SDLDisplay) + + mock_display2 = model.W_PointersObject(space.w_Point, 4) + mock_display2.store(space, 0, model.W_WordsObject(space.w_Array, 100)) # bitmap + mock_display2.store(space, 1, space.wrap_int(32)) # width + mock_display2.store(space, 2, space.wrap_int(10)) # height + mock_display2.store(space, 3, space.wrap_int(1)) # depth + prim(primitives.BE_DISPLAY, [mock_display2]) + assert space.objtable["w_display"] is mock_display2 + w_bitmap2 = mock_display.fetch(space, 0) + assert isinstance(w_bitmap2, model.W_DisplayBitmap) + assert w_bitmap.display is w_bitmap2.display + assert sdldisplay.width == 32 + assert sdldisplay.height == 10 + + prim(primitives.BE_DISPLAY, [mock_display]) + assert space.objtable["w_display"] is mock_display + assert mock_display.fetch(space, 0) is w_bitmap + # Note: # primitives.NEXT is unimplemented as it is a performance optimization # primitives.NEXT_PUT is unimplemented as it is a performance optimization @@ -619,4 +652,3 @@ # primitives.VALUE_WITH_ARGS is tested in test_interpreter # primitives.OBJECT_AT is tested in test_interpreter # primitives.OBJECT_AT_PUT is tested in test_interpreter - From noreply at buildbot.pypy.org Mon Mar 18 13:59:02 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:59:02 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: add test for display flushing Message-ID: <20130318125902.723001C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r206:80508809991a Date: 2013-03-18 13:45 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/80508809991a/ Log: add test for display flushing diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -643,6 +643,29 @@ assert space.objtable["w_display"] is mock_display assert mock_display.fetch(space, 0) is w_bitmap +def test_primitive_force_display_update(monkeypatch): + assert space.objtable["w_display"] is None + mock_display = model.W_PointersObject(space.w_Point, 4) + w_wordbmp = model.W_WordsObject(space.w_Array, 100) + mock_display.store(space, 0, w_wordbmp) # bitmap + mock_display.store(space, 1, space.wrap_int(32)) # width + mock_display.store(space, 2, space.wrap_int(10)) # height + mock_display.store(space, 3, space.wrap_int(1)) # depth + prim(primitives.BE_DISPLAY, [mock_display]) + + class DisplayFlush(Exception): + pass + + def flush_to_screen_mock(): + raise DisplayFlush + + try: + monkeypatch.setattr(mock_display.fetch(space, 0), "flush_to_screen", flush_to_screen_mock) + with py.test.raises(DisplayFlush): + prim(primitives.FORCE_DISPLAY_UPDATE, [mock_display]) + finally: + monkeypatch.undo() + # Note: # primitives.NEXT is unimplemented as it is a performance optimization # primitives.NEXT_PUT is unimplemented as it is a performance optimization From noreply at buildbot.pypy.org Mon Mar 18 13:59:03 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:59:03 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: test that BITBLT_COPY_BITS primitive calls simulateCopyBits on the receiver Message-ID: <20130318125903.9C5A61C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r207:fceab4630b40 Date: 2013-03-18 13:51 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/fceab4630b40/ Log: test that BITBLT_COPY_BITS primitive calls simulateCopyBits on the receiver diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -666,6 +666,24 @@ finally: monkeypatch.undo() +def test_bitblt_copy_bits(monkeypatch): + class CallCopyBitsSimulation(Exception): + pass + + def perform_mock(w_rcvr, string): + if string == "simulateCopyBits": + raise CallCopyBitsSimulation + + mock_bitblt = model.W_PointersObject(space.w_Point, 15) + interp, w_frame, argument_count = mock([mock_bitblt], None) + + try: + monkeypatch.setattr(interp, "perform", perform_mock) + with py.test.raises(CallCopyBitsSimulation): + prim_table[primitives.BITBLT_COPY_BITS](interp, w_frame.as_context_get_shadow(space), argument_count-1) + finally: + monkeypatch.undo() + # Note: # primitives.NEXT is unimplemented as it is a performance optimization # primitives.NEXT_PUT is unimplemented as it is a performance optimization From noreply at buildbot.pypy.org Mon Mar 18 13:59:04 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:59:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: more specific test Message-ID: <20130318125904.A72091C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r208:65a278524d71 Date: 2013-03-18 13:52 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/65a278524d71/ Log: more specific test diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -670,11 +670,12 @@ class CallCopyBitsSimulation(Exception): pass + mock_bitblt = model.W_PointersObject(space.w_Point, 15) + def perform_mock(w_rcvr, string): - if string == "simulateCopyBits": + if w_rcvr is mock_bitblt and string == "simulateCopyBits": raise CallCopyBitsSimulation - mock_bitblt = model.W_PointersObject(space.w_Point, 15) interp, w_frame, argument_count = mock([mock_bitblt], None) try: From noreply at buildbot.pypy.org Mon Mar 18 13:59:06 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 13:59:06 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: Update image for debugging bitblt, the bitblt changeset, add the sdl display, and rename a test Message-ID: <20130318125906.09CDF1C01AF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r209:d6145fa46316 Date: 2013-03-18 13:58 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d6145fa46316/ Log: Update image for debugging bitblt, the bitblt changeset, add the sdl display, and rename a test diff too long, truncating to 2000 out of 2003 lines diff --git a/BitBltSim.14.cs b/BitBltSim.14.cs deleted file mode 100644 --- a/BitBltSim.14.cs +++ /dev/null @@ -1,1 +0,0 @@ -'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 15 March 2013 at 12:52:22 pm'! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta ' classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' poolDictionaries: '' category: 'Graphics-Support'! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path ' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBlt methodsFor: 'private'! clipRange destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - (clipY - destY). simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! !BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! copyBitsAgain self simulateCopyBits.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! calculateOffsets "check if we need to preload buffer (i.e., two words of source needed for first word of destination)" simPreload _ (sourceForm notNil) and: [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. simHDir < 0 ifTrue: [simPreload _ simPreload == false]. "calculate starting offsets" simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). simDestIndex _ simDy * simDestRaster + (simDx // WordSize). "calculate increments from end of 1 line to start of next" simSourceDelta _ (simSourceRaster * simVDir) - (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:28'! checkOverlap | t | "check for possible overlap of source and destination" simHDir _ simVDir _ 1. "defaults for no overlap" (sourceForm == destForm and: [simDy >= simSy]) ifTrue: [simDy > simSy "have to start at bottom" ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] ifFalse: [simDx > simSx "y's are equal, but x's are backward" ifTrue: [simHDir _ -1. simSx _ simSx + simW - 1. "start at right" simDx _ simDx + simW - 1. "and fix up masks" simSkewMask _ simSkewMask bitInvert. t _ simMask1. simMask1 _ simMask2. simMask2 _ t]]]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:53'! computeMasks | startBits endBits | "calculate skeq and edge masks" simDestBits _ destForm bits. simDestRaster _ destForm width - 1 // WordSize + 1. sourceForm notNil ifTrue: [simSourceBits _ sourceForm bits. simSourceRaster _ sourceForm width - 1 // WordSize + 1]. halftoneForm notNil ifTrue: [simHalftoneBits _ halftoneForm bits]. simSkew _ (simSx - simDx) bitAnd: WordSize0. "how many bits source gets skewed to right" startBits _ WordSize - (simDx bitAnd: WordSize0). "how many bits in first word" simMask1 _ RightMasks at: startBits + 1. endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). "how many bits in last word" simMask2 _ (RightMasks at: endBits + 1) bitInvert. simSkewMask _ (simSkew = 0 ifTrue: [0] ifFalse: [RightMasks at: WordSize - simSkew + 1]). "determine number of words stored per line; merge masks if necessary" simW < startBits ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. simMask2 _ 0. simNWords _ 1] ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 12:52'! copyLoop | prevWord thisWord skewWord mergeMask halftoneWord mergeWord newDestWord | 1 to: simH do: "here is the vertical loop" [:i | (halftoneForm notNil) ifTrue: "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" [halftoneWord _ simHalftoneBits at: (1 + ((simDy bitAnd: WordSize0) \\ simHalftoneBits size)). simDy _ simDy + simVDir] ifFalse: [halftoneWord _ AllOnes]. skewWord _ halftoneWord. simPreload ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. "load the 32bit shifter. TODO: check if this is WordSize dependent" simSourceIndex _ simSourceIndex + simHDir] ifFalse: [prevWord _ 0]. mergeMask _ simMask1. 1 to: simNWords do: "here is the inner horizontal loop" [:word | sourceForm notNil "if source is used" ifTrue: [prevWord _ prevWord bitAnd: simSkewMask. "HACK: Modulo access" thisWord _ simSourceBits at: (simSourceIndex \\ simSourceBits size) + 1. "pick up next word" skewWord _ prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert). prevWord _ thisWord. skewWord _ (skewWord bitShift: simSkew) bitOr: (skewWord bitShift: simSkew - WordSize)]. "WordSize-bit rotate" mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (simDestBits at: simDestIndex + 1). newDestWord := ((mergeMask bitAnd: mergeWord) bitOr: (mergeMask bitInvert bitAnd: (simDestBits at: simDestIndex + 1))). newDestWord < 0 ifTrue: [newDestWord := newDestWord bitInvert + 1]. simDestBits at: simDestIndex + 1 put: newDestWord. simSourceIndex _ simSourceIndex + simHDir. simDestIndex _ simDestIndex + simHDir. word = (simNWords - 1) ifTrue: [mergeMask _ simMask2] ifFalse: [mergeMask _ AllOnes]]. simSourceIndex _ simSourceIndex + simSourceDelta. simDestIndex _ simDestIndex + simDestDelta]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 12:50'! merge: srcWord with: dstWord "These are the 16 combination rules." combinationRule = 0 ifTrue: [^ 0]. combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert]. combinationRule = 3 ifTrue: [^ srcWord]. combinationRule = 4 ifTrue: [^ srcWord bitInvert bitAnd: dstWord]. combinationRule = 5 ifTrue: [^ dstWord]. combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. combinationRule = 8 ifTrue: [^ srcWord bitInvert bitAnd: dstWord bitInvert]. combinationRule = 9 ifTrue: [^ srcWord bitInvert bitXor: dstWord]. combinationRule = 10 ifTrue: [^ dstWord bitInvert]. combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert]. combinationRule = 12 ifTrue: [^ srcWord bitInvert]. combinationRule = 13 ifTrue: [^ srcWord bitInvert bitOr: dstWord]. combinationRule = 14 ifTrue: [^ srcWord bitInvert bitOr: dstWord bitInvert]. combinationRule = 15 ifTrue: [^ dstWord bitAnd: AllOnes]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:16'! sanitizeInput destForm unhibernate. sourceForm ifNil: [sourceForm := destForm] ifNotNil: [sourceForm unhibernate]. halftoneForm ifNotNil: [ halftoneForm isForm ifFalse: [halftoneForm := Form new bits: halftoneForm; yourself]. halftoneForm unhibernate]. width ifNil: [width := sourceForm width]. height ifNil: [height := sourceForm height]. self roundVariables.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:20'! simClipRange "clip and adjust source origin and extent appropriately" "first in x" destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. "then in y" destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - clipY - destY. simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:12'! simulateCopyBits self sanitizeInput. self simClipRange. (simW <= 0 or: [simH <= 0]) ifTrue: [^ self]. self computeMasks. self checkOverlap. self calculateOffsets. self copyLoop.! ! !BitBlt class methodsFor: 'benchmarks' stamp: 'tfel 3/13/2013 14:48'! simpleBenchmark | aBitBlt depth f time | depth := Display depth. Display newDepth: 1. time := Time millisecondsToRun: [ f := Form extent: 20 @ 20. f fillBlack. aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: 5 destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits]. Display newDepth: depth. ^ time! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! exampleOne "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" | pathClass path displayDepth | displayDepth := Display depth. Display newDepth: 1. (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. Display fillWhite. 1 to: 16 do: [:index | BitBlt exampleAt: (path at: index) rule: index - 1 fillColor: nil]. [Sensor anyButtonPressed] whileFalse: []. Display newDepth: displayDepth. "BitBlt exampleOne"! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! exampleTwo "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." | f aBitBlt displayDepth | "create a small black Form source as a brush. " displayDepth := Display depth. Display newDepth: 1. f := Form extent: 20 @ 20. f fillBlack. "create a BitBlt which will OR gray into the display. " aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: Form over destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. "paint the gray Form on the screen for a while. " [Sensor anyButtonPressed] whileFalse: [aBitBlt destOrigin: Sensor cursorPoint. aBitBlt simulateCopyBits]. Display newDepth: displayDepth. "BitBlt exampleTwo"! ! !BitBlt class methodsFor: 'private' stamp: 'tfel 3/13/2013 09:05'! exampleAt: originPoint rule: rule fillColor: mask "This builds a source and destination form and copies the source to the destination using the specifed rule and mask. It is called from the method named exampleOne. Only works with Display depth of 1" | s d border aBitBlt | border:=Form extent: 32 at 32. border fillBlack. border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). s displayOn: Display at: originPoint. border displayOn: Display at: originPoint rule: Form under. d displayOn: Display at: originPoint + (s width @0). border displayOn: Display at: originPoint + (s width @0) rule: Form under. d displayOn: Display at: originPoint + (s extent // (2 @ 1)). aBitBlt := BitBlt destForm: Display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits. border displayOn: Display at: originPoint + (s extent // (2 @ 1)) rule: Form under. "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! !BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! initialize "self initialize" super initialize. WordSize := 32. WordSize0 := WordSize - 1. RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. AllOnes _ (2 raisedTo: WordSize) - 1. ! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:50'! initialize super initialize. "World restoreDisplay." (Form extent: 500 at 300 depth: 32) fill: (0 at 0 extent: 500 at 300) fillColor: Color green muchDarker; displayOn: Display at: 0 at 0 rule: Form over.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 12:05'! runTest222: index | s d aBitBlt mask rule simD originPoint display | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). display := (Form extent: Display extent) depth: 1. display fillWhite. aBitBlt := BitBlt destForm: display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: display computeBoundingBox. aBitBlt simulateCopyBits. simD := display deepCopy. aBitBlt copyBits. simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. display displayOn: Display at: originPoint - (10 at 0) rule: Form over. display bits = simD bits ifTrue: [index asString displayAt: originPoint - 20] ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 12:48'! runTest: index | s d aBitBlt mask rule simD originPoint | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). simD := d deepCopy. aBitBlt := BitBlt destForm: simD sourceForm: s fillColor: mask combinationRule: rule destOrigin: 0 at 0 sourceOrigin: 0 @ 0 extent: s extent clipRect: simD computeBoundingBox. aBitBlt simulateCopyBits. aBitBlt := BitBlt destForm: d sourceForm: s fillColor: mask combinationRule: rule destOrigin: 0 at 0 sourceOrigin: 0 @ 0 extent: s extent clipRect: d computeBoundingBox. aBitBlt copyBits. simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. d displayOn: Display at: originPoint - (10 at 0) rule: Form over. d bits = simD bits ifTrue: [index asString displayAt: originPoint - 20] ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:38'! setUp | pathClass | (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. ! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test1 self runTest: 1.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:41'! test10 self runTest: 10.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:39'! test11 self runTest: 11.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:28'! test12 self runTest: 12.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:28'! test13 self runTest: 13.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:29'! test14 self runTest: 14.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:29'! test15 self runTest: 15.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:29'! test16 self runTest: 16.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test2 self runTest: 2.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test3 self runTest: 3.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test4 self runTest: 4.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test5 self runTest: 5.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test6 self runTest: 6.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test7 self runTest: 7.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test8 self runTest: 8.! ! !BitBltSimTest methodsFor: 'as yet unclassified' stamp: 'tfel 3/15/2013 11:24'! test9 self runTest: 9.! ! BitBltSimTest removeSelector: #testAllAlphasRgbAdd! BitBltSimTest removeSelector: #testAllAlphasRgbMax! BitBltSimTest removeSelector: #testAllAlphasRgbMin! BitBltSimTest removeSelector: #testAllAlphasRgbMinInvert! BitBltSimTest removeSelector: #testAllAlphasRgbMul! BitBltSimTest removeSelector: #testAllAlphasRgbSub! BitBltSimTest removeSelector: #testAlphaCompositing! BitBltSimTest removeSelector: #testAlphaCompositing2! BitBltSimTest removeSelector: #testBWAdd! BitBltSimTest removeSelector: #testFirst! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBltSimTest reorganize! ('as yet unclassified' initialize runTest222: runTest: setUp test1 test10 test11 test12 test13 test14 test15 test16 test2 test3 test4 test5 test6 test7 test8 test9) ! BitBlt initialize! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta' classVariableNames: 'AllOnes RightMasks WordSize WordSize0' poolDictionaries: '' category: 'Graphics-Support'! \ No newline at end of file diff --git a/BitBltSim.19.cs b/BitBltSim.19.cs --- a/BitBltSim.19.cs +++ b/BitBltSim.19.cs @@ -1,1 +1,674 @@ -'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 17 March 2013 at 4:20:53 pm'! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug ' classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' poolDictionaries: '' category: 'Graphics-Support'! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path ' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBlt methodsFor: 'private'! clipRange destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - (clipY - destY). simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! !BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! copyBitsAgain self simulateCopyBits.! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! calculateOffsets "check if we need to preload buffer (i.e., two words of source needed for first word of destination)" simPreload _ (sourceForm notNil) and: [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. simHDir < 0 ifTrue: [simPreload _ simPreload == false]. "calculate starting offsets" simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). simDestIndex _ simDy * simDestRaster + (simDx // WordSize). "calculate increments from end of 1 line to start of next" simSourceDelta _ (simSourceRaster * simVDir) - (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! checkOverlap | t | "check for possible overlap of source and destination" simHDir _ simVDir _ 1. "defaults for no overlap" (sourceForm == destForm and: [simDy >= simSy]) ifTrue: [simDy > simSy "have to start at bottom" ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] ifFalse: [simDx > simSx "y's are equal, but x's are backward" ifTrue: [simHDir _ -1. simSx _ simSx + simW - 1. "start at right" simDx _ simDx + simW - 1. "and fix up masks" simSkewMask _ simSkewMask bitInvert32. t _ simMask1. simMask1 _ simMask2. simMask2 _ t]]]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! computeMasks | startBits endBits | "calculate skeq and edge masks" simDestBits _ destForm bits. simDestRaster _ destForm width - 1 // WordSize + 1. sourceForm notNil ifTrue: [simSourceBits _ sourceForm bits. simSourceRaster _ sourceForm width - 1 // WordSize + 1]. halftoneForm notNil ifTrue: [simHalftoneBits _ halftoneForm bits]. simSkew _ (simSx - simDx) bitAnd: WordSize0. "how many bits source gets skewed to right" startBits _ WordSize - (simDx bitAnd: WordSize0). "how many bits in first word" simMask1 _ RightMasks at: startBits + 1. endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). "how many bits in last word" simMask2 _ (RightMasks at: endBits + 1) bitInvert32. simSkewMask _ (simSkew = 0 ifTrue: [0] ifFalse: [RightMasks at: WordSize - simSkew + 1]). "determine number of words stored per line; merge masks if necessary" simW < startBits ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. simMask2 _ 0. simNWords _ 1] ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! copyLoop | prevWord thisWord skewWord mergeMask halftoneWord mergeWord | 1 to: simH do: "here is the vertical loop" [:i | (halftoneForm notNil) ifTrue: "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" [halftoneWord _ simHalftoneBits at: (1 + ((simDy bitAnd: WordSize0) \\ simHalftoneBits size)). simDy _ simDy + simVDir] ifFalse: [halftoneWord _ AllOnes]. skewWord _ halftoneWord. simPreload ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. "load the 32bit shifter. TODO: check if this is WordSize dependent" simSourceIndex _ simSourceIndex + simHDir] ifFalse: [prevWord _ 0]. mergeMask _ simMask1. 1 to: simNWords do: "here is the inner horizontal loop" [:word | sourceForm notNil "if source is used" ifTrue: [prevWord _ prevWord bitAnd: simSkewMask. thisWord := simSourceIndex >= simSourceBits size ifTrue: [AllOnes] "XXX: Change from BB: Ignore out-of bounds" ifFalse: [simSourceBits at: simSourceIndex + 1]. "pick up next word" skewWord _ prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert32). prevWord _ thisWord. "Change from BB: bitAnd: AllOnes to stay in word bounds" skewWord _ ((skewWord bitShift: simSkew) bitAnd: AllOnes) bitOr: (skewWord bitShift: simSkew - WordSize)]. "WordSize-bit rotate" mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (simDestBits at: simDestIndex + 1). simDestBits at: simDestIndex + 1 put: ((mergeMask bitAnd: mergeWord) bitOr: (mergeMask bitInvert32 bitAnd: (simDestBits at: simDestIndex + 1))). simSourceIndex _ simSourceIndex + simHDir. simDestIndex _ simDestIndex + simHDir. word = (simNWords - 1) ifTrue: [mergeMask _ simMask2] ifFalse: [mergeMask _ AllOnes]]. simSourceIndex _ simSourceIndex + simSourceDelta. simDestIndex _ simDestIndex + simDestDelta]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! merge: srcWord with: dstWord "These are the 16 combination rules." combinationRule = 0 ifTrue: [^ 0]. combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert32]. combinationRule = 3 ifTrue: [^ srcWord]. combinationRule = 4 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord]. combinationRule = 5 ifTrue: [^ dstWord]. combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. combinationRule = 8 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord bitInvert32]. combinationRule = 9 ifTrue: [^ srcWord bitInvert32 bitXor: dstWord]. combinationRule = 10 ifTrue: [^ dstWord bitInvert32]. combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert32]. combinationRule = 12 ifTrue: [^ srcWord bitInvert32]. combinationRule = 13 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord]. combinationRule = 14 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord bitInvert]. combinationRule = 15 ifTrue: [^ dstWord]! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 14:49'! sanitizeInput destForm unhibernate. sourceForm ifNil: [sourceForm := destForm] ifNotNil: [sourceForm unhibernate]. halftoneForm ifNotNil: [ (halftoneForm isKindOf: Form) ifFalse: [halftoneForm := Form new bits: halftoneForm; yourself]. halftoneForm unhibernate]. width ifNil: [width := sourceForm width]. height ifNil: [height := sourceForm height].! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 13:04'! simClipRange "clip and adjust source origin and extent appropriately" "first in x" destX >= clipX ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] ifFalse: [simSx _ sourceX + (clipX - destX). simW _ width - (clipX - destX). simDx _ clipX]. simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. "then in y" destY >= clipY ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] ifFalse: [simSy _ sourceY + clipY - destY. simH _ height - clipY - destY. simDy _ clipY]. simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. simSx < 0 ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. simSy < 0 ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:31'! simDebug: aString simInDebug == true ifFalse: [simInDebug := true. aString displayAt: 10 at 10. 1 to: 10000000 do: [:i |]. simInDebug := false]. ! ! !BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:30'! simulateCopyBits self simDebug: Time now asString. self sanitizeInput. self simClipRange. (simW <= 0 or: [simH <= 0]) ifTrue: [^ self]. self computeMasks. self checkOverlap. self calculateOffsets. self copyLoop.! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! exampleOne "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" | pathClass path displayDepth | displayDepth := Display depth. Display newDepth: 1. (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. Display fillWhite. 1 to: 16 do: [:index | BitBlt exampleAt: (path at: index) rule: index - 1 fillColor: nil]. [Sensor anyButtonPressed] whileFalse: []. Display newDepth: displayDepth. "BitBlt exampleOne"! ! !BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! exampleTwo "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." | f aBitBlt displayDepth | "create a small black Form source as a brush. " displayDepth := Display depth. Display newDepth: 1. f := Form extent: 20 @ 20. f fillBlack. "create a BitBlt which will OR gray into the display. " aBitBlt := BitBlt destForm: Display sourceForm: f fillColor: Color gray combinationRule: Form over destOrigin: Sensor cursorPoint sourceOrigin: 0 @ 0 extent: f extent clipRect: Display computeBoundingBox. "paint the gray Form on the screen for a while. " [Sensor anyButtonPressed] whileFalse: [aBitBlt destOrigin: Sensor cursorPoint. aBitBlt simulateCopyBits]. Display newDepth: displayDepth. "BitBlt exampleTwo"! ! !BitBlt class methodsFor: 'private' stamp: 'tfel 3/15/2013 14:32'! exampleAt: originPoint rule: rule fillColor: mask "This builds a source and destination form and copies the source to the destination using the specifed rule and mask. It is called from the method named exampleOne. Only works with Display depth of 1" | s d border aBitBlt | border:=Form extent: 32 at 32. border fillBlack. border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). s displayOn: Display at: originPoint. border displayOn: Display at: originPoint rule: Form under. d displayOn: Display at: originPoint + (s width @0). border displayOn: Display at: originPoint + (s width @0) rule: Form under. d displayOn: Display at: originPoint + (s extent // (2 @ 1)). aBitBlt := BitBlt destForm: Display sourceForm: s fillColor: mask combinationRule: rule destOrigin: originPoint + (s extent // (2 @ 1)) sourceOrigin: 0 @ 0 extent: s extent clipRect: Display computeBoundingBox. aBitBlt simulateCopyBits. border displayOn: Display at: originPoint + (s extent // (2 @ 1)) rule: Form under. "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! !BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! initialize "self initialize" super initialize. WordSize := 32. WordSize0 := WordSize - 1. RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. AllOnes _ (2 raisedTo: WordSize) - 1. ! ! !BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! destForm "black top half, white bottom half" | bitmap | bitmap := Bitmap new: 32. #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) withIndexDo: [:word :idx | bitmap at: idx put: word]. ^ (Form extent: 32 at 32 depth: 1) bits: bitmap; yourself! ! !BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! sourceForm "white form with black rect in the middle" | bitmap | bitmap := Bitmap new: 32. #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) withIndexDo: [:word :idx | bitmap at: idx put: word]. ^ (Form extent: 32 at 32 depth: 1) bits: bitmap; yourself! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test1 self runTest: 1.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:41'! test10 self runTest: 10.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:39'! test11 self runTest: 11.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! test12 self runTest: 12.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! test13 self runTest: 13.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! test14 self runTest: 14.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! test15 self runTest: 15.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! test16 self runTest: 16.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test2 self runTest: 2.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test3 self runTest: 3.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test4 self runTest: 4.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test5 self runTest: 5.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test6 self runTest: 6.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test7 self runTest: 7.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test8 self runTest: 8.! ! !BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! test9 self runTest: 9.! ! !BitBltSimTest methodsFor: 'test data' stamp: 'tfel 3/15/2013 14:43'! bitsForTest: index | results | results := #( #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ). ^ results at: index! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/17/2013 16:18'! runTest: index "self runTestVisual: index" "to show something" self runTestLarge: index "to test non-aligned stuff" "self runTestDark: index" "to run without blitting primitive, against saved data" ! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:37'! runTestDark: index | s d rule | rule := index - 1. s := self sourceForm. d := self destForm. (BitBlt destForm: d sourceForm: s fillColor: nil combinationRule: rule destOrigin: 0 at 0 sourceOrigin: 0 at 0 extent: s extent clipRect: (0 at 0 extent: d extent)) simulateCopyBits. self assert: d bits asArray = (self bitsForTest: index). ! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:30'! runTestLarge: index | s d aBitBlt mask rule simD originPoint destOrigin | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 500 at 500. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). destOrigin := originPoint + (s extent // (2 @ 1)). simD := d deepCopy. aBitBlt := BitBlt destForm: simD sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: simD computeBoundingBox. aBitBlt simulateCopyBits. aBitBlt := BitBlt destForm: d sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: d computeBoundingBox. aBitBlt copyBits. self assert: [d bits = simD bits]. ! ! !BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:43'! runTestVisual: index | s d aBitBlt mask rule simD originPoint destOrigin | originPoint := path at: index. rule := index - 1. mask := nil. s := Form extent: 32 at 32. s fillWhite. s fillBlack: (7 at 7 corner: 25 at 25). d := Form extent: 32 at 32. d fillWhite. d fillBlack: (0 at 0 corner: 32 at 16). destOrigin := 0 @ 0. simD := d deepCopy. aBitBlt := BitBlt destForm: simD sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: simD computeBoundingBox. aBitBlt simulateCopyBits. aBitBlt := BitBlt destForm: d sourceForm: s fillColor: mask combinationRule: rule destOrigin: destOrigin sourceOrigin: 0 @ 0 extent: s extent clipRect: d computeBoundingBox. aBitBlt copyBits. simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. d displayOn: Display at: originPoint - (10 at 0) rule: Form over. d bits = simD bits ifTrue: [index asString displayAt: originPoint - 20] ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! !BitBltSimTest methodsFor: 'initialize-release' stamp: 'tfel 3/15/2013 14:38'! initialize super initialize. "World restoreDisplay." "(Form extent: 500 at 300 depth: 32) fill: (0 at 0 extent: 500 at 300) fillColor: Color green muchDarker; displayOn: Display at: 0 at 0 rule: Form over."! ! !BitBltSimTest methodsFor: 'running' stamp: 'tfel 3/15/2013 11:38'! setUp | pathClass | (Smalltalk hasClassNamed: #Path) ifTrue: [pathClass := Smalltalk at: #Path. path := pathClass new. 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. path := path translateBy: 60 @ 40.] ifFalse: ["For mini image, where Path isn't available" path := OrderedCollection new: 16. #(40 115 190 265) do: [:y | #(60 160 260 360) do: [:x | path add: x at y]]]. ! ! !BitBltSimTest class methodsFor: 'as yet unclassified' stamp: 'tfel 3/17/2013 16:08'! runAllTestsBlind 1 to: 16 do: [:idx | self new setUp; runTestDark: idx].! ! TestCase subclass: #BitBltSimTest instanceVariableNames: 'path' classVariableNames: '' poolDictionaries: '' category: 'GraphicsTests-Primitives'! !BitBltSimTest reorganize! ('sourceForm' destForm sourceForm) ('testing' test1 test10 test11 test12 test13 test14 test15 test16 test2 test3 test4 test5 test6 test7 test8 test9) ('test data' bitsForTest:) ('running-modes' runTest: runTestDark: runTestLarge: runTestVisual:) ('initialize-release' initialize) ('running' setUp) ! BitBlt initialize! Object subclass: #BitBlt instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug' classVariableNames: 'AllOnes RightMasks WordSize WordSize0' poolDictionaries: '' category: 'Graphics-Support'! \ No newline at end of file +'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 17 March 2013 at 4:20:53 pm'! +Object subclass: #BitBlt + instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug ' + classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' + poolDictionaries: '' + category: 'Graphics-Support'! +TestCase subclass: #BitBltSimTest + instanceVariableNames: 'path ' + classVariableNames: '' + poolDictionaries: '' + category: 'GraphicsTests-Primitives'! + +!BitBlt methodsFor: 'private'! +clipRange + destX >= clipX + ifTrue: + [simSx _ sourceX. + simDx _ destX. + simW _ width] + ifFalse: + [simSx _ sourceX + (clipX - destX). + simW _ width - (clipX - destX). + simDx _ clipX]. + simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. + destY >= clipY + ifTrue: + [simSy _ sourceY. + simDy _ destY. + simH _ height] + ifFalse: + [simSy _ sourceY + clipY - destY. + simH _ height - (clipY - destY). + simDy _ clipY]. + simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. + simSx < 0 + ifTrue: + [simDx _ simDx - simSx. + simW _ simW + simSx. + simSx _ 0]. + simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. + simSy < 0 + ifTrue: + [simDy _ simDy - simSy. + simH _ simH + simSy. + simSy _ 0]. + simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! + +!BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! +copyBitsAgain + + self simulateCopyBits.! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! +calculateOffsets + "check if we need to preload buffer + (i.e., two words of source needed for first word of destination)" + simPreload _ (sourceForm notNil) and: + [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. + simHDir < 0 ifTrue: [simPreload _ simPreload == false]. + "calculate starting offsets" + simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). + simDestIndex _ simDy * simDestRaster + (simDx // WordSize). + "calculate increments from end of 1 line to start of next" + simSourceDelta _ + (simSourceRaster * simVDir) - + (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). + simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! +checkOverlap + | t | + "check for possible overlap of source and destination" + simHDir _ simVDir _ 1. "defaults for no overlap" + (sourceForm == destForm and: [simDy >= simSy]) + ifTrue: + [simDy > simSy "have to start at bottom" + ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] + ifFalse: [simDx > simSx "y's are equal, but x's are backward" + ifTrue: [simHDir _ -1. + simSx _ simSx + simW - 1. + "start at right" + simDx _ simDx + simW - 1. + "and fix up masks" + simSkewMask _ simSkewMask bitInvert32. + t _ simMask1. + simMask1 _ simMask2. + simMask2 _ t]]]! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! +computeMasks + | startBits endBits | + "calculate skeq and edge masks" + simDestBits _ destForm bits. + simDestRaster _ destForm width - 1 // WordSize + 1. + sourceForm notNil + ifTrue: [simSourceBits _ sourceForm bits. + simSourceRaster _ sourceForm width - 1 // WordSize + 1]. + halftoneForm notNil + ifTrue: [simHalftoneBits _ halftoneForm bits]. + simSkew _ (simSx - simDx) bitAnd: WordSize0. + "how many bits source gets skewed to right" + startBits _ WordSize - (simDx bitAnd: WordSize0). + "how many bits in first word" + simMask1 _ RightMasks at: startBits + 1. + endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). + "how many bits in last word" + simMask2 _ (RightMasks at: endBits + 1) bitInvert32. + simSkewMask _ + (simSkew = 0 + ifTrue: [0] + ifFalse: [RightMasks at: WordSize - simSkew + 1]). + "determine number of words stored per line; merge masks if necessary" + simW < startBits + ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. + simMask2 _ 0. + simNWords _ 1] + ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! +copyLoop + | prevWord thisWord skewWord mergeMask + halftoneWord mergeWord | + 1 to: simH do: "here is the vertical loop" + [:i | + (halftoneForm notNil) + ifTrue: + "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" + [halftoneWord _ simHalftoneBits at: (1 + (simDy \\ simHalftoneBits size)). + simDy _ simDy + simVDir] + ifFalse: [halftoneWord _ AllOnes]. + skewWord _ halftoneWord. + simPreload + ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. + "load the 32bit shifter. TODO: check if this is WordSize dependent" + simSourceIndex _ simSourceIndex + simHDir] + ifFalse: [prevWord _ 0]. + mergeMask _ simMask1. + 1 to: simNWords do: "here is the inner horizontal loop" + [:word | + sourceForm notNil "if source is used" + ifTrue: + [prevWord _ prevWord bitAnd: simSkewMask. + "XXX: Hack to work around out-of-bounds access" + thisWord := simSourceBits at: (simSourceIndex \\ simSourceBits size) + 1. + "pick up next word" + skewWord _ + prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert32). + prevWord _ thisWord. + "Change from BB: bitAnd: AllOnes to stay in word bounds" + skewWord _ ((skewWord bitShift: simSkew) bitAnd: AllOnes) bitOr: + (skewWord bitShift: simSkew - WordSize)]. + "WordSize-bit rotate" + mergeWord _ self merge: (skewWord bitAnd: halftoneWord) + with: (simDestBits at: simDestIndex + 1). + simDestBits + at: simDestIndex + 1 + put: ((mergeMask bitAnd: mergeWord) + bitOr: (mergeMask bitInvert32 + bitAnd: (simDestBits at: simDestIndex + 1))). + simSourceIndex _ simSourceIndex + simHDir. + simDestIndex _ simDestIndex + simHDir. + word = (simNWords - 1) + ifTrue: [mergeMask _ simMask2] + ifFalse: [mergeMask _ AllOnes]]. + simSourceIndex _ simSourceIndex + simSourceDelta. + simDestIndex _ simDestIndex + simDestDelta]! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! +merge: srcWord with: dstWord + "These are the 16 combination rules." + combinationRule = 0 ifTrue: [^ 0]. + combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. + combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert32]. + combinationRule = 3 ifTrue: [^ srcWord]. + combinationRule = 4 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord]. + combinationRule = 5 ifTrue: [^ dstWord]. + combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. + combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. + combinationRule = 8 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord bitInvert32]. + combinationRule = 9 ifTrue: [^ srcWord bitInvert32 bitXor: dstWord]. + combinationRule = 10 ifTrue: [^ dstWord bitInvert32]. + combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert32]. + combinationRule = 12 ifTrue: [^ srcWord bitInvert32]. + combinationRule = 13 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord]. + combinationRule = 14 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord bitInvert32]. + combinationRule = 15 ifTrue: [^ dstWord]! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 14:49'! +sanitizeInput + + destForm unhibernate. + sourceForm + ifNil: [sourceForm := destForm] + ifNotNil: [sourceForm unhibernate]. + halftoneForm ifNotNil: [ + (halftoneForm isKindOf: Form) + ifFalse: [halftoneForm := Form new + bits: halftoneForm; + yourself]. + halftoneForm unhibernate]. + width ifNil: [width := sourceForm width]. + height ifNil: [height := sourceForm height].! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 13:04'! +simClipRange + "clip and adjust source origin and extent appropriately" + "first in x" + destX >= clipX + ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] + ifFalse: [simSx _ sourceX + (clipX - destX). + simW _ width - (clipX - destX). + simDx _ clipX]. + simDx + simW > (clipX + clipWidth) + ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. + "then in y" + destY >= clipY + ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] + ifFalse: [simSy _ sourceY + clipY - destY. + simH _ height - clipY - destY. + simDy _ clipY]. + simDy + simH > (clipY + clipHeight) + ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. + simSx < 0 + ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. + simSx + simW > sourceForm width + ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. + simSy < 0 + ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. + simSy + simH > sourceForm height + ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. +! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:31'! +simDebug: aString + + simInDebug == true + ifTrue: [1 to: 400 by: 20 + do: [:word | Display bits at: word put: 0]. + simInDebug _ false] + ifFalse: [1 to: 400 by: 20 + do: [:word | Display bits at: word put: 4294967295]. + simInDebug _ true] +! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:30'! +simulateCopyBits + + "self simDebug: Time now asString." + self sanitizeInput. + self simClipRange. + (simW <= 0 or: [simH <= 0]) + ifTrue: [^ self]. + self computeMasks. + self checkOverlap. + self calculateOffsets. + self copyLoop.! ! + + +!BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! +exampleOne + "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" + | pathClass path displayDepth | + + displayDepth := Display depth. + Display newDepth: 1. + + (Smalltalk hasClassNamed: #Path) + ifTrue: [pathClass := Smalltalk at: #Path. + path := pathClass new. + 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. + path := path translateBy: 60 @ 40.] + ifFalse: ["For mini image, where Path isn't available" + path := OrderedCollection new: 16. + #(40 115 190 265) do: [:y | + #(60 160 260 360) do: [:x | + path add: x at y]]]. + Display fillWhite. + 1 to: 16 do: [:index | BitBlt + exampleAt: (path at: index) + rule: index - 1 + fillColor: nil]. + + [Sensor anyButtonPressed] whileFalse: []. + Display newDepth: displayDepth. + + "BitBlt exampleOne"! ! + +!BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! +exampleTwo + "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." + | f aBitBlt displayDepth | + "create a small black Form source as a brush. " + displayDepth := Display depth. + Display newDepth: 1. + f := Form extent: 20 @ 20. + f fillBlack. + "create a BitBlt which will OR gray into the display. " + aBitBlt := BitBlt + destForm: Display + sourceForm: f + fillColor: Color gray + combinationRule: Form over + destOrigin: Sensor cursorPoint + sourceOrigin: 0 @ 0 + extent: f extent + clipRect: Display computeBoundingBox. + "paint the gray Form on the screen for a while. " + [Sensor anyButtonPressed] whileFalse: + [aBitBlt destOrigin: Sensor cursorPoint. + aBitBlt simulateCopyBits]. + Display newDepth: displayDepth. + "BitBlt exampleTwo"! ! + +!BitBlt class methodsFor: 'private' stamp: 'tfel 3/15/2013 14:32'! +exampleAt: originPoint rule: rule fillColor: mask + "This builds a source and destination form and copies the source to the + destination using the specifed rule and mask. It is called from the method + named exampleOne. Only works with Display depth of 1" + + | s d border aBitBlt | + border:=Form extent: 32 at 32. + border fillBlack. + border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. + s := Form extent: 32 at 32. + s fillWhite. + s fillBlack: (7 at 7 corner: 25 at 25). + d := Form extent: 32 at 32. + d fillWhite. + d fillBlack: (0 at 0 corner: 32 at 16). + + s displayOn: Display at: originPoint. + border displayOn: Display at: originPoint rule: Form under. + d displayOn: Display at: originPoint + (s width @0). + border displayOn: Display at: originPoint + (s width @0) rule: Form under. + + d displayOn: Display at: originPoint + (s extent // (2 @ 1)). + aBitBlt := BitBlt + destForm: Display + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: originPoint + (s extent // (2 @ 1)) + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: Display computeBoundingBox. + aBitBlt simulateCopyBits. + border + displayOn: Display at: originPoint + (s extent // (2 @ 1)) + rule: Form under. + + "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! + +!BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! +initialize + "self initialize" + super initialize. + WordSize := 32. + WordSize0 := WordSize - 1. + RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. + AllOnes _ (2 raisedTo: WordSize) - 1. +! ! + + +!BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! +destForm + "black top half, white bottom half" + | bitmap | + bitmap := Bitmap new: 32. + #(4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) withIndexDo: [:word :idx | + bitmap at: idx put: word]. + ^ (Form extent: 32 at 32 depth: 1) + bits: bitmap; + yourself! ! + +!BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! +sourceForm + "white form with black rect in the middle" + | bitmap | + bitmap := Bitmap new: 32. + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 + 33554304 33554304 33554304 33554304 33554304 + 33554304 33554304 33554304 33554304 33554304 + 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) withIndexDo: [:word :idx | + bitmap at: idx put: word]. + ^ (Form extent: 32 at 32 depth: 1) + bits: bitmap; + yourself! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test1 + + self runTest: 1.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:41'! +test10 + + self runTest: 10.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:39'! +test11 + + self runTest: 11.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! +test12 + + self runTest: 12.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! +test13 + + self runTest: 13.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! +test14 + + self runTest: 14.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! +test15 + + self runTest: 15.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! +test16 + + self runTest: 16.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test2 + + self runTest: 2.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test3 + + self runTest: 3.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test4 + + self runTest: 4.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test5 + + self runTest: 5.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test6 + + self runTest: 6.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test7 + + self runTest: 7.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test8 + + self runTest: 8.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test9 + + self runTest: 9.! ! + +!BitBltSimTest methodsFor: 'test data' stamp: 'tfel 3/15/2013 14:43'! +bitsForTest: index + | results | + results := #( + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + ). + + ^ results at: index! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/17/2013 16:18'! +runTest: index + "self runTestVisual: index" "to show something" + self runTestLarge: index "to test non-aligned stuff" + "self runTestDark: index" "to run without blitting primitive, against saved data" +! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:37'! +runTestDark: index + | s d rule | + rule := index - 1. + s := self sourceForm. + d := self destForm. + (BitBlt + destForm: d + sourceForm: s + fillColor: nil + combinationRule: rule + destOrigin: 0 at 0 + sourceOrigin: 0 at 0 + extent: s extent + clipRect: (0 at 0 extent: d extent)) + simulateCopyBits. + self assert: d bits asArray = (self bitsForTest: index). +! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:30'! +runTestLarge: index + | s d aBitBlt mask rule simD originPoint destOrigin | + originPoint := path at: index. + rule := index - 1. + mask := nil. + s := Form extent: 32 at 32. + s fillWhite. + s fillBlack: (7 at 7 corner: 25 at 25). + d := Form extent: 500 at 500. + d fillWhite. + d fillBlack: (0 at 0 corner: 32 at 16). + destOrigin := originPoint + (s extent // (2 @ 1)). + + simD := d deepCopy. + aBitBlt := BitBlt + destForm: simD + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: simD computeBoundingBox. + aBitBlt simulateCopyBits. + + aBitBlt := BitBlt + destForm: d + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: d computeBoundingBox. + aBitBlt copyBits. + self assert: [d bits = simD bits]. +! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:43'! +runTestVisual: index + | s d aBitBlt mask rule simD originPoint destOrigin | + originPoint := path at: index. + rule := index - 1. + mask := nil. + s := Form extent: 32 at 32. + s fillWhite. + s fillBlack: (7 at 7 corner: 25 at 25). + d := Form extent: 32 at 32. + d fillWhite. + d fillBlack: (0 at 0 corner: 32 at 16). + destOrigin := 0 @ 0. + + simD := d deepCopy. + aBitBlt := BitBlt + destForm: simD + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: simD computeBoundingBox. + aBitBlt simulateCopyBits. + + aBitBlt := BitBlt + destForm: d + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: d computeBoundingBox. + aBitBlt copyBits. + + simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. + d displayOn: Display at: originPoint - (10 at 0) rule: Form over. + + d bits = simD bits + ifTrue: [index asString displayAt: originPoint - 20] + ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! + +!BitBltSimTest methodsFor: 'initialize-release' stamp: 'tfel 3/15/2013 14:38'! +initialize + + super initialize. + "World restoreDisplay." + "(Form extent: 500 at 300 depth: 32) + fill: (0 at 0 extent: 500 at 300) fillColor: Color green muchDarker; + displayOn: Display at: 0 at 0 rule: Form over."! ! + +!BitBltSimTest methodsFor: 'running' stamp: 'tfel 3/15/2013 11:38'! +setUp + | pathClass | + (Smalltalk hasClassNamed: #Path) + ifTrue: [pathClass := Smalltalk at: #Path. + path := pathClass new. + 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. + path := path translateBy: 60 @ 40.] + ifFalse: ["For mini image, where Path isn't available" + path := OrderedCollection new: 16. + #(40 115 190 265) do: [:y | + #(60 160 260 360) do: [:x | + path add: x at y]]]. + ! ! + + +!BitBltSimTest class methodsFor: 'as yet unclassified' stamp: 'tfel 3/17/2013 16:08'! +runAllTestsBlind + + 1 to: 16 do: [:idx | + self new + setUp; + runTestDark: idx].! ! + +TestCase subclass: #BitBltSimTest + instanceVariableNames: 'path' + classVariableNames: '' + poolDictionaries: '' + category: 'GraphicsTests-Primitives'! + +!BitBltSimTest reorganize! +('sourceForm' destForm sourceForm) +('testing' test1 test10 test11 test12 test13 test14 test15 test16 test2 test3 test4 test5 test6 test7 test8 test9) +('test data' bitsForTest:) +('running-modes' runTest: runTestDark: runTestLarge: runTestVisual:) +('initialize-release' initialize) +('running' setUp) +! + +BitBlt initialize! +Object subclass: #BitBlt + instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug' + classVariableNames: 'AllOnes RightMasks WordSize WordSize0' + poolDictionaries: '' + category: 'Graphics-Support'! diff --git a/images/minibluebookdebug.image b/images/minibluebookdebug.image index 216c8fee57511e58f50f6757a635bdaad0672d2b..55870b1f6092dbfa3dcb4e4d0c46fec62b223bf2 GIT binary patch [cut] diff --git a/spyvm/display.py b/spyvm/display.py new file mode 100644 --- /dev/null +++ b/spyvm/display.py @@ -0,0 +1,41 @@ +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import lltype, rffi + +from rsdl import RSDL, RSDL_helper + + +class SDLDisplay(object): + _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface"] + + def __init__(self): + assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 + self.has_surface = False + + def set_video_mode(self, w, h, d): + assert w > 0 and h > 0 + assert d in [1, 2, 4, 8, 16, 32] + self.width = w + self.height = h + self.depth = d + self.screen = RSDL.SetVideoMode(w, h, 32, 0) + assert self.screen + # self.fillwhite() + + def set_pixelbuffer(self, pixelbuffer): + if self.has_surface: + RSDL.FreeSurface(self.surface) + pitch = 4 * self.width + rmask, gmask, bmask, amask = r_uint(0x000000FF), r_uint(0x0000FF00), r_uint(0x00FF0000), r_uint(0xFF000000) + self.surface = RSDL.CreateRGBSurfaceFrom(pixelbuffer, self.width, self.height, 32, pitch, + rmask, gmask, bmask, amask) + self.has_surface = True + + def fillwhite(self): + fmt = self.screen.c_format + color = RSDL.MapRGB(fmt, 255, 255, 255) + RSDL.FillRect(self.screen, lltype.nullptr(RSDL.Rect), color) + RSDL.Flip(self.screen) + + def blit(self): + RSDL.BlitSurface(self.surface, lltype.nullptr(RSDL.Rect), self.screen, lltype.nullptr(RSDL.Rect)) + RSDL.Flip(self.screen) diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -156,7 +156,7 @@ assert repr(space.w_true.shadow_of_my_class(space)) == "" assert repr(space.w_false.shadow_of_my_class(space)) == "" -def test_special_classes0(): +def test_special_objects0(): From noreply at buildbot.pypy.org Mon Mar 18 14:12:51 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 14:12:51 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: fix tests Message-ID: <20130318131251.8F23E1C07FF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r210:eace0d3f61e4 Date: 2013-03-18 14:11 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/eace0d3f61e4/ Log: fix tests diff --git a/images/running-something-mini.image b/images/running-something-mini.image index c748b0833b7ac5f4885ffd1f49a1d5a37df6b00f..ac12f8bf556e24ceb6046e03ef26d92e1e1201bf GIT binary patch [cut] diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -47,9 +47,9 @@ def test_read_header(): reader = open_miniimage(space) reader.read_header() - assert reader.endofmemory == 655196 - assert reader.oldbaseaddress == -1220960256 - assert reader.specialobjectspointer == -1220832384 + assert reader.endofmemory == 726592 + assert reader.oldbaseaddress == -1221464064 + assert reader.specialobjectspointer == -1221336216 def test_read_all_header(): reader = open_miniimage(space) @@ -113,8 +113,8 @@ def test_special_classes0(): image = get_image() - w = image.special(constants.SO_BITMAP_CLASS) - assert str(w) == "Bitmap class" + # w = image.special(constants.SO_BITMAP_CLASS) + # assert str(w) == "Bitmap class" w = image.special(constants.SO_SMALLINTEGER_CLASS) assert str(w) == "SmallInteger class" w = image.special(constants.SO_STRING_CLASS) diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -644,7 +644,6 @@ assert mock_display.fetch(space, 0) is w_bitmap def test_primitive_force_display_update(monkeypatch): - assert space.objtable["w_display"] is None mock_display = model.W_PointersObject(space.w_Point, 4) w_wordbmp = model.W_WordsObject(space.w_Array, 100) mock_display.store(space, 0, w_wordbmp) # bitmap From noreply at buildbot.pypy.org Mon Mar 18 14:12:52 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 14:12:52 +0100 (CET) Subject: [pypy-commit] lang-smalltalk bitblt: close bitblt branch Message-ID: <20130318131252.BB4871C07FF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: bitblt Changeset: r211:69ff16574514 Date: 2013-03-18 14:12 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/69ff16574514/ Log: close bitblt branch From noreply at buildbot.pypy.org Mon Mar 18 14:12:54 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 14:12:54 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge bitblt Message-ID: <20130318131254.D009E1C07FF@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r212:4530b0bf03a4 Date: 2013-03-18 14:12 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4530b0bf03a4/ Log: merge bitblt diff --git a/BitBltSim.19.cs b/BitBltSim.19.cs new file mode 100644 --- /dev/null +++ b/BitBltSim.19.cs @@ -0,0 +1,674 @@ +'From Squeak4.4 of 15 December 2012 [latest update: #12303] on 17 March 2013 at 4:20:53 pm'! +Object subclass: #BitBlt + instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug ' + classVariableNames: 'AllOnes RightMasks WordSize0 WordSize ' + poolDictionaries: '' + category: 'Graphics-Support'! +TestCase subclass: #BitBltSimTest + instanceVariableNames: 'path ' + classVariableNames: '' + poolDictionaries: '' + category: 'GraphicsTests-Primitives'! + +!BitBlt methodsFor: 'private'! +clipRange + destX >= clipX + ifTrue: + [simSx _ sourceX. + simDx _ destX. + simW _ width] + ifFalse: + [simSx _ sourceX + (clipX - destX). + simW _ width - (clipX - destX). + simDx _ clipX]. + simDx + simW > (clipX + clipWidth) ifTrue: [simW _ simW - (simDx + simW - (clipX + clipWidth))]. + destY >= clipY + ifTrue: + [simSy _ sourceY. + simDy _ destY. + simH _ height] + ifFalse: + [simSy _ sourceY + clipY - destY. + simH _ height - (clipY - destY). + simDy _ clipY]. + simDy + simH > (clipY + clipHeight) ifTrue: [simH _ simH - (simDy + simH - (clipY + clipHeight))]. + simSx < 0 + ifTrue: + [simDx _ simDx - simSx. + simW _ simW + simSx. + simSx _ 0]. + simSx + simW > sourceForm width ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. + simSy < 0 + ifTrue: + [simDy _ simDy - simSy. + simH _ simH + simSy. + simSy _ 0]. + simSy + simH > sourceForm height ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]! ! + +!BitBlt methodsFor: 'private' stamp: 'tfel 3/13/2013 12:02'! +copyBitsAgain + + self simulateCopyBits.! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 10:31'! +calculateOffsets + "check if we need to preload buffer + (i.e., two words of source needed for first word of destination)" + simPreload _ (sourceForm notNil) and: + [simSkew ~= 0 and: [simSkew <= (simSx bitAnd: WordSize0)]]. + simHDir < 0 ifTrue: [simPreload _ simPreload == false]. + "calculate starting offsets" + simSourceIndex _ simSy * simSourceRaster + (simSx // WordSize). + simDestIndex _ simDy * simDestRaster + (simDx // WordSize). + "calculate increments from end of 1 line to start of next" + simSourceDelta _ + (simSourceRaster * simVDir) - + (simNWords + (simPreload ifTrue: [1] ifFalse: [0]) * simHDir). + simDestDelta _ (simDestRaster * simVDir) - (simNWords * simHDir)! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! +checkOverlap + | t | + "check for possible overlap of source and destination" + simHDir _ simVDir _ 1. "defaults for no overlap" + (sourceForm == destForm and: [simDy >= simSy]) + ifTrue: + [simDy > simSy "have to start at bottom" + ifTrue: [simVDir _ -1. simSy _ simSy + simH - 1. simDy _ simDy + simH - 1] + ifFalse: [simDx > simSx "y's are equal, but x's are backward" + ifTrue: [simHDir _ -1. + simSx _ simSx + simW - 1. + "start at right" + simDx _ simDx + simW - 1. + "and fix up masks" + simSkewMask _ simSkewMask bitInvert32. + t _ simMask1. + simMask1 _ simMask2. + simMask2 _ t]]]! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:16'! +computeMasks + | startBits endBits | + "calculate skeq and edge masks" + simDestBits _ destForm bits. + simDestRaster _ destForm width - 1 // WordSize + 1. + sourceForm notNil + ifTrue: [simSourceBits _ sourceForm bits. + simSourceRaster _ sourceForm width - 1 // WordSize + 1]. + halftoneForm notNil + ifTrue: [simHalftoneBits _ halftoneForm bits]. + simSkew _ (simSx - simDx) bitAnd: WordSize0. + "how many bits source gets skewed to right" + startBits _ WordSize - (simDx bitAnd: WordSize0). + "how many bits in first word" + simMask1 _ RightMasks at: startBits + 1. + endBits _ WordSize0 - ((simDx + simW - 1) bitAnd: WordSize0). + "how many bits in last word" + simMask2 _ (RightMasks at: endBits + 1) bitInvert32. + simSkewMask _ + (simSkew = 0 + ifTrue: [0] + ifFalse: [RightMasks at: WordSize - simSkew + 1]). + "determine number of words stored per line; merge masks if necessary" + simW < startBits + ifTrue: [simMask1 _ simMask1 bitAnd: simMask2. + simMask2 _ 0. + simNWords _ 1] + ifFalse: [simNWords _ (simW - startBits - 1) // WordSize + 2].! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! +copyLoop + | prevWord thisWord skewWord mergeMask + halftoneWord mergeWord | + 1 to: simH do: "here is the vertical loop" + [:i | + (halftoneForm notNil) + ifTrue: + "XXX Accessing simHalftoneBits with wrap-around ... different from BlueBook" + [halftoneWord _ simHalftoneBits at: (1 + (simDy \\ simHalftoneBits size)). + simDy _ simDy + simVDir] + ifFalse: [halftoneWord _ AllOnes]. + skewWord _ halftoneWord. + simPreload + ifTrue: [prevWord _ simSourceBits at: simSourceIndex + 1. + "load the 32bit shifter. TODO: check if this is WordSize dependent" + simSourceIndex _ simSourceIndex + simHDir] + ifFalse: [prevWord _ 0]. + mergeMask _ simMask1. + 1 to: simNWords do: "here is the inner horizontal loop" + [:word | + sourceForm notNil "if source is used" + ifTrue: + [prevWord _ prevWord bitAnd: simSkewMask. + "XXX: Hack to work around out-of-bounds access" + thisWord := simSourceBits at: (simSourceIndex \\ simSourceBits size) + 1. + "pick up next word" + skewWord _ + prevWord bitOr: (thisWord bitAnd: simSkewMask bitInvert32). + prevWord _ thisWord. + "Change from BB: bitAnd: AllOnes to stay in word bounds" + skewWord _ ((skewWord bitShift: simSkew) bitAnd: AllOnes) bitOr: + (skewWord bitShift: simSkew - WordSize)]. + "WordSize-bit rotate" + mergeWord _ self merge: (skewWord bitAnd: halftoneWord) + with: (simDestBits at: simDestIndex + 1). + simDestBits + at: simDestIndex + 1 + put: ((mergeMask bitAnd: mergeWord) + bitOr: (mergeMask bitInvert32 + bitAnd: (simDestBits at: simDestIndex + 1))). + simSourceIndex _ simSourceIndex + simHDir. + simDestIndex _ simDestIndex + simHDir. + word = (simNWords - 1) + ifTrue: [mergeMask _ simMask2] + ifFalse: [mergeMask _ AllOnes]]. + simSourceIndex _ simSourceIndex + simSourceDelta. + simDestIndex _ simDestIndex + simDestDelta]! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/17/2013 16:17'! +merge: srcWord with: dstWord + "These are the 16 combination rules." + combinationRule = 0 ifTrue: [^ 0]. + combinationRule = 1 ifTrue: [^ srcWord bitAnd: dstWord]. + combinationRule = 2 ifTrue: [^ srcWord bitAnd: dstWord bitInvert32]. + combinationRule = 3 ifTrue: [^ srcWord]. + combinationRule = 4 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord]. + combinationRule = 5 ifTrue: [^ dstWord]. + combinationRule = 6 ifTrue: [^ srcWord bitXor: dstWord]. + combinationRule = 7 ifTrue: [^ srcWord bitOr: dstWord]. + combinationRule = 8 ifTrue: [^ srcWord bitInvert32 bitAnd: dstWord bitInvert32]. + combinationRule = 9 ifTrue: [^ srcWord bitInvert32 bitXor: dstWord]. + combinationRule = 10 ifTrue: [^ dstWord bitInvert32]. + combinationRule = 11 ifTrue: [^ srcWord bitOr: dstWord bitInvert32]. + combinationRule = 12 ifTrue: [^ srcWord bitInvert32]. + combinationRule = 13 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord]. + combinationRule = 14 ifTrue: [^ srcWord bitInvert32 bitOr: dstWord bitInvert32]. + combinationRule = 15 ifTrue: [^ dstWord]! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 14:49'! +sanitizeInput + + destForm unhibernate. + sourceForm + ifNil: [sourceForm := destForm] + ifNotNil: [sourceForm unhibernate]. + halftoneForm ifNotNil: [ + (halftoneForm isKindOf: Form) + ifFalse: [halftoneForm := Form new + bits: halftoneForm; + yourself]. + halftoneForm unhibernate]. + width ifNil: [width := sourceForm width]. + height ifNil: [height := sourceForm height].! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/15/2013 13:04'! +simClipRange + "clip and adjust source origin and extent appropriately" + "first in x" + destX >= clipX + ifTrue: [simSx _ sourceX. simDx _ destX. simW _ width] + ifFalse: [simSx _ sourceX + (clipX - destX). + simW _ width - (clipX - destX). + simDx _ clipX]. + simDx + simW > (clipX + clipWidth) + ifTrue: [simW _ simW - ((simDx + simW) - (clipX + clipWidth))]. + "then in y" + destY >= clipY + ifTrue: [simSy _ sourceY. simDy _ destY. simH _ height] + ifFalse: [simSy _ sourceY + clipY - destY. + simH _ height - clipY - destY. + simDy _ clipY]. + simDy + simH > (clipY + clipHeight) + ifTrue: [simH _ simH - ((simDy + simH) - (clipY + clipHeight))]. + simSx < 0 + ifTrue: [simDx _ simDx - simSx. simW _ simW + simSx. simSx _ 0]. + simSx + simW > sourceForm width + ifTrue: [simW _ simW - (simSx + simW - sourceForm width)]. + simSy < 0 + ifTrue: [simDy _ simDy - simSy. simH _ simH + simSy. simSy _ 0]. + simSy + simH > sourceForm height + ifTrue: [simH _ simH - (simSy + simH - sourceForm height)]. +! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:31'! +simDebug: aString + + simInDebug == true + ifTrue: [1 to: 400 by: 20 + do: [:word | Display bits at: word put: 0]. + simInDebug _ false] + ifFalse: [1 to: 400 by: 20 + do: [:word | Display bits at: word put: 4294967295]. + simInDebug _ true] +! ! + +!BitBlt methodsFor: 'simulation' stamp: 'tfel 3/16/2013 17:30'! +simulateCopyBits + + "self simDebug: Time now asString." + self sanitizeInput. + self simClipRange. + (simW <= 0 or: [simH <= 0]) + ifTrue: [^ self]. + self computeMasks. + self checkOverlap. + self calculateOffsets. + self copyLoop.! ! + + +!BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:40'! +exampleOne + "This tests BitBlt by displaying the result of all sixteen combination rules that BitBlt is capable of using. (Please see the comment in BitBlt for the meaning of the combination rules). This only works at Display depth of 1. (Rule 15 does not work?)" + | pathClass path displayDepth | + + displayDepth := Display depth. + Display newDepth: 1. + + (Smalltalk hasClassNamed: #Path) + ifTrue: [pathClass := Smalltalk at: #Path. + path := pathClass new. + 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. + path := path translateBy: 60 @ 40.] + ifFalse: ["For mini image, where Path isn't available" + path := OrderedCollection new: 16. + #(40 115 190 265) do: [:y | + #(60 160 260 360) do: [:x | + path add: x at y]]]. + Display fillWhite. + 1 to: 16 do: [:index | BitBlt + exampleAt: (path at: index) + rule: index - 1 + fillColor: nil]. + + [Sensor anyButtonPressed] whileFalse: []. + Display newDepth: displayDepth. + + "BitBlt exampleOne"! ! + +!BitBlt class methodsFor: 'examples' stamp: 'tfel 3/13/2013 13:12'! +exampleTwo + "This is to test painting with a gray tone. It also tests that the seaming with gray patterns is correct in the microcode. Lets you paint for a while and then automatically stops. This only works at Depth of 1." + | f aBitBlt displayDepth | + "create a small black Form source as a brush. " + displayDepth := Display depth. + Display newDepth: 1. + f := Form extent: 20 @ 20. + f fillBlack. + "create a BitBlt which will OR gray into the display. " + aBitBlt := BitBlt + destForm: Display + sourceForm: f + fillColor: Color gray + combinationRule: Form over + destOrigin: Sensor cursorPoint + sourceOrigin: 0 @ 0 + extent: f extent + clipRect: Display computeBoundingBox. + "paint the gray Form on the screen for a while. " + [Sensor anyButtonPressed] whileFalse: + [aBitBlt destOrigin: Sensor cursorPoint. + aBitBlt simulateCopyBits]. + Display newDepth: displayDepth. + "BitBlt exampleTwo"! ! + +!BitBlt class methodsFor: 'private' stamp: 'tfel 3/15/2013 14:32'! +exampleAt: originPoint rule: rule fillColor: mask + "This builds a source and destination form and copies the source to the + destination using the specifed rule and mask. It is called from the method + named exampleOne. Only works with Display depth of 1" + + | s d border aBitBlt | + border:=Form extent: 32 at 32. + border fillBlack. + border fill: (1 at 1 extent: 30 at 30) fillColor: Color white. + s := Form extent: 32 at 32. + s fillWhite. + s fillBlack: (7 at 7 corner: 25 at 25). + d := Form extent: 32 at 32. + d fillWhite. + d fillBlack: (0 at 0 corner: 32 at 16). + + s displayOn: Display at: originPoint. + border displayOn: Display at: originPoint rule: Form under. + d displayOn: Display at: originPoint + (s width @0). + border displayOn: Display at: originPoint + (s width @0) rule: Form under. + + d displayOn: Display at: originPoint + (s extent // (2 @ 1)). + aBitBlt := BitBlt + destForm: Display + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: originPoint + (s extent // (2 @ 1)) + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: Display computeBoundingBox. + aBitBlt simulateCopyBits. + border + displayOn: Display at: originPoint + (s extent // (2 @ 1)) + rule: Form under. + + "BitBlt exampleAt: 100 at 100 rule: 0 fillColor: nil" ! ! + +!BitBlt class methodsFor: 'class initialization' stamp: 'tfel 3/15/2013 10:23'! +initialize + "self initialize" + super initialize. + WordSize := 32. + WordSize0 := WordSize - 1. + RightMasks _ #(0), (1 to: WordSize) collect: [:m | (2 raisedTo: m) - 1]. + AllOnes _ (2 raisedTo: WordSize) - 1. +! ! + + +!BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! +destForm + "black top half, white bottom half" + | bitmap | + bitmap := Bitmap new: 32. + #(4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) withIndexDo: [:word :idx | + bitmap at: idx put: word]. + ^ (Form extent: 32 at 32 depth: 1) + bits: bitmap; + yourself! ! + +!BitBltSimTest methodsFor: 'sourceForm' stamp: 'tfel 3/15/2013 14:24'! +sourceForm + "white form with black rect in the middle" + | bitmap | + bitmap := Bitmap new: 32. + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 + 33554304 33554304 33554304 33554304 33554304 + 33554304 33554304 33554304 33554304 33554304 + 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) withIndexDo: [:word :idx | + bitmap at: idx put: word]. + ^ (Form extent: 32 at 32 depth: 1) + bits: bitmap; + yourself! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test1 + + self runTest: 1.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:41'! +test10 + + self runTest: 10.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:39'! +test11 + + self runTest: 11.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! +test12 + + self runTest: 12.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:28'! +test13 + + self runTest: 13.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! +test14 + + self runTest: 14.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! +test15 + + self runTest: 15.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:29'! +test16 + + self runTest: 16.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test2 + + self runTest: 2.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test3 + + self runTest: 3.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test4 + + self runTest: 4.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test5 + + self runTest: 5.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test6 + + self runTest: 6.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test7 + + self runTest: 7.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test8 + + self runTest: 8.! ! + +!BitBltSimTest methodsFor: 'testing' stamp: 'tfel 3/15/2013 11:24'! +test9 + + self runTest: 9.! ! + +!BitBltSimTest methodsFor: 'test data' stamp: 'tfel 3/15/2013 14:43'! +bitsForTest: index + | results | + results := #( + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 0 0 0 0 0 0 0) + + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(0 0 0 0 0 0 0 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 33554304 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4261412991 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295) + + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + ). + + ^ results at: index! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/17/2013 16:18'! +runTest: index + "self runTestVisual: index" "to show something" + self runTestLarge: index "to test non-aligned stuff" + "self runTestDark: index" "to run without blitting primitive, against saved data" +! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:37'! +runTestDark: index + | s d rule | + rule := index - 1. + s := self sourceForm. + d := self destForm. + (BitBlt + destForm: d + sourceForm: s + fillColor: nil + combinationRule: rule + destOrigin: 0 at 0 + sourceOrigin: 0 at 0 + extent: s extent + clipRect: (0 at 0 extent: d extent)) + simulateCopyBits. + self assert: d bits asArray = (self bitsForTest: index). +! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:30'! +runTestLarge: index + | s d aBitBlt mask rule simD originPoint destOrigin | + originPoint := path at: index. + rule := index - 1. + mask := nil. + s := Form extent: 32 at 32. + s fillWhite. + s fillBlack: (7 at 7 corner: 25 at 25). + d := Form extent: 500 at 500. + d fillWhite. + d fillBlack: (0 at 0 corner: 32 at 16). + destOrigin := originPoint + (s extent // (2 @ 1)). + + simD := d deepCopy. + aBitBlt := BitBlt + destForm: simD + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: simD computeBoundingBox. + aBitBlt simulateCopyBits. + + aBitBlt := BitBlt + destForm: d + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: d computeBoundingBox. + aBitBlt copyBits. + self assert: [d bits = simD bits]. +! ! + +!BitBltSimTest methodsFor: 'running-modes' stamp: 'tfel 3/15/2013 14:43'! +runTestVisual: index + | s d aBitBlt mask rule simD originPoint destOrigin | + originPoint := path at: index. + rule := index - 1. + mask := nil. + s := Form extent: 32 at 32. + s fillWhite. + s fillBlack: (7 at 7 corner: 25 at 25). + d := Form extent: 32 at 32. + d fillWhite. + d fillBlack: (0 at 0 corner: 32 at 16). + destOrigin := 0 @ 0. + + simD := d deepCopy. + aBitBlt := BitBlt + destForm: simD + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: simD computeBoundingBox. + aBitBlt simulateCopyBits. + + aBitBlt := BitBlt + destForm: d + sourceForm: s + fillColor: mask + combinationRule: rule + destOrigin: destOrigin + sourceOrigin: 0 @ 0 + extent: s extent + clipRect: d computeBoundingBox. + aBitBlt copyBits. + + simD displayOn: Display at: originPoint + (s width @ 0) rule: Form over. + d displayOn: Display at: originPoint - (10 at 0) rule: Form over. + + d bits = simD bits + ifTrue: [index asString displayAt: originPoint - 20] + ifFalse: [(index asString, ' failed') displayAt: originPoint - 20. self assert: false].! ! + +!BitBltSimTest methodsFor: 'initialize-release' stamp: 'tfel 3/15/2013 14:38'! +initialize + + super initialize. + "World restoreDisplay." + "(Form extent: 500 at 300 depth: 32) + fill: (0 at 0 extent: 500 at 300) fillColor: Color green muchDarker; + displayOn: Display at: 0 at 0 rule: Form over."! ! + +!BitBltSimTest methodsFor: 'running' stamp: 'tfel 3/15/2013 11:38'! +setUp + | pathClass | + (Smalltalk hasClassNamed: #Path) + ifTrue: [pathClass := Smalltalk at: #Path. + path := pathClass new. + 0 to: 3 do: [:i | 0 to: 3 do: [:j | path add: j * 100 @ (i * 75)]]. + path := path translateBy: 60 @ 40.] + ifFalse: ["For mini image, where Path isn't available" + path := OrderedCollection new: 16. + #(40 115 190 265) do: [:y | + #(60 160 260 360) do: [:x | + path add: x at y]]]. + ! ! + + +!BitBltSimTest class methodsFor: 'as yet unclassified' stamp: 'tfel 3/17/2013 16:08'! +runAllTestsBlind + + 1 to: 16 do: [:idx | + self new + setUp; + runTestDark: idx].! ! + +TestCase subclass: #BitBltSimTest + instanceVariableNames: 'path' + classVariableNames: '' + poolDictionaries: '' + category: 'GraphicsTests-Primitives'! + +!BitBltSimTest reorganize! +('sourceForm' destForm sourceForm) +('testing' test1 test10 test11 test12 test13 test14 test15 test16 test2 test3 test4 test5 test6 test7 test8 test9) +('test data' bitsForTest:) +('running-modes' runTest: runTestDark: runTestLarge: runTestVisual:) +('initialize-release' initialize) +('running' setUp) +! + +BitBlt initialize! +Object subclass: #BitBlt + instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight colorMap simW simH simSx simSy simDx simDy simDestBits simDestRaster simSourceBits simSourceRaster simHalftoneBits simSkew simMask1 simMask2 simSkewMask simNWords simHDir simVDir simPreload simSourceIndex simDestIndex simSourceDelta simDestDelta simInDebug' + classVariableNames: 'AllOnes RightMasks WordSize WordSize0' + poolDictionaries: '' + category: 'Graphics-Support'! diff --git a/images/mini.image b/images/mini.image index 4e0739b0aa769798ae904fee0eff0b0eac8c8368..a8cfbe28687d27aca4ab2d9dd0f37da338fd475d GIT binary patch [cut] diff --git a/images/minibluebookdebug.image b/images/minibluebookdebug.image new file mode 100644 index 0000000000000000000000000000000000000000..55870b1f6092dbfa3dcb4e4d0c46fec62b223bf2 GIT binary patch [cut] diff --git a/images/running-something-mini.image b/images/running-something-mini.image index e87374dba659882613fccb6486bb1da78b5e7fde..ac12f8bf556e24ceb6046e03ef26d92e1e1201bf GIT binary patch [cut] diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -114,7 +114,7 @@ "BlockClosure" : SO_BLOCKCLOSURE_CLASS, "Point" : SO_POINT_CLASS, "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS, -# "Message" : SO_MESSAGE_CLASS, + "Message" : SO_MESSAGE_CLASS, "CompiledMethod" : SO_COMPILEDMETHOD_CLASS, "Semaphore" : SO_SEMAPHORE_CLASS, "Character" : SO_CHARACTER_CLASS, @@ -134,6 +134,7 @@ "special_selectors": SO_SPECIAL_SELECTORS_ARRAY, "smalltalkdict" : SO_SMALLTALK, "display" : SO_DISPLAY_OBJECT, + "doesNotUnderstand" : SO_DOES_NOT_UNDERSTAND, "interrupt_semaphore" : SO_USER_INTERRUPT_SEMAPHORE, } diff --git a/spyvm/display.py b/spyvm/display.py new file mode 100644 --- /dev/null +++ b/spyvm/display.py @@ -0,0 +1,41 @@ +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import lltype, rffi + +from rsdl import RSDL, RSDL_helper + + +class SDLDisplay(object): + _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface"] + + def __init__(self): + assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 + self.has_surface = False + + def set_video_mode(self, w, h, d): + assert w > 0 and h > 0 + assert d in [1, 2, 4, 8, 16, 32] + self.width = w + self.height = h + self.depth = d + self.screen = RSDL.SetVideoMode(w, h, 32, 0) + assert self.screen + # self.fillwhite() + + def set_pixelbuffer(self, pixelbuffer): + if self.has_surface: + RSDL.FreeSurface(self.surface) + pitch = 4 * self.width + rmask, gmask, bmask, amask = r_uint(0x000000FF), r_uint(0x0000FF00), r_uint(0x00FF0000), r_uint(0xFF000000) + self.surface = RSDL.CreateRGBSurfaceFrom(pixelbuffer, self.width, self.height, 32, pitch, + rmask, gmask, bmask, amask) + self.has_surface = True + + def fillwhite(self): + fmt = self.screen.c_format + color = RSDL.MapRGB(fmt, 255, 255, 255) + RSDL.FillRect(self.screen, lltype.nullptr(RSDL.Rect), color) + RSDL.Flip(self.screen) + + def blit(self): + RSDL.BlitSurface(self.surface, lltype.nullptr(RSDL.Rect), self.screen, lltype.nullptr(RSDL.Rect)) + RSDL.Flip(self.screen) diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -1,5 +1,5 @@ import py -from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow +from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow, MethodNotFound from spyvm import model, constants, primitives, conftest, wrapper from spyvm.tool.bitmanipulation import splitter @@ -287,9 +287,23 @@ interp._last_indent, w_selector.as_string(), receiver, [self.peek(argcount-1-i) for i in range(argcount)]) assert argcount >= 0 - s_method = receiverclassshadow.lookup(w_selector) - # XXX catch MethodNotFound here and send doesNotUnderstand: - # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. + try: + s_method = receiverclassshadow.lookup(w_selector) + except MethodNotFound: + arguments = self.pop_and_return_n(argcount) + s_message_class = self.space.classtable["w_Message"].as_class_get_shadow(self.space) + w_message = s_message_class.new() + w_message.store(self.space, 0, w_selector) + w_message.store(self.space, 1, self.space.wrap_list(arguments)) + try: + s_method = receiverclassshadow.lookup(self.space.objtable["w_doesNotUnderstand"]) + except MethodNotFound: + print "Missing doesDoesNotUnderstand in hierarchy of %s" % receiverclassshadow.getname() + raise + s_frame = s_method.create_frame(self.space, receiver, [w_message], self) + self.pop() + return interp.stack_frame(s_frame) + code = s_method.primitive() if code: # the primitive pushes the result (if any) onto the stack itself diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -2,9 +2,9 @@ Squeak model. W_Object - W_SmallInteger - W_Float + W_SmallInteger W_AbstractObjectWithIdentityHash + W_Float W_AbstractObjectWithClassReference W_PointersObject W_BytesObject @@ -21,7 +21,9 @@ from rpython.rlib import rrandom, objectmodel, jit from rpython.rlib.rarithmetic import intmask, r_uint from rpython.tool.pairtype import extendabletype -from rpython.rlib.objectmodel import instantiate +from rpython.rlib.objectmodel import instantiate, compute_hash +from rpython.rtyper.lltypesystem import lltype, rffi +from rsdl import RSDL, RSDL_helper class W_Object(object): """Root of Squeak model, abstract.""" @@ -152,7 +154,33 @@ def clone(self, space): return self -class W_Float(W_Object): +class W_AbstractObjectWithIdentityHash(W_Object): + """Object with explicit hash (ie all except small + ints and floats).""" + _attrs_ = ['hash'] + + #XXX maybe this is too extreme, but it's very random + hash_generator = rrandom.Random() + UNASSIGNED_HASH = sys.maxint + + hash = UNASSIGNED_HASH # default value + + def setchar(self, n0, character): + raise NotImplementedError() + + def gethash(self): + if self.hash == self.UNASSIGNED_HASH: + self.hash = hash = intmask(self.hash_generator.genrand32()) // 2 + return hash + return self.hash + + def invariant(self): + return isinstance(self.hash, int) + + def _become(self, w_other): + self.hash, w_other.hash = w_other.hash, self.hash + +class W_Float(W_AbstractObjectWithIdentityHash): """Boxed float value.""" _attrs_ = ['value'] @@ -170,11 +198,15 @@ return space.w_Float def gethash(self): - return 41 # XXX check this + return compute_hash(self.value) def invariant(self): - return self.value is not None # XXX but later: - #return isinstance(self.value, float) + return isinstance(self.value, float) + + def _become(self, w_other): + self.value, w_other.value = w_other.value, self.value + W_AbstractObjectWithIdentityHash._become(self, w_other) + def __repr__(self): return "W_Float(%f)" % self.value @@ -226,33 +258,6 @@ r = ((r >> 32) << 32) | uint self.value = float_unpack(r, 8) - -class W_AbstractObjectWithIdentityHash(W_Object): - """Object with explicit hash (ie all except small - ints and floats).""" - _attrs_ = ['hash'] - - #XXX maybe this is too extreme, but it's very random - hash_generator = rrandom.Random() - UNASSIGNED_HASH = sys.maxint - - hash = UNASSIGNED_HASH # default value - - def setchar(self, n0, character): - raise NotImplementedError() - - def gethash(self): - if self.hash == self.UNASSIGNED_HASH: - self.hash = hash = intmask(self.hash_generator.genrand32()) // 2 - return hash - return self.hash - - def invariant(self): - return isinstance(self.hash, int) - - def _become(self, w_other): - self.hash, w_other.hash = w_other.hash, self.hash - class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash): """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" @@ -523,6 +528,83 @@ w_result.words = list(self.words) return w_result +NATIVE_DEPTH = 32 +class W_DisplayBitmap(W_AbstractObjectWithClassReference): + _attrs_ = ['pixelbuffer', '_depth', '_realsize', 'display'] + _immutable_fields_ = ['_depth', '_realsize', 'display'] + + def __init__(self, w_class, size, depth, display): + W_AbstractObjectWithClassReference.__init__(self, w_class) + assert depth == 1 # XXX: Only support B/W for now + bytelen = NATIVE_DEPTH / depth * size * 4 + self.pixelbuffer = lltype.malloc(rffi.VOIDP.TO, bytelen, flavor='raw') + self._depth = depth + self._realsize = size + self.display = display + + def __del__(self): + lltype.free(self.pixelbuffer, flavor='raw') + + def at0(self, space, index0): + val = self.getword(index0) + return space.wrap_uint(val) + + def atput0(self, space, index0, w_value): + word = space.unwrap_uint(w_value) + self.setword(index0, word) + + # XXX: Only supports 1-bit to 32-bit conversion for now + @jit.unroll_safe + def getword(self, n): + pixel_per_word = NATIVE_DEPTH / self._depth + word = r_uint(0) + pos = n * pixel_per_word * 4 + for i in xrange(32): + word <<= 1 + red = self.pixelbuffer[pos] + if red == '\0': # Black + word |= r_uint(1) + pos += 4 + return word + + @jit.unroll_safe + def setword(self, n, word): + pixel_per_word = NATIVE_DEPTH / self._depth + pos = n * pixel_per_word * 4 + mask = r_uint(1) + mask <<= 31 + for i in xrange(32): + bit = mask & word + if bit == 0: # white + self.pixelbuffer[pos] = '\xff' + self.pixelbuffer[pos + 1] = '\xff' + self.pixelbuffer[pos + 2] = '\xff' + else: + self.pixelbuffer[pos] = '\0' + self.pixelbuffer[pos + 1] = '\0' + self.pixelbuffer[pos + 2] = '\0' + self.pixelbuffer[pos + 3] = '\xff' + mask >>= 1 + pos += 4 + + def flush_to_screen(self): + self.display.blit() + + def size(self): + return self._realsize + + def invariant(self): + return False + + def clone(self, space): + w_result = W_WordsObject(self.w_class, self._realsize) + n = 0 + while n < self._realsize: + w_result.words[n] = self.getword(n) + n += 1 + return w_result + + # XXX Shouldn't compiledmethod have class reference for subclassed compiled # methods? class W_CompiledMethod(W_AbstractObjectWithIdentityHash): diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -87,6 +87,7 @@ define_cls("w_SmallInteger", "w_Integer") define_cls("w_LargePositiveInteger", "w_Integer", format=shadow.BYTES) define_cls("w_Float", "w_Number", format=shadow.BYTES) + define_cls("w_Message", "w_Object") define_cls("w_Collection", "w_Object") define_cls("w_SequenceableCollection", "w_Collection") define_cls("w_ArrayedCollection", "w_SequenceableCollection") @@ -285,6 +286,7 @@ closure.atput0(i0, copiedValues[i0]) return w_closure + def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): from spyvm import model diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -4,6 +4,7 @@ import operator from spyvm import model, shadow from spyvm import constants +from spyvm import display from spyvm.error import PrimitiveFailedError, \ PrimitiveNotYetWrittenError from spyvm import wrapper @@ -523,7 +524,7 @@ INPUT_SEMAPHORE = 93 GET_NEXT_EVENT = 94 INPUT_WORD = 95 -OBSOLETE_INDEXED = 96 +BITBLT_COPY_BITS = 96 # OBSOLETE_INDEXED = 96 SNAPSHOT = 97 STORE_IMAGE_SEGMENT = 98 LOAD_IMAGE_SEGMENT = 99 @@ -531,7 +532,7 @@ BE_CURSOR = 101 BE_DISPLAY = 102 SCAN_CHARACTERS = 103 -# OBSOLETE_INDEXED = 104 # also 96 +OBSOLETE_INDEXED = 104 # also 96 STRING_REPLACE = 105 SCREEN_SIZE = 106 MOUSE_BUTTONS = 107 @@ -543,6 +544,21 @@ def func(interp, s_frame, w_rcvr): raise PrimitiveNotYetWrittenError() + at expose_primitive(BITBLT_COPY_BITS, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15: + raise PrimitiveFailedError + + interp.perform(w_rcvr, "simulateCopyBits") + + w_dest_form = w_rcvr.fetch(interp.space, 0) + if w_dest_form.is_same_object(interp.space.objtable['w_display']): + w_bitmap = w_dest_form.fetch(interp.space, 0) + assert isinstance(w_bitmap, model.W_DisplayBitmap) + w_bitmap.flush_to_screen() + + return w_rcvr + @expose_primitive(BE_CURSOR, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): # TODO: Use info from cursor object. @@ -554,6 +570,39 @@ if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 4: raise PrimitiveFailedError # the fields required are bits (a pointer to a Bitmap), width, height, depth + + # XXX: TODO get the initial image TODO: figure out whether we + # should decide the width an report it in the other SCREEN_SIZE + w_bitmap = w_rcvr.fetch(interp.space, 0) + width = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1)) + height = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2)) + depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3)) + + sdldisplay = None + + w_prev_display = interp.space.objtable['w_display'] + if w_prev_display: + w_prev_bitmap = w_prev_display.fetch(interp.space, 0) + if isinstance(w_prev_bitmap, model.W_DisplayBitmap): + sdldisplay = w_prev_bitmap.display + + if isinstance(w_bitmap, model.W_DisplayBitmap): + assert (sdldisplay is None) or (sdldisplay is w_bitmap.display) + sdldisplay = w_bitmap.display + w_display_bitmap = w_bitmap + else: + assert isinstance(w_bitmap, model.W_WordsObject) + if not sdldisplay: + sdldisplay = display.SDLDisplay() + w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, sdldisplay) + for idx, word in enumerate(w_bitmap.words): + w_display_bitmap.setword(idx, word) + w_rcvr.store(interp.space, 0, w_display_bitmap) + + sdldisplay.set_video_mode(width, height, depth) + sdldisplay.set_pixelbuffer(w_display_bitmap.pixelbuffer) + sdldisplay.blit() + interp.space.objtable['w_display'] = w_rcvr return w_rcvr @@ -658,6 +707,7 @@ VALUE_UNINTERRUPTABLY = 123 LOW_SPACE_SEMAPHORE = 124 SIGNAL_AT_BYTES_LEFT = 125 +DEFER_UPDATES = 126 DRAW_RECTANGLE = 127 @expose_primitive(IMAGE_NAME) @@ -680,8 +730,13 @@ # dont know when the space runs out return w_reciver + at expose_primitive(DEFER_UPDATES, unwrap_spec=[object, object]) +def func(interp, s_frame, w_receiver, w_bool): + raise PrimitiveNotYetWrittenError() + @expose_primitive(DRAW_RECTANGLE, unwrap_spec=[object, int, int, int, int]) def func(interp, s_frame, w_rcvr, left, right, top, bottom): + # import pdb; pdb.set_trace() raise PrimitiveNotYetWrittenError() @@ -1135,6 +1190,21 @@ CTXT_SIZE = 212 # ___________________________________________________________________________ +# Drawing + +FORCE_DISPLAY_UPDATE = 231 + + at expose_primitive(FORCE_DISPLAY_UPDATE, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + w_prev_display = interp.space.objtable['w_display'] + assert w_prev_display + w_prev_bitmap = w_prev_display.fetch(interp.space, 0) + assert isinstance(w_prev_bitmap, model.W_DisplayBitmap) + w_prev_bitmap.flush_to_screen() + return w_rcvr + + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -72,7 +72,6 @@ WEAK_POINTERS = 3 COMPILED_METHOD = 4 FLOAT = 5 -DISPLAY_SCREEN = 6 class MethodNotFound(error.SmalltalkException): pass @@ -790,8 +789,11 @@ return 0 def short_str(self): - return 'BlockContext of %s (%i)' % (self.w_method().get_identifier_string(), - self.pc() + 1) + return 'BlockContext of %s (%s) [%i]' % ( + self.w_method().get_identifier_string(), + self.w_receiver(), + self.pc() + 1 + ) class MethodContextShadow(ContextPartShadow): _attr_ = ['w_closure_or_nil', '_w_receiver', '__w_method'] @@ -937,7 +939,12 @@ def short_str(self): block = '[] of' if self.is_closure_context() else '' - return '%s %s (%i)' % (block, self.w_method().get_identifier_string(), self.pc() + 1) + return '%s %s (%s) [%i]' % ( + block, + self.w_method().get_identifier_string(), + self.w_receiver(), + self.pc() + 1 + ) class CompiledMethodShadow(object): _attr_ = ["_w_self", "bytecode", @@ -1031,6 +1038,7 @@ def update(self): pass + class ObserveeShadow(AbstractShadow): _attr_ = ['dependent'] def __init__(self, space, w_self): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -47,9 +47,9 @@ def test_read_header(): reader = open_miniimage(space) reader.read_header() - assert reader.endofmemory == 655196 - assert reader.oldbaseaddress == -1220960256 - assert reader.specialobjectspointer == -1220832384 + assert reader.endofmemory == 726592 + assert reader.oldbaseaddress == -1221464064 + assert reader.specialobjectspointer == -1221336216 def test_read_all_header(): reader = open_miniimage(space) @@ -113,8 +113,8 @@ def test_special_classes0(): image = get_image() - w = image.special(constants.SO_BITMAP_CLASS) - assert str(w) == "Bitmap class" + # w = image.special(constants.SO_BITMAP_CLASS) + # assert str(w) == "Bitmap class" w = image.special(constants.SO_SMALLINTEGER_CLASS) assert str(w) == "SmallInteger class" w = image.special(constants.SO_STRING_CLASS) @@ -131,6 +131,8 @@ assert str(w) == "Point class" w = image.special(constants.SO_LARGEPOSITIVEINTEGER_CLASS) assert str(w) == "LargePositiveInteger class" + w = image.special(constants.SO_MESSAGE_CLASS) + assert str(w) == "Message class" # to be continued @@ -154,7 +156,7 @@ assert repr(space.w_true.shadow_of_my_class(space)) == "" assert repr(space.w_false.shadow_of_my_class(space)) == "" -def test_special_classes0(): +def test_special_objects0(): image = get_image() w = image.special(constants.SO_DOES_NOT_UNDERSTAND) assert str(w) == "doesNotUnderstand:" @@ -348,3 +350,24 @@ w_result = perform(interp.space.w_Float, "new") assert w_result is not None assert isinstance(w_result, model.W_Float) + +def test_doesNotUnderstand(): + w_dnu = interp.space.objtable["w_doesNotUnderstand"] + assert isinstance(w_dnu, model.W_BytesObject) + assert w_dnu.as_string() == "doesNotUnderstand:" + +def test_run_doesNotUnderstand(): + from spyvm.test import test_miniimage + setup_module(test_miniimage, filename='running-something-mini.image') + w_result = test_miniimage.interp.perform(test_miniimage.interp.space.wrap_int(0), "runningADNU") + assert isinstance(w_result, model.W_BytesObject) + assert w_result.as_string() == "foobarThis:doesNotExist:('pypy' 'heya' )" + +def test_Message(): + w_message_cls = interp.space.w_Message + assert w_message_cls is interp.space.classtable["w_Message"] + assert isinstance(w_message_cls, model.W_PointersObject) + s_message_cls = w_message_cls.as_class_get_shadow(interp.space) + assert s_message_cls.getname() == "Message class" + w_message = s_message_cls.new() + assert isinstance(w_message, model.W_PointersObject) diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -260,3 +260,32 @@ assert math.isnan(target.value) else: assert target.value == f + +def test_float_hash(): + target = model.W_Float(1.1) + assert target.gethash() == model.W_Float(1.1).gethash() + target.store(space, 0, space.wrap_int(42)) + assert target.gethash() != model.W_Float(1.1).gethash() + +def test_display_bitmap(): + target = model.W_DisplayBitmap(space.w_Array, 100, 1, None) + target.setword(0, 0xFF00) + assert bin(target.getword(0)) == bin(0xFF00) + target.setword(0, 0x00FF00FF) + assert bin(target.getword(0)) == bin(0x00FF00FF) + target.setword(0, 0xFF00FF00) + assert bin(target.getword(0)) == bin(0xFF00FF00) + for i in xrange(32): + if (i + 1) % 4 == 0: + assert target.pixelbuffer[i] == "\xff" + else: + assert target.pixelbuffer[i] == "\x00" + for i in xrange(32, 64): + assert target.pixelbuffer[i] == "\xff" + for i in xrange(64, 96): + if (i + 1) % 4 == 0: + assert target.pixelbuffer[i] == "\xff" + else: + assert target.pixelbuffer[i] == "\x00" + for i in xrange(96, 128): + assert target.pixelbuffer[i] == "\xff" diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -3,7 +3,7 @@ import math from spyvm.primitives import prim_table, PrimitiveFailedError from spyvm import model, shadow, interpreter -from spyvm import constants, primitives, objspace, wrapper +from spyvm import constants, primitives, objspace, wrapper, display from rpython.rlib.rfloat import INFINITY, NAN, isinf, isnan @@ -610,6 +610,80 @@ assert w_2.getclass(space) is space.w_Array assert w_1 is not w_2 +def test_primitive_be_display(): + assert space.objtable["w_display"] is None + mock_display = model.W_PointersObject(space.w_Point, 4) + w_wordbmp = model.W_WordsObject(space.w_Array, 100) + mock_display.store(space, 0, w_wordbmp) # bitmap + mock_display.store(space, 1, space.wrap_int(32)) # width + mock_display.store(space, 2, space.wrap_int(10)) # height + mock_display.store(space, 3, space.wrap_int(1)) # depth + prim(primitives.BE_DISPLAY, [mock_display]) + assert space.objtable["w_display"] is mock_display + w_bitmap = mock_display.fetch(space, 0) + assert w_bitmap is not w_wordbmp + assert isinstance(w_bitmap, model.W_DisplayBitmap) + sdldisplay = w_bitmap.display + assert isinstance(sdldisplay, display.SDLDisplay) + + mock_display2 = model.W_PointersObject(space.w_Point, 4) + mock_display2.store(space, 0, model.W_WordsObject(space.w_Array, 100)) # bitmap + mock_display2.store(space, 1, space.wrap_int(32)) # width + mock_display2.store(space, 2, space.wrap_int(10)) # height + mock_display2.store(space, 3, space.wrap_int(1)) # depth + prim(primitives.BE_DISPLAY, [mock_display2]) + assert space.objtable["w_display"] is mock_display2 + w_bitmap2 = mock_display.fetch(space, 0) + assert isinstance(w_bitmap2, model.W_DisplayBitmap) + assert w_bitmap.display is w_bitmap2.display + assert sdldisplay.width == 32 + assert sdldisplay.height == 10 + + prim(primitives.BE_DISPLAY, [mock_display]) + assert space.objtable["w_display"] is mock_display + assert mock_display.fetch(space, 0) is w_bitmap + +def test_primitive_force_display_update(monkeypatch): + mock_display = model.W_PointersObject(space.w_Point, 4) + w_wordbmp = model.W_WordsObject(space.w_Array, 100) + mock_display.store(space, 0, w_wordbmp) # bitmap + mock_display.store(space, 1, space.wrap_int(32)) # width + mock_display.store(space, 2, space.wrap_int(10)) # height + mock_display.store(space, 3, space.wrap_int(1)) # depth + prim(primitives.BE_DISPLAY, [mock_display]) + + class DisplayFlush(Exception): + pass + + def flush_to_screen_mock(): + raise DisplayFlush + + try: + monkeypatch.setattr(mock_display.fetch(space, 0), "flush_to_screen", flush_to_screen_mock) + with py.test.raises(DisplayFlush): + prim(primitives.FORCE_DISPLAY_UPDATE, [mock_display]) + finally: + monkeypatch.undo() + +def test_bitblt_copy_bits(monkeypatch): + class CallCopyBitsSimulation(Exception): + pass + + mock_bitblt = model.W_PointersObject(space.w_Point, 15) + + def perform_mock(w_rcvr, string): + if w_rcvr is mock_bitblt and string == "simulateCopyBits": + raise CallCopyBitsSimulation + + interp, w_frame, argument_count = mock([mock_bitblt], None) + + try: + monkeypatch.setattr(interp, "perform", perform_mock) + with py.test.raises(CallCopyBitsSimulation): + prim_table[primitives.BITBLT_COPY_BITS](interp, w_frame.as_context_get_shadow(space), argument_count-1) + finally: + monkeypatch.undo() + # Note: # primitives.NEXT is unimplemented as it is a performance optimization # primitives.NEXT_PUT is unimplemented as it is a performance optimization @@ -619,4 +693,3 @@ # primitives.VALUE_WITH_ARGS is tested in test_interpreter # primitives.OBJECT_AT is tested in test_interpreter # primitives.OBJECT_AT_PUT is tested in test_interpreter - From noreply at buildbot.pypy.org Mon Mar 18 15:33:41 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Mon, 18 Mar 2013 15:33:41 +0100 (CET) Subject: [pypy-commit] pypy default: add an assert to the object list strategy that it is not switching to itself. Message-ID: <20130318143341.E07B71C0084@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62398:51ddba03aa92 Date: 2013-03-18 15:31 +0100 http://bitbucket.org/pypy/pypy/changeset/51ddba03aa92/ Log: add an assert to the object list strategy that it is not switching to itself. This assert failed when going via the generic setitem_str, which I also fixed. diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -565,6 +565,12 @@ def w_keys(self, w_dict): return self.space.newlist(self.unerase(w_dict.dstorage).keys()) + def setitem_str(self, w_dict, s, w_value): + self.setitem(w_dict, self.space.wrap(s), w_value) + + def switch_to_object_strategy(self, w_dict): + assert 0, "should be unreachable" + create_iterator_classes(ObjectDictStrategy) class StringDictStrategy(AbstractTypedStrategy, DictStrategy): From noreply at buildbot.pypy.org Mon Mar 18 17:16:16 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 18 Mar 2013 17:16:16 +0100 (CET) Subject: [pypy-commit] pypy default: for the series "how could this have ever worked?": distutils.unixcompiler needs to know the CC to determine the correct linker parameters Message-ID: <20130318161616.056811C131F@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62399:173c519a85ce Date: 2013-03-18 16:16 +0000 http://bitbucket.org/pypy/pypy/changeset/173c519a85ce/ Log: for the series "how could this have ever worked?": distutils.unixcompiler needs to know the CC to determine the correct linker parameters diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -61,6 +61,7 @@ g['SO'] = _get_so_extension() or ".so" g['SOABI'] = g['SO'].rsplit('.')[0] g['LIBDIR'] = os.path.join(sys.prefix, 'lib') + g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check global _config_vars _config_vars = g From noreply at buildbot.pypy.org Mon Mar 18 17:32:57 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 17:32:57 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: add developer names Message-ID: <20130318163257.156531C13FB@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: extradoc Changeset: r4961:8f374c5de87a Date: 2013-03-18 09:32 -0700 http://bitbucket.org/pypy/extradoc/changeset/8f374c5de87a/ Log: add developer names diff --git a/blog/draft/numpy-status-update-6.rst b/blog/draft/numpy-status-update-6.rst --- a/blog/draft/numpy-status-update-6.rst +++ b/blog/draft/numpy-status-update-6.rst @@ -13,7 +13,7 @@ complete set of attributes on ndarrays. We are progressing alphabetically, and have made it to d. Unsupported attributes, and unsupported arguments to attribute calls - will raise a NotImplementedException. + will raise a NotImplementedError. * **pickling support for numarray** - hasn't started yet, but next on the list @@ -29,7 +29,7 @@ While our funding drive over 2012 did not reach our goal, we still managed to raise a fair amount of money in donations. So far we only managed to spend around $10 000 of it. -We issued a call for additional developers, and are glad to welcome ___________ +We issued a call for additional developers, and are glad to welcome Romain Guillebert and Ronan Lamy to the numpypy team. Hopefully we will be able to report on speedier progress soon. Cheers, From noreply at buildbot.pypy.org Mon Mar 18 18:17:15 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Mar 2013 18:17:15 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: add input primitives, using a bad queue for now. this'll go away once we get the SDL event queue working with this. Message-ID: <20130318171715.79C841C0084@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r213:8a4ae64a404c Date: 2013-03-18 18:16 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8a4ae64a404c/ Log: add input primitives, using a bad queue for now. this'll go away once we get the SDL event queue working with this. diff --git a/spyvm/display.py b/spyvm/display.py --- a/spyvm/display.py +++ b/spyvm/display.py @@ -1,15 +1,54 @@ from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rlib.runicode import unicode_encode_utf_8 from rsdl import RSDL, RSDL_helper +class SDLEventQueue(object): + def __init__(self, default, maxlen=10): + assert default + self.default = default + self.ary = [] + self.maxlen = 10 + + def push(self, event): + if len(self.ary) == self.maxlen: + self.ary.pop(0) + self.ary.append(event) + + def shift(self): + if not self.ary: + self.ary += self.default + return self.ary.pop(0) + + def peek(self): + if self.ary: + return self.ary[0] + else: + return self.default[0] + + def size(self): + if not self.ary: + return len(self.default) + else: + return len(self.ary) + + class SDLDisplay(object): - _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface"] + _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface", + "last_mouse_position", "mouse_downs", "mouse_ups", "key_ups", "key_downs"] - def __init__(self): + def __init__(self, title): assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 + RSDL.WM_SetCaption(title, "RSqueakVM") + RSDL.EnableUNICODE(1) self.has_surface = False + self.last_mouse_position = [0, 0] + self.mouse_downs = SDLEventQueue([0]) + self.mouse_ups = SDLEventQueue([0]) + self.key_ups = SDLEventQueue([0]) + self.key_downs = SDLEventQueue([0]) def set_video_mode(self, w, h, d): assert w > 0 and h > 0 @@ -39,3 +78,58 @@ def blit(self): RSDL.BlitSurface(self.surface, lltype.nullptr(RSDL.Rect), self.screen, lltype.nullptr(RSDL.Rect)) RSDL.Flip(self.screen) + + def get_next_event(self): + event = lltype.malloc(RSDL.Event, flavor="raw") + ok = 1 + try: + while ok == 1: + ok = rffi.cast(lltype.Signed, RSDL.PollEvent(event)) + if ok == 1: + c_type = rffi.getintfield(event, 'c_type') + if c_type == RSDL.MOUSEBUTTONDOWN or c_type == RSDL.MOUSEBUTTONUP: + b = rffi.cast(RSDL.MouseButtonEventPtr, event) + btn = rffi.getintfield(b, 'c_button') + if btn == RSDL.BUTTON_LEFT: + btn = 1 + elif btn == RSDL.BUTTON_MIDDLE: + btn = 2 + elif btn == RSDL.BUTTON_RIGHT: + btn = 4 + + if c_type == RSDL.MOUSEBUTTONDOWN: + self.mouse_downs.push(btn) + else: + self.mouse_ups.push(btn) + elif c_type == RSDL.MOUSEMOTION: + m = rffi.cast(RSDL.MouseMotionEventPtr, event) + x = rffi.getintfield(m, "c_x") + y = rffi.getintfield(m, "c_y") + self.last_mouse_position = [x, y] + elif c_type == RSDL.KEYUP or c_type == RSDL.KEYDOWN: + p = rffi.cast(RSDL.KeyboardEventPtr, event) + char = rffi.getintfield(p.c_keysym, 'c_unicode') + if char != 0: + for c in unicode_encode_utf_8(unichr(char), 1, "ignore"): + if c_type == RSDL.KEYUP: + self.key_ups.push(ord(c)) + else: + self.key_downs.push(ord(c)) + finally: + lltype.free(event, flavor='raw') + + def mouse_point(self): + self.get_next_event() + return self.last_mouse_position + + def mouse_button(self): + self.get_next_event() + return self.mouse_ups.shift() + + def next_keycode(self): + self.get_next_event() + return self.key_downs.shift() + + def peek_keycode(self): + self.get_next_event() + return self.key_downs.peek() diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,5 +1,5 @@ from spyvm import constants, model, shadow, wrapper -from spyvm.error import UnwrappingError, WrappingError +from spyvm.error import UnwrappingError, WrappingError, PrimitiveFailedError from rpython.rlib.objectmodel import instantiate, specialize from rpython.rlib.rarithmetic import intmask, r_uint, int_between @@ -270,7 +270,15 @@ assert isinstance(w_array, model.W_PointersObject) return [w_array.at0(self, i) for i in range(w_array.size())] - + + def get_display(self): + w_display = self.objtable['w_display'] + if w_display: + w_bitmap = w_display.fetch(self, 0) + if isinstance(w_bitmap, model.W_DisplayBitmap): + return w_bitmap.display + raise PrimitiveFailedError() + def _freeze_(self): return True diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -540,6 +540,14 @@ KBD_PEEK = 109 + at expose_primitive(MOUSE_POINT, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + x, y = interp.space.get_display().mouse_point() + w_point = model.W_PointersObject(interp.space.w_Point, 2) + w_point.store(interp.space, 0, interp.space.wrap_int(x)) + w_point.store(interp.space, 1, interp.space.wrap_int(y)) + return w_point + @expose_primitive(GET_NEXT_EVENT, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): raise PrimitiveNotYetWrittenError() @@ -593,7 +601,7 @@ else: assert isinstance(w_bitmap, model.W_WordsObject) if not sdldisplay: - sdldisplay = display.SDLDisplay() + sdldisplay = display.SDLDisplay(interp.image_name) w_display_bitmap = model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth, sdldisplay) for idx, word in enumerate(w_bitmap.words): w_display_bitmap.setword(idx, word) @@ -630,7 +638,6 @@ w_rcvr.atput0(interp.space, i0, w_replacement.at0(interp.space, repOff + i0)) return w_rcvr - @expose_primitive(SCREEN_SIZE, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): # XXX get the real screen size @@ -640,6 +647,20 @@ point.store_y(480) return w_res + at expose_primitive(MOUSE_BUTTONS, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + btn = interp.space.get_display().mouse_button() + return interp.space.wrap_int(btn) + + at expose_primitive(KBD_NEXT, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + return interp.space.wrap_int(interp.space.get_display().next_keycode()) + + at expose_primitive(KBD_PEEK, unwrap_spec=[object]) +def func(interp, s_frame, w_rcvr): + return interp.space.wrap_int(interp.space.get_display().peek_keycode()) + + # ___________________________________________________________________________ # Control Primitives From noreply at buildbot.pypy.org Mon Mar 18 19:50:49 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 19:50:49 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: seperate jit merge points, fix 'whoops' in indexing Message-ID: <20130318185049.0D4611C0084@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62400:173bb0fa22cf Date: 2013-03-18 10:10 -0700 http://bitbucket.org/pypy/pypy/changeset/173bb0fa22cf/ Log: seperate jit merge points, fix 'whoops' in indexing 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 @@ -79,18 +79,11 @@ source_iter = source.create_iter(shape) dtype = target.dtype shapelen = len(shape) - if dtype.is_str_or_unicode(): - while not target_iter.done(): - setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) - target_iter.setitem(dtype.convert_from(space, source_iter.getitem())) - target_iter.next() - source_iter.next() - else: - while not target_iter.done(): - setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) - target_iter.setitem(source_iter.getitem().convert_to(dtype)) - target_iter.next() - source_iter.next() + while not target_iter.done(): + setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(source_iter.getitem().convert_to(dtype)) + target_iter.next() + source_iter.next() return target reduce_driver = jit.JitDriver(name='numpy_reduce', 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 @@ -1643,7 +1643,7 @@ @jit.unroll_safe def store(self, arr, i, offset, box): assert isinstance(box, interp_boxes.W_StringBox) - for k in range(min(self.size - i, box.arr.size-offset)): + for k in range(min(self.size, box.arr.size-offset)): arr.storage[k + i] = box.arr.storage[k + offset] def read(self, arr, i, offset, dtype=None): From noreply at buildbot.pypy.org Mon Mar 18 19:50:50 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 19:50:50 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: fix nd array indexing with a lower dimensional array Message-ID: <20130318185050.489121C0084@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: indexing-by-array Changeset: r62401:1f15361645b3 Date: 2013-03-18 11:35 -0700 http://bitbucket.org/pypy/pypy/changeset/1f15361645b3/ Log: fix nd array indexing with a lower dimensional array diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -79,7 +79,8 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - res = W_NDimArray.from_shape([size], self.get_dtype()) + res_shape = [size] + self.get_shape()[1:] + res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) def setitem_filter(self, space, idx, val): 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 @@ -300,13 +300,14 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter() + index_iter = index.create_iter(arr.get_shape()) arr_iter = arr.create_iter() shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? while not index_iter.done(): + print 'res,arr,index', res_iter.get_index(), arr.get_index(), index.get_index() getitem_filter_driver.jit_merge_point(shapelen=shapelen, index_dtype=index_dtype, arr_dtype=arr_dtype, 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 @@ -1595,7 +1595,7 @@ assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): - from numpypy import array, arange, zeros + from numpypy import arange, zeros a = arange(10) a[[3, 2, 1, 5]] = zeros(4, dtype=int) assert (a == [0, 0, 0, 0, 4, 0, 6, 7, 8, 9]).all() @@ -1610,6 +1610,10 @@ assert (b[array([True, False, True])] == [0, 2]).all() raises(ValueError, "array([1, 2])[array([True, True, True])]") raises(ValueError, "b[array([[True, False], [True, False]])]") + a = array([[1,2,3],[4,5,6],[7,8,9]],int) + c = array([True,False,True],bool) + b = a[c] + assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): from numpypy import arange, array From noreply at buildbot.pypy.org Mon Mar 18 19:50:51 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 19:50:51 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: wip Message-ID: <20130318185051.7C26F1C0084@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: indexing-by-array Changeset: r62402:47a587edf829 Date: 2013-03-18 11:49 -0700 http://bitbucket.org/pypy/pypy/changeset/47a587edf829/ Log: wip 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 @@ -307,7 +307,7 @@ index_dtype = index.get_dtype() # XXX length of shape of index as well? while not index_iter.done(): - print 'res,arr,index', res_iter.get_index(), arr.get_index(), index.get_index() + print 'res,arr,index', res_iter.offset, arr_iter.offset, index_iter.offset, index_iter.getitem_bool() getitem_filter_driver.jit_merge_point(shapelen=shapelen, index_dtype=index_dtype, arr_dtype=arr_dtype, 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 @@ -1612,7 +1612,9 @@ raises(ValueError, "b[array([[True, False], [True, False]])]") a = array([[1,2,3],[4,5,6],[7,8,9]],int) c = array([True,False,True],bool) + print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' b = a[c] + print 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy' assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): @@ -2064,7 +2066,6 @@ assert isinstance(i['data'][0], int) def test_array_indexing_one_elem(self): - skip("not yet") from numpypy import array, arange raises(IndexError, 'arange(3)[array([3.5])]') a = arange(3)[array([1])] From noreply at buildbot.pypy.org Mon Mar 18 21:15:57 2013 From: noreply at buildbot.pypy.org (taavi_burns) Date: Mon, 18 Mar 2013 21:15:57 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Adds instrumentation to transaction.py to report on the number of transactions run during a call to run(). Message-ID: <20130318201557.809931C00E4@cobra.cs.uni-duesseldorf.de> Author: Taavi Burns Branch: stm-thread-2 Changeset: r62403:7a29f5163381 Date: 2013-03-18 16:13 -0400 http://bitbucket.org/pypy/pypy/changeset/7a29f5163381/ Log: Adds instrumentation to transaction.py to report on the number of transactions run during a call to run(). diff --git a/lib_pypy/pypy_test/test_transaction.py b/lib_pypy/pypy_test/test_transaction.py --- a/lib_pypy/pypy_test/test_transaction.py +++ b/lib_pypy/pypy_test/test_transaction.py @@ -76,6 +76,21 @@ assert num_foos == 1, lsts +def test_number_of_transactions_reported(): + transaction.add(lambda: None) + transaction.run() + assert transaction.number_of_transactions_in_last_run() == 1 + + def add_transactions(l): + if l: + for x in range(l[0]): + transaction.add(add_transactions, l[1:]) + + transaction.add(add_transactions, [10, 10, 10]) + transaction.run() + assert transaction.number_of_transactions_in_last_run() == 1111 + + def run_tests(): for name in sorted(globals().keys()): if name.startswith('test_'): diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -96,6 +96,9 @@ tpool.teardown() tpool.reraise() +def number_of_transactions_in_last_run(): + return _thread_pool.transactions_run + # ____________________________________________________________ @@ -104,6 +107,7 @@ def __init__(self): self.num_threads = 4 # XXX default value, tweak self.in_transaction = False + self.transactions_run = None def setup(self): # a mutex to protect parts of _grab_next_thing_to_do() @@ -122,17 +126,20 @@ _thread_local.pending = None # self.num_waiting_threads = 0 + self.transactions_run = 0 self.finished = False self.got_exception = [] self.in_transaction = True def run(self): # start the N threads - for i in range(self.num_threads): - thread.start_new_thread(self._run_thread, ()) + task_counters = [[0] for i in range(self.num_threads)] + for counter in task_counters: + thread.start_new_thread(self._run_thread, (counter,)) # now wait. When we manage to acquire the following lock, then # we are finished. self.lock_if_released_then_finished.acquire() + self.transactions_run = sum(x[0] for x in task_counters) def teardown(self): self.in_transaction = False @@ -148,13 +155,14 @@ if exc: raise exc[0], exc[1], exc[2] # exception, value, traceback - def _run_thread(self): + def _run_thread(self, counter): tloc_pending = _thread_local.pending got_exception = self.got_exception try: while True: self._do_it(self._grab_next_thing_to_do(tloc_pending), got_exception) + counter[0] += 1 except _Done: pass From noreply at buildbot.pypy.org Mon Mar 18 21:21:33 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 21:21:33 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: add broadcast_backwards to allow indexing by a lower-shaped array Message-ID: <20130318202133.D192F1C0084@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: indexing-by-array Changeset: r62404:7f18238a3962 Date: 2013-03-18 12:47 -0700 http://bitbucket.org/pypy/pypy/changeset/7f18238a3962/ Log: add broadcast_backwards to allow indexing by a lower-shaped array diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -294,12 +294,12 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is None or shape == self.get_shape(): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, backward_broadcast) return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): @@ -362,11 +362,12 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, + backward_broadcast) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -224,9 +224,10 @@ s.append('])') return s.build() - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseArrayImplementation) - return self.implementation.create_iter(shape) + return self.implementation.create_iter(shape, + backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) 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 @@ -300,14 +300,13 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter(arr.get_shape()) + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) arr_iter = arr.create_iter() shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? while not index_iter.done(): - print 'res,arr,index', res_iter.offset, arr_iter.offset, index_iter.offset, index_iter.getitem_bool() getitem_filter_driver.jit_merge_point(shapelen=shapelen, index_dtype=index_dtype, arr_dtype=arr_dtype, diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -40,7 +40,7 @@ rshape += shape[s:] return rshape, rstart, rstrides, rbackstrides -def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape): +def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape, backwards=False): rstrides = [] rbackstrides = [] for i in range(len(orig_shape)): @@ -50,8 +50,12 @@ else: rstrides.append(strides[i]) rbackstrides.append(backstrides[i]) - rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides - rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides + if backwards: + rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape)) + rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape)) + else: + rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides + rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides return rstrides, rbackstrides def is_single_elem(space, w_elem, is_rec_type): 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 @@ -1612,9 +1612,7 @@ raises(ValueError, "b[array([[True, False], [True, False]])]") a = array([[1,2,3],[4,5,6],[7,8,9]],int) c = array([True,False,True],bool) - print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' b = a[c] - print 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy' assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): From noreply at buildbot.pypy.org Mon Mar 18 21:21:35 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 21:21:35 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: tests segfault Message-ID: <20130318202135.16DBB1C0084@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: indexing-by-array Changeset: r62405:2688a8fd8e04 Date: 2013-03-18 13:21 -0700 http://bitbucket.org/pypy/pypy/changeset/2688a8fd8e04/ Log: tests segfault diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -38,7 +38,7 @@ def get_strides(self): return [] - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) def get_scalar_value(self): diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -19,7 +19,7 @@ def get_shape(self): return self.shape - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.base(), W_NDimArray) return self.base().create_iter() diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -79,7 +79,12 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - res_shape = [size] + self.get_shape()[1:] + print 'size',size + if len(arr.get_shape()) == 1: + res_shape = [size] + self.get_shape()[1:] + else: + res_shape = [size] + print 'res_shape',res_shape res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) 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 @@ -300,7 +300,9 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + print 'xxx' + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=False) + print 'yyy' arr_iter = arr.create_iter() shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() @@ -311,6 +313,7 @@ index_dtype=index_dtype, arr_dtype=arr_dtype, ) + print 'res,arr,index', res_iter.offset, arr_iter.offset, index_iter.offset, index_iter.getitem_bool() if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() 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 @@ -1595,7 +1595,7 @@ assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): - from numpypy import arange, zeros + from numpypy import arange, zeros, array a = arange(10) a[[3, 2, 1, 5]] = zeros(4, dtype=int) assert (a == [0, 0, 0, 0, 4, 0, 6, 7, 8, 9]).all() @@ -2155,15 +2155,26 @@ def test_compress(self): from numpypy import arange, array a = arange(10) + print 0 assert (a.compress([True, False, True]) == [0, 2]).all() + print 1 assert (a.compress([1, 0, 13]) == [0, 2]).all() + print 2 + assert (a.compress([1, 0, 13]) == [0, 2]).all() + print '2a' assert (a.compress([1, 0, 13.5]) == [0, 2]).all() + print 3 assert (a.compress(array([1, 0, 13.5], dtype='>f4')) == [0, 2]).all() + print 4 assert (a.compress(array([1, 0, 13.5], dtype=' Author: Matti Picus Branch: indexing-by-array Changeset: r62406:628865d8e981 Date: 2013-03-18 13:36 -0700 http://bitbucket.org/pypy/pypy/changeset/628865d8e981/ Log: wip 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 @@ -300,9 +300,9 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - print 'xxx' - index_iter = index.create_iter(arr.get_shape(), backward_broadcast=False) - print 'yyy' + print 'index.size', index.get_size() + print 'res.size', res.get_size() + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) arr_iter = arr.create_iter() shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() From noreply at buildbot.pypy.org Mon Mar 18 22:06:51 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 22:06:51 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: broadcast only when needed, fix compress for nd array with no axis arg (rguillebert, mattip) Message-ID: <20130318210651.B852E1C131F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: indexing-by-array Changeset: r62407:fc9348336eda Date: 2013-03-18 14:04 -0700 http://bitbucket.org/pypy/pypy/changeset/fc9348336eda/ Log: broadcast only when needed, fix compress for nd array with no axis arg (rguillebert, mattip) diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -79,12 +79,10 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - print 'size',size if len(arr.get_shape()) == 1: res_shape = [size] + self.get_shape()[1:] else: res_shape = [size] - print 'res_shape',res_shape res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) @@ -369,8 +367,11 @@ if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for compress")) + arr = self + else: + arr = self.descr_reshape(space, [space.wrap(-1)]) index = convert_to_array(space, w_obj) - return self.getitem_filter(space, index) + return arr.getitem_filter(space, index) def descr_flatten(self, space, w_order=None): if self.is_scalar(): 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 @@ -300,11 +300,12 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - print 'index.size', index.get_size() - print 'res.size', res.get_size() - index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + shapelen = len(arr.get_shape()) + if shapelen > 1 and len(index.get_shape()) < 2: + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + else: + index_iter = index.create_iter() arr_iter = arr.create_iter() - shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? @@ -313,7 +314,6 @@ index_dtype=index_dtype, arr_dtype=arr_dtype, ) - print 'res,arr,index', res_iter.offset, arr_iter.offset, index_iter.offset, index_iter.getitem_bool() if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() 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 @@ -2155,26 +2155,16 @@ def test_compress(self): from numpypy import arange, array a = arange(10) - print 0 assert (a.compress([True, False, True]) == [0, 2]).all() - print 1 assert (a.compress([1, 0, 13]) == [0, 2]).all() - print 2 assert (a.compress([1, 0, 13]) == [0, 2]).all() - print '2a' assert (a.compress([1, 0, 13.5]) == [0, 2]).all() - print 3 assert (a.compress(array([1, 0, 13.5], dtype='>f4')) == [0, 2]).all() - print 4 assert (a.compress(array([1, 0, 13.5], dtype=' Author: Wim Lavrijsen Branch: fast-newarray Changeset: r62408:4b24eca3babc Date: 2013-03-18 13:40 -0700 http://bitbucket.org/pypy/pypy/changeset/4b24eca3babc/ Log: (fijal, wlav) in-progress malloc_varsize 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 @@ -145,6 +145,7 @@ gcrootmap = None passes_frame = True write_barrier_descr = None + max_size_of_young_obj = 50 def __init__(self, callback): GcLLDescription.__init__(self, None) @@ -244,6 +245,29 @@ # slowpath never called assert gc_ll_descr.calls == [] + def test_malloc_nursery_varsize(self): + self.cpu = self.getcpu(None) + ops = ''' + [i0, i1, i2] + p0 = call_malloc_nursery_varsize(8, i0) + p1 = call_malloc_nursery_varsize(5, i1) + p2 = call_malloc_nursery_varsize(7, i2) + guard_true(i0) [p0, p1, p2] + ''' + self.interpret(ops, [1, 2, 3]) + # check the returned pointers + gc_ll_descr = self.cpu.gc_ll_descr + nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) + ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) + assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 + assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 2*WORD + 8*1 + assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 2*WORD + 8*1 + 2*WORD + 5*2 + # check the nursery content and state + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.addrs[0] == nurs_adr + 64 + # slowpath never called + assert gc_ll_descr.calls == [] + def test_malloc_slowpath(self): def check(frame): expected_size = 1 @@ -664,9 +688,6 @@ assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame - def test_malloc_nursery_varsize(self): - xxx - def test_call_release_gil(self): # note that we can't test floats here because when untranslated # people actually wreck xmm registers diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2460,6 +2460,31 @@ self.mc.overwrite(jmp_adr-1, chr(offset)) self.mc.MOV(heap(nursery_free_adr), edi) + def malloc_cond_varsize(self, nursery_free_adr, nursery_top_adr, + lengthloc, itemsize, maxlength, gcmap): + self.mc.CMP(lengthloc, imm(maxlength)) + self.mc.J_il8(rx86.Conditions['L'], 0) # patched later + jmp_adr0 = self.mc.get_relative_pos() + self.mc.MOV(edi, heap(nursery_free_adr)) + self.mc.MOV(eax, edi) + self.mc.MOV(edi, lengthloc) + self.mc.IMUL(edi, imm(itemsize)) + self.mc.ADD(edi, eax) + self.mc.ADD(edi, imm(WORD * 2)) + self.mc.CMP(edi, heap(nursery_top_adr)) + self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later + jmp_adr1 = self.mc.get_relative_pos() + offset = self.mc.get_relative_pos() - jmp_adr0 + assert 0 < offset <= 127 + self.mc.overwrite(jmp_adr0-1, chr(offset)) + # save the gcmap + self.push_gcmap(self.mc, gcmap, mov=True) + self.mc.CALL(imm(0)) + offset = self.mc.get_relative_pos() - jmp_adr1 + assert 0 < offset <= 127 + self.mc.overwrite(jmp_adr1-1, chr(offset)) + self.mc.MOV(heap(nursery_free_adr), edi) + def force_token(self, reg): # XXX kill me assert isinstance(reg, RegLoc) 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 @@ -870,6 +870,28 @@ gc_ll_descr.get_nursery_top_addr(), sizeloc, gcmap) + def consider_call_malloc_nursery_varsize(self, op): + length_box = op.getarg(1) + assert isinstance(length_box, BoxInt) # we cannot have a const here! + # looking at the result + self.rm.force_allocate_reg(op.result, selected_reg=eax) + # + # We need edx as a temporary, but otherwise don't save any more + # register. See comments in _build_malloc_slowpath(). + tmp_box = TempBox() + self.rm.force_allocate_reg(tmp_box, selected_reg=edi) + lengthloc = self.rm.make_sure_var_in_reg(length_box, [op.result, tmp_box]) + gcmap = self.get_gcmap([eax, edi]) # allocate the gcmap *before* + self.rm.possibly_free_var(tmp_box) + # + gc_ll_descr = self.assembler.cpu.gc_ll_descr + itemsize = op.getarg(0).getint() + maxlength = (gc_ll_descr.max_size_of_young_obj - WORD * 2) / itemsize + self.assembler.malloc_cond_varsize( + gc_ll_descr.get_nursery_free_addr(), + gc_ll_descr.get_nursery_top_addr(), + lengthloc, itemsize, maxlength, gcmap) + def get_gcmap(self, forbidden_regs=[], noregs=False): frame_depth = self.fm.get_frame_depth() gcmap = allocate_gcmap(self.assembler, frame_depth, JITFRAME_FIXED_SIZE) From noreply at buildbot.pypy.org Mon Mar 18 22:25:46 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 18 Mar 2013 22:25:46 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: tests for STL map and allow iterations over std::pair Message-ID: <20130318212546.1DDA11C13F8@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62409:1ea72a905385 Date: 2013-03-18 14:25 -0700 http://bitbucket.org/pypy/pypy/changeset/1ea72a905385/ Log: tests for STL map and allow iterations over std::pair diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py --- a/pypy/module/cppyy/pythonify.py +++ b/pypy/module/cppyy/pythonify.py @@ -336,9 +336,20 @@ return self.c_str() == other.c_str() else: return self.c_str() == other - pyclass.__eq__ = eq + pyclass.__eq__ = eq pyclass.__str__ = pyclass.c_str + # std::pair unpacking through iteration + if 'std::pair' in pyclass.__name__: + def getitem(self, idx): + if idx == 0: return self.first + if idx == 1: return self.second + raise IndexError("out of bounds") + def return2(self): + return 2 + pyclass.__getitem__ = getitem + pyclass.__len__ = return2 + _loaded_dictionaries = {} def load_reflection_info(name): """Takes the name of a library containing reflection info, returns a handle diff --git a/pypy/module/cppyy/test/stltypes.h b/pypy/module/cppyy/test/stltypes.h --- a/pypy/module/cppyy/test/stltypes.h +++ b/pypy/module/cppyy/test/stltypes.h @@ -1,6 +1,7 @@ #include #include #include +#include #include //- basic example class @@ -14,6 +15,14 @@ std::STLTYPE::iterator STLTYPE##_##N##_i; \ std::STLTYPE::const_iterator STLTYPE##_##N##_ci +#define STLTYPE_INSTANTIATION2(STLTYPE, TTYPE1, TTYPE2, N) \ + std::STLTYPE STLTYPE##_##N; \ + std::pair STLTYPE##_##N##_p; \ + std::pair STLTYPE##_##N##_cp; \ + std::STLTYPE::iterator STLTYPE##_##N##_i; \ + std::STLTYPE::const_iterator STLTYPE##_##N##_ci + + //- instantiations of used STL types namespace { @@ -28,9 +37,16 @@ struct _CppyyListInstances { - STLTYPE_INSTANTIATION(list, int, 1); - STLTYPE_INSTANTIATION(list, float, 2); - STLTYPE_INSTANTIATION(list, double, 3); + STLTYPE_INSTANTIATION(list, int, 1); + STLTYPE_INSTANTIATION(list, float, 2); + STLTYPE_INSTANTIATION(list, double, 3); + + }; + + struct _CppyyMapInstances { + + STLTYPE_INSTANTIATION2(map, int, int, 1); + STLTYPE_INSTANTIATION2(map, std::string, int, 2); }; diff --git a/pypy/module/cppyy/test/stltypes.xml b/pypy/module/cppyy/test/stltypes.xml --- a/pypy/module/cppyy/test/stltypes.xml +++ b/pypy/module/cppyy/test/stltypes.xml @@ -11,6 +11,11 @@ + + + + + diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py --- a/pypy/module/cppyy/test/test_stltypes.py +++ b/pypy/module/cppyy/test/test_stltypes.py @@ -279,7 +279,7 @@ assert s == c.get_string1() -class AppTestSTLSTRING: +class AppTestSTLLIST: spaceconfig = dict(usemodules=['cppyy']) def setup_class(cls): @@ -334,3 +334,92 @@ for arg in a: pass + +class AppTestSTLMAP: + spaceconfig = dict(usemodules=['cppyy', 'itertools']) + + def setup_class(cls): + cls.w_N = cls.space.wrap(13) + cls.w_test_dct = cls.space.wrap(test_dct) + cls.w_stlstring = cls.space.appexec([], """(): + import cppyy, math + return cppyy.load_reflection_info(%r)""" % (test_dct, )) + + def test01_builtin_map_type(self): + """Test access to a map""" + + import cppyy + std = cppyy.gbl.std + + a = std.map(int, int)() + for i in range(self.N): + a[i] = i + assert a[i] == i + + assert len(a) == self.N + + for key, value in a: + assert key == value + assert key == self.N-1 + assert value == self.N-1 + + # add a variation, just in case + m = std.map(int, int)() + for i in range(self.N): + m[i] = i*i + assert m[i] == i*i + + for key, value in m: + assert key*key == value + assert key == self.N-1 + assert value == (self.N-1)*(self.N-1) + + def test02_keyed_maptype(self): + """Test access to a map""" + + import cppyy + std = cppyy.gbl.std + + a = std.map(std.string, int)() + for i in range(self.N): + a[str(i)] = i + import pdb + pdb.set_trace() + assert a[str(i)] == i + + assert len(a) == self.N + + def test03_empty_maptype(self): + """Test behavior of empty map""" + + import cppyy + std = cppyy.gbl.std + + m = std.map(int, int)() + for key, value in m: + pass + + def test04_unsignedvalue_typemap_types(self): + """Test assignability of maps with unsigned value types""" + + import cppyy, math + std = cppyy.gbl.std + + mui = std.map(str, 'unsigned int')() + mui['one'] = 1 + assert mui['one'] == 1 + raises(ValueError, mui.__setitem__, 'minus one', -1) + + # UInt_t is always 32b, sys.maxint follows system int + maxint32 = int(math.pow(2,31)-1) + mui['maxint'] = maxint32 + 3 + assert mui['maxint'] == maxint32 + 3 + + mul = std.map(str, 'unsigned long')() + mul['two'] = 2 + assert mul['two'] == 2 + mul['maxint'] = maxvalue + 3 + assert mul['maxint'] == maxvalue + 3 + + raises(ValueError, mul.__setitem__, 'minus two', -2) + From noreply at buildbot.pypy.org Mon Mar 18 23:08:36 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Mar 2013 23:08:36 +0100 (CET) Subject: [pypy-commit] pypy default: we may have already been removed w/ daemon threads & sys.exit. this is diffcult Message-ID: <20130318220836.B9DDA1C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62410:58a5238702ca Date: 2013-03-18 14:57 -0700 http://bitbucket.org/pypy/pypy/changeset/58a5238702ca/ Log: we may have already been removed w/ daemon threads & sys.exit. this is diffcult to test diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -350,7 +350,11 @@ def remove(self, w_iobase): holder = w_iobase.streamholder if holder is not None: - del self.streams[holder] + try: + del self.streams[holder] + except KeyError: + # this can happen in daemon threads + pass def flush_all(self, space): while self.streams: From noreply at buildbot.pypy.org Mon Mar 18 23:08:39 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Mar 2013 23:08:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130318220839.D91D11C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62411:7d3b2666f8b2 Date: 2013-03-18 15:08 -0700 http://bitbucket.org/pypy/pypy/changeset/7d3b2666f8b2/ Log: merge default diff too long, truncating to 2000 out of 23512 lines diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -43,7 +43,7 @@ if prefix is None: prefix = PREFIX if standard_lib: - return os.path.join(prefix, "lib-python", get_python_version()) + return os.path.join(prefix, "lib-python", sys.version[0]) return os.path.join(prefix, 'site-packages') @@ -61,6 +61,7 @@ g['SO'] = _get_so_extension() or ".so" g['SOABI'] = g['SO'].rsplit('.')[0] g['LIBDIR'] = os.path.join(sys.prefix, 'lib') + g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check global _config_vars _config_vars = g diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,6 +34,8 @@ import struct import re +from __pypy__.builders import StringBuilder + __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1409,11 +1411,24 @@ except ImportError: from StringIO import StringIO + +class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + self.write = self.builder.append + + def getvalue(self): + return self.builder.build() + + def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib-python/2/sysconfig.py b/lib-python/2/sysconfig.py --- a/lib-python/2/sysconfig.py +++ b/lib-python/2/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python/{py_version_short}', - 'platstdlib': '{base}/lib-python/{py_version_short}', - 'purelib': '{base}/lib-python/{py_version_short}', - 'platlib': '{base}/lib-python/{py_version_short}', + 'stdlib': '{base}/lib-python/{py_version}', + 'platstdlib': '{base}/lib-python/{py_version}', + 'purelib': '{base}/lib-python/{py_version}', + 'platlib': '{base}/lib-python/{py_version}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -7,7 +7,6 @@ # the "sandboxed" process. It must work for Python2 as well. import types -from _codecs import utf_8_decode, utf_8_encode try: intern @@ -166,9 +165,8 @@ def dump_unicode(self, x): self._write(TYPE_UNICODE) - #s = x.encode('utf8') - s, len_s = utf_8_encode(x) - self.w_long(len_s) + s = x.encode('utf8') + self.w_long(len(s)) self._write(s) try: unicode @@ -386,8 +384,7 @@ def load_unicode(self): n = self.r_long() s = self._read(n) - #ret = s.decode('utf8') - ret, len_ret = utf_8_decode(s) + ret = s.decode('utf8') return ret dispatch[TYPE_UNICODE] = load_unicode diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -364,9 +364,10 @@ self._in_transaction = False self.isolation_level = isolation_level - self._cursors = [] + self.__cursors = [] + self.__cursors_counter = 0 self.__statements = [] - self.__statement_counter = 0 + self.__statements_counter = 0 self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} @@ -394,10 +395,7 @@ def close(self): self._check_thread() - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._finalize() + self.__do_all_statements(Statement._finalize, True) if self._db: ret = _lib.sqlite3_close(self._db) @@ -469,13 +467,33 @@ exc.error_code = error_code return exc + def _remember_cursor(self, cursor): + self.__cursors.append(weakref.ref(cursor)) + self.__cursors_counter += 1 + if self.__cursors_counter < 200: + return + self.__cursors_counter = 0 + self.__cursors = [r for r in self.__cursors if r() is not None] + def _remember_statement(self, statement): self.__statements.append(weakref.ref(statement)) - self.__statement_counter += 1 + self.__statements_counter += 1 + if self.__statements_counter < 200: + return + self.__statements_counter = 0 + self.__statements = [r for r in self.__statements if r() is not None] - if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements - if ref() is not None] + def __do_all_statements(self, action, reset_cursors): + for weakref in self.__statements: + statement = weakref() + if statement is not None: + action(statement) + + if reset_cursors: + for weakref in self.__cursors: + cursor = weakref() + if cursor is not None: + cursor._reset = True @_check_thread_wrap @_check_closed_wrap @@ -528,10 +546,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() + self.__do_all_statements(Statement._reset, False) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, @@ -552,15 +567,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() - - for cursor_ref in self._cursors: - cursor = cursor_ref() - if cursor: - cursor._reset = True + self.__do_all_statements(Statement._reset, True) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, @@ -787,14 +794,9 @@ __statement = None def __init__(self, con): - self.__initialized = True - self.__connection = con - if not isinstance(con, Connection): raise TypeError - con._check_thread() - con._check_closed() - con._cursors.append(weakref.ref(self)) + self.__connection = con self.arraysize = 1 self.row_factory = None @@ -804,11 +806,12 @@ self.__description = None self.__rowcount = -1 + con._check_thread() + con._remember_cursor(self) + + self.__initialized = True + def __del__(self): - try: - self.__connection._cursors.remove(weakref.ref(self)) - except (AttributeError, ValueError): - pass if self.__statement: self.__statement._reset() @@ -876,9 +879,6 @@ if self.__statement._kind == Statement._DQL and ret == _lib.SQLITE_ROW: self.__statement._build_row_cast_map() self.__statement._readahead(self) - else: - self.__statement._item = None - self.__statement._exhausted = True if self.__statement._kind == Statement._DML: if self.__rowcount == -1: @@ -886,7 +886,6 @@ self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False - return self @__check_cursor_wrap @@ -924,9 +923,10 @@ if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement) if rc == _lib.SQLITE_OK: - return self + break else: raise self.__connection._get_exception(rc) + rc = _lib.sqlite3_finalize(statement) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -1003,6 +1003,7 @@ def __init__(self, connection, sql): self.__con = connection + self.__con._remember_statement(self) if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") @@ -1015,7 +1016,6 @@ self._kind = Statement._DDL self._in_use = False - self._exhausted = False self._row_factory = None if isinstance(sql, unicode): @@ -1031,10 +1031,9 @@ ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(sql)) self._kind = Statement._DQL - if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) - self.__con._remember_statement(self) + sql = sql.value.decode('utf-8') if _check_remaining_sql(sql): raise Warning("You can only execute one statement at a time.") @@ -1053,7 +1052,6 @@ if self._in_use and self._statement: _lib.sqlite3_reset(self._statement) self._in_use = False - self._exhausted = False if sys.version_info[0] < 3: def __check_decodable(self, param): @@ -1218,20 +1216,19 @@ self._item = row def _next(self, cursor): - if self._exhausted: + try: + item = self._item + except AttributeError: raise StopIteration - item = self._item + del self._item ret = _lib.sqlite3_step(self._statement) - if ret == _lib.SQLITE_DONE: - self._exhausted = True - self._item = None - elif ret != _lib.SQLITE_ROW: - exc = self.__con._get_exception(ret) + if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW): _lib.sqlite3_reset(self._statement) - raise exc + raise self.__con._get_exception(ret) + elif ret == _lib.SQLITE_ROW: + self._readahead(cursor) - self._readahead(cursor) return item def _get_description(self): diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -4,6 +4,7 @@ 'array_repr', 'array_str', 'set_string_function', 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + 'seterr', ] import sys diff --git a/pypy/TODO b/pypy/TODO new file mode 100644 --- /dev/null +++ b/pypy/TODO @@ -0,0 +1,2 @@ + +* ARM 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 @@ -42,6 +42,7 @@ .. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal +.. branch: pickle-dumps .. branch: release-2.0-beta1 @@ -85,3 +86,8 @@ .. branch: vendor-rename Remove minor verison number from lib-python dirs to simplify stdlib upgrades. + +.. branch: jitframe-on-heap +Moves optimized JIT frames from stack to heap. As a side effect it enables +stackless to work well with the JIT on PyPy. Also removes a bunch of code from +the GC which fixes cannot find gc roots. diff --git a/pypy/goal/getnightly.py b/pypy/goal/getnightly.py new file mode 100755 --- /dev/null +++ b/pypy/goal/getnightly.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import sys +import os +import py + +if sys.platform.startswith('linux'): + arch = 'linux' +else: + print 'Cannot determine the platform, please update this scrip' + sys.exit(1) + +if sys.maxint == 2**63 - 1: + arch += '64' + +filename = 'pypy-c-jit-latest-%s.tar.bz2' % arch +url = 'http://buildbot.pypy.org/nightly/trunk/%s' % filename +tmp = py.path.local.mkdtemp() +mydir = tmp.chdir() +print 'Downloading pypy to', tmp +if os.system('wget "%s"' % url) != 0: + sys.exit(1) + +print 'Extracting pypy binary' +mydir.chdir() +os.system("tar -x -v --wildcards --strip-components=2 -f %s '*/bin/pypy'" % tmp.join(filename)) + diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -1,8 +1,15 @@ -import os, sys +import cStringIO import itertools +import os +import sys +import traceback +from errno import EINTR + from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated -from errno import EINTR + +from pypy.interpreter import debug + AUTO_DEBUG = os.getenv('PYPY_DEBUG') RECORD_INTERPLEVEL_TRACEBACK = True @@ -94,7 +101,7 @@ if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_text): @@ -128,7 +135,8 @@ def print_application_traceback(self, space, file=None): "NOT_RPYTHON: Dump a standard application-level traceback." - if file is None: file = sys.stderr + if file is None: + file = sys.stderr self.print_app_tb_only(file) print >> file, self.errorstr(space) @@ -163,8 +171,8 @@ def print_detailed_traceback(self, space=None, file=None): """NOT_RPYTHON: Dump a nice detailed interpreter- and application-level traceback, useful to debug the interpreter.""" - import traceback, cStringIO - if file is None: file = sys.stderr + if file is None: + file = sys.stderr f = cStringIO.StringIO() for i in range(len(self.debug_excs)-1, -1, -1): print >> f, "Traceback (interpreter-level):" @@ -177,7 +185,6 @@ self.print_app_tb_only(file) print >> file, '(application-level)', self.errorstr(space) if AUTO_DEBUG: - import debug debug.fire(self) @jit.unroll_safe @@ -202,7 +209,7 @@ # (Class, x) (Class, Class(x)) no # (inst, None) (inst.__class__, inst) no # - w_type = self.w_type + w_type = self.w_type w_value = self.get_w_value(space) if space.exception_is_valid_obj_as_class_w(w_type): @@ -252,7 +259,7 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type + self.w_type = w_type self._w_value = w_value def _exception_getclass(self, space, w_inst, what="exceptions"): @@ -372,7 +379,7 @@ from rpython.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(zip(itertools.count(), formats, attrs)) - # + class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): assert len(args) == len(strings) - 1 @@ -381,6 +388,7 @@ setattr(self, attr, args[i]) assert w_type is not None self.setup(w_type) + def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, fmt, attr in entries: diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -1,11 +1,13 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter import function, pycode, pyframe -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.astcompiler import consts from rpython.rlib import jit from rpython.tool.uid import uid +from pypy.interpreter import function, pycode, pyframe +from pypy.interpreter.astcompiler import consts +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule + + class Cell(Wrappable): "A simple container for a wrapped value." @@ -20,7 +22,7 @@ def get(self): if self.w_value is None: - raise ValueError, "get() from an empty cell" + raise ValueError("get() from an empty cell") return self.w_value def set(self, w_value): @@ -28,7 +30,7 @@ def delete(self): if self.w_value is None: - raise ValueError, "delete() on an empty cell" + raise ValueError("delete() on an empty cell") self.w_value = None def descr__lt__(self, space, w_other): @@ -53,10 +55,10 @@ return space.eq(self.w_value, other.w_value) def descr__reduce__(self, space): - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('cell_new') - if self.w_value is None: #when would this happen? + if self.w_value is None: # when would this happen? return space.newtuple([new_inst, space.newtuple([])]) tup = [self.w_value] return space.newtuple([new_inst, space.newtuple([]), @@ -64,7 +66,7 @@ def descr__setstate__(self, space, w_state): self.w_value = space.getitem(w_state, space.wrap(0)) - + def __repr__(self): """ representation for debugging purposes """ if self.w_value is None: @@ -81,10 +83,9 @@ raise OperationError(space.w_ValueError, space.wrap("Cell is empty")) - super_initialize_frame_scopes = pyframe.PyFrame.initialize_frame_scopes -super_fast2locals = pyframe.PyFrame.fast2locals -super_locals2fast = pyframe.PyFrame.locals2fast +super_fast2locals = pyframe.PyFrame.fast2locals +super_locals2fast = pyframe.PyFrame.locals2fast class __extend__(pyframe.PyFrame): @@ -139,7 +140,7 @@ def fast2locals(self): super_fast2locals(self) # cellvars are values exported to inner scopes - # freevars are values coming from outer scopes + # freevars are values coming from outer scopes freevarnames = list(self.pycode.co_cellvars) if self.pycode.co_flags & consts.CO_OPTIMIZED: freevarnames.extend(self.pycode.co_freevars) diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -19,11 +19,6 @@ # - normal: self.sthread != None, not is_empty_handle(self.h) # - finished: self.sthread != None, is_empty_handle(self.h) - def __del__(self): - sthread = self.sthread - if sthread is not None and not sthread.is_empty_handle(self.h): - sthread.destroy(self.h) - def check_sthread(self): ec = self.space.getexecutioncontext() if ec.stacklet_thread is not self.sthread: @@ -34,7 +29,6 @@ if self.sthread is not None: raise geterror(self.space, "continulet already __init__ialized") sthread = build_sthread(self.space) - workaround_disable_jit(sthread) # # hackish: build the frame "by hand", passing it the correct arguments space = self.space @@ -77,8 +71,7 @@ global_state.clear() raise geterror(self.space, "continulet already finished") self.check_sthread() - workaround_disable_jit(self.sthread) - # + global_state.origin = self if to is None: # simple switch: going to self.h @@ -271,16 +264,6 @@ sthread = ec.stacklet_thread = SThread(space, ec) return sthread -def workaround_disable_jit(sthread): - # A bad workaround to kill the JIT anywhere in this thread. - # This forces all the frames. It's a bad workaround because - # it takes O(depth) time, and it will cause some "abort: - # vable escape" in the JIT. The goal is to prevent any frame - # from being still virtuals, because the JIT generates code - # to un-virtualizable them "on demand" by loading values based - # on FORCE_TOKEN, which is an address in the stack. - sthread.ec.force_all_frames() - # ____________________________________________________________ def permute(space, args_w): diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -391,7 +391,11 @@ def remove(self, w_iobase): holder = w_iobase.streamholder if holder is not None: - del self.streams[holder] + try: + del self.streams[holder] + except KeyError: + # this can happen in daemon threads + pass def flush_all(self, space): while self.streams: diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi/reflex_capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -9,18 +9,23 @@ srcpath = pkgpath.join("src") incpath = pkgpath.join("include") +import commands +(config_stat, incdir) = commands.getstatusoutput("root-config --incdir") + if os.environ.get("ROOTSYS"): - import commands - (stat, incdir) = commands.getstatusoutput("root-config --incdir") - if stat != 0: # presumably Reflex-only + if config_stat != 0: # presumably Reflex-only rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")] else: rootincpath = [incdir] rootlibpath = commands.getoutput("root-config --libdir").split() else: - rootincpath = [] - rootlibpath = [] + if config_stat == 0: + rootincpath = [incdir] + rootlibpath = commands.getoutput("root-config --libdir").split() + else: + rootincpath = [] + rootlibpath = [] def identify(): return 'Reflex' diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -7,7 +7,7 @@ ifeq ($(ROOTSYS),) genreflex=genreflex - cppflags= + cppflags=-I$(shell root-config --incdir) -L$(shell root-config --libdir) else genreflex=$(ROOTSYS)/bin/genreflex ifeq ($(wildcard $(ROOTSYS)/include),) # standard locations used? diff --git a/pypy/module/cppyy/test/test_crossing.py b/pypy/module/cppyy/test/test_crossing.py --- a/pypy/module/cppyy/test/test_crossing.py +++ b/pypy/module/cppyy/test/test_crossing.py @@ -1,6 +1,16 @@ import py, os, sys +from pypy.interpreter.gateway import interp2app, unwrap_spec +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.translator import platform +from rpython.translator.gensupp import uniquemodulename +from rpython.tool.udir import udir + +from pypy.module.cpyext import api +from pypy.module.cpyext.state import State + from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("crossingDict.so")) @@ -11,27 +21,90 @@ if err: raise OSError("'make' failed (see stderr)") +# from pypy/module/cpyext/test/test_cpyext.py; modified to accept more external +# symbols and called directly instead of import_module +def compile_extension_module(space, modname, symbols, **kwds): + """ + Build an extension module and return the filename of the resulting native + code file. + + modname is the name of the module, possibly including dots if it is a module + inside a package. + + Any extra keyword arguments are passed on to ExternalCompilationInfo to + build the module (so specify your source with one of those). + """ + state = space.fromcache(State) + api_library = state.api_lib + if sys.platform == 'win32': + kwds["libraries"] = [api_library] + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] + elif sys.platform == 'darwin': + kwds["link_files"] = [str(api_library + '.dylib')] + else: + kwds["link_files"] = [str(api_library + '.so')] + if sys.platform.startswith('linux'): + kwds["compile_extra"]=["-Werror=implicit-function-declaration"] + + modname = modname.split('.')[-1] + eci = ExternalCompilationInfo( + export_symbols=['init%s' % (modname,)]+symbols, + include_dirs=api.include_dirs, + **kwds + ) + eci = eci.convert_sources_to_files() + dirname = (udir/uniquemodulename('module')).ensure(dir=1) + soname = platform.platform.compile( + [], eci, + outputfilename=str(dirname/modname), + standalone=False) + from pypy.module.imp.importing import get_so_extension + pydname = soname.new(purebasename=modname, ext=get_so_extension(space)) + soname.rename(pydname) + return str(pydname) class AppTestCrossing(AppTestCpythonExtensionBase): spaceconfig = dict(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi', 'array', 'itertools', 'rctime', 'binascii']) def setup_class(cls): - # following from AppTestCpythonExtensionBase, with cppyy added - cls.space.getbuiltinmodule("cpyext") - from pypy.module.imp.importing import importhook - importhook(cls.space, "os") # warm up reference counts - from pypy.module.cpyext.pyobject import RefcountState - state = cls.space.fromcache(RefcountState) - state.non_heaptypes_w[:] = [] - - # cppyy specific additions (not that the test_dct is loaded late + AppTestCpythonExtensionBase.setup_class.im_func(cls) + # cppyy specific additions (note that test_dct is loaded late # to allow the generated extension module be loaded first) cls.w_test_dct = cls.space.wrap(test_dct) cls.w_pre_imports = cls.space.appexec([], """(): import cppyy, ctypes""") # prevents leak-checking complaints on ctypes - from pypy.module.imp.importing import get_so_extension - cls.w_soext = cls.space.wrap(get_so_extension(cls.space)) + + def setup_method(self, func): + AppTestCpythonExtensionBase.setup_method.im_func(self, func) + + @unwrap_spec(name=str, init=str, body=str) + def load_cdll(space, name, init, body, w_symbols): + # the following is loosely from test_cpyext.py import_module; it + # is copied here to be able to tweak the call to + # compile_extension_module and to get a different return result + # than in that function + code = """ + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + kwds = dict(separate_module_sources=[code]) + symbols = [space.str_w(w_item) for w_item in space.fixedview(w_symbols)] + mod = compile_extension_module(space, name, symbols, **kwds) + + # explicitly load the module as a CDLL rather than as a module + import ctypes + from pypy.module.imp.importing import get_so_extension + fullmodname = os.path.join( + os.path.dirname(mod), name + get_so_extension(space)) + return ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) + + self.w_load_cdll = self.space.wrap(interp2app(load_cdll)) def test00_base_class(self): """Test from cpyext; only here to see whether the imported class works""" @@ -49,10 +122,13 @@ import os, ctypes + name = 'bar' + init = """ if (Py_IsInitialized()) Py_InitModule("bar", methods); """ + # note: only the symbols are needed for C, none for python body = """ long bar_unwrap(PyObject* arg) @@ -67,10 +143,12 @@ { NULL } }; """ + # explicitly load the module as a CDLL rather than as a module +# dirname = space.wrap(os.path.dirname(mod)) - dirname = self.import_module(name='bar', init=init, body=body, load_it=False) - fullmodname = os.path.join(dirname, 'bar' + self.soext) - self.cmodule = ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) +# dirname = self.import_module(name='bar', init=init, body=body, load_it=False) +# fullmodname = os.path.join(dirname, name + self.soext) + self.cmodule = self.load_cdll(name, init, body, ['bar_unwrap', 'bar_wrap'])#ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) def test02_crossing_dict(self): """Test availability of all needed classes in the dict""" diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py --- a/pypy/module/cppyy/test/test_pythonify.py +++ b/pypy/module/cppyy/test/test_pythonify.py @@ -6,6 +6,9 @@ test_dct = str(currpath.join("example01Dict.so")) def setup_module(mod): + # force removal of ROOTSYS for this one test, which serves as a test itself + if os.getenv("ROOTSYS"): + os.unsetenv("ROOTSYS") if sys.platform == 'win32': py.test.skip("win32 not supported so far") err = os.system("cd '%s' && make example01Dict.so" % currpath) diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -109,19 +109,19 @@ _axis = axis if axis < 0: _axis = len(shape) + axis - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for arr in args_w[1:]: - dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, - arr.get_dtype()) - if _axis < 0 or len(arr.get_shape()) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for i, axis_size in enumerate(arr.get_shape()): if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, + arr.get_dtype()) + if _axis < 0 or len(arr.get_shape()) <= _axis: + raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) + if _axis < 0 or len(shape) <= _axis: + raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -136,6 +136,10 @@ def getitem_array_int(self, space, w_index): prefix, res_shape, iter_shape, indexes = \ self._prepare_array_index(space, w_index) + if iter_shape is None: + # w_index is a list of slices, return a view + chunks = self.implementation._prepare_slice_args(space, w_index) + return chunks.apply(self) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) if not res.get_size(): @@ -147,8 +151,15 @@ val_arr = convert_to_array(space, w_value) prefix, _, iter_shape, indexes = \ self._prepare_array_index(space, w_index) - return loop.setitem_array_int(space, self, iter_shape, indexes, val_arr, - prefix) + if iter_shape is None: + # w_index is a list of slices + w_value = convert_to_array(space, w_value) + chunks = self.implementation._prepare_slice_args(space, w_index) + view = chunks.apply(self) + view.implementation.setslice(space, w_value) + return + loop.setitem_array_int(space, self, iter_shape, indexes, val_arr, + prefix) def descr_getitem(self, space, w_idx): if (isinstance(w_idx, W_NDimArray) and @@ -169,9 +180,9 @@ def descr_setitem(self, space, w_idx, w_value): if (isinstance(w_idx, W_NDimArray) and - w_idx.get_dtype().is_bool_type()): - return self.setitem_filter(space, w_idx, - convert_to_array(space, w_value)) + w_idx.get_dtype().is_bool_type()): + self.setitem_filter(space, w_idx, convert_to_array(space, w_value)) + return try: self.implementation.descr_setitem(space, self, w_idx, w_value) except ArrayArgumentException: 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 @@ -1470,12 +1470,11 @@ assert str(exc.value) == \ "all the input arrays must have same number of dimensions" - if 0: # XXX too pedantic - g1 = array([0,1,2]) - g2 = array([[3,4,5]]) - exc = raises(ValueError, concatenate, (g1, g2), axis=2) - assert str(exc.value) == \ - "all the input arrays must have same number of dimensions" + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] @@ -2204,6 +2203,20 @@ a[array([0, 2]), slice(0, 2)] = [[10, 11], [12, 13]] assert (a == [[10, 11], [3, 4], [12, 13]]).all() + def test_slice_vector_index(self): + from numpypy import arange + b = arange(145) + a = b[slice(25, 125, None)] + assert (a == range(25, 125)).all() + a = b[[slice(25, 125, None)]] + assert a.shape == (100,) + # a is a view into b + a[10] = 200 + assert b[35] == 200 + b[[slice(25, 30)]] = range(5) + assert all(a[:5] == range(5)) + raises(TypeError, 'b[[[slice(25, 125)]]]') + def test_cumsum(self): from numpypy import arange a = arange(6).reshape(3, 2) diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -22,6 +22,7 @@ 'lastblock', 'is_being_profiled', 'w_globals', + 'w_f_trace', ] JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE'] @@ -39,9 +40,6 @@ def set_jitcell_at(newcell, next_instr, is_being_profiled, bytecode): bytecode.jit_cells[next_instr, is_being_profiled] = newcell -def confirm_enter_jit(next_instr, is_being_profiled, bytecode, frame, ec): - return (frame.w_f_trace is None and - ec.w_tracefunc is None) def can_never_inline(next_instr, is_being_profiled, bytecode): return False @@ -57,7 +55,6 @@ pypyjitdriver = PyPyJitDriver(get_printable_location = get_printable_location, get_jitcell_at = get_jitcell_at, set_jitcell_at = set_jitcell_at, - confirm_enter_jit = confirm_enter_jit, can_never_inline = can_never_inline, should_unroll_one_iteration = should_unroll_one_iteration, 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 @@ -5,14 +5,14 @@ from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError -from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, hlstr from rpython.rtyper.lltypesystem.rclass import OBJECT -from rpython.jit.metainterp.resoperation import rop, AbstractResOp +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 -from rpython.rlib.rarithmetic import r_uint +from rpython.rlib.objectmodel import compute_unique_id from pypy.module.pypyjit.interp_jit import pypyjitdriver class Cache(object): @@ -270,7 +270,8 @@ self.jd_name = debug_info.get_jitdriver().name self.type = debug_info.type if is_bridge: - self.bridge_no = debug_info.fail_descr_no + self.bridge_no = compute_unique_id(debug_info.fail_descr) + #self.bridge_no = debug_info.fail_descr_no self.w_green_key = space.w_None else: self.w_green_key = wrap_greenkey(space, diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py --- a/pypy/module/pypyjit/policy.py +++ b/pypy/module/pypyjit/policy.py @@ -106,7 +106,7 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat']: + '_cffi_backend', 'pyexpat', '_continuation']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -2,7 +2,8 @@ import py from pypy.interpreter.gateway import interp2app from pypy.interpreter.pycode import PyCode -from rpython.jit.metainterp.history import JitCellToken, ConstInt, ConstPtr +from rpython.jit.metainterp.history import JitCellToken, ConstInt, ConstPtr,\ + BasicFailDescr from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.logger import Logger from rpython.rtyper.annlowlevel import (cast_instance_to_base_ptr, @@ -69,7 +70,7 @@ oplist, 'loop', greenkey) di_loop.asminfo = AsmInfo(offset, 0, 0) di_bridge = JitDebugInfo(MockJitDriverSD, logger, JitCellToken(), - oplist, 'bridge', fail_descr_no=0) + oplist, 'bridge', fail_descr=BasicFailDescr()) di_bridge.asminfo = AsmInfo(offset, 0, 0) def interp_on_compile(): diff --git a/pypy/module/test_lib_pypy/test_marshal_extra.py b/pypy/module/test_lib_pypy/test_marshal_extra.py --- a/pypy/module/test_lib_pypy/test_marshal_extra.py +++ b/pypy/module/test_lib_pypy/test_marshal_extra.py @@ -144,3 +144,8 @@ def test_load_truncated_string(): s = '(\x02\x00\x00\x00i\x03\x00\x00\x00sB\xf9\x00\x00\nabcd' py.test.raises(EOFError, marshal.loads, s) + +def test_dump_unicode_length(): + s = b'123\xe9'.decode('latin-1') + r = marshal.dumps(s) + assert r == b'u\x05\x00\x00\x00123\xc3\xa9' 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 @@ -57,11 +57,34 @@ cur = con.cursor() with pytest.raises(StopIteration): next(cur) - cur = con.execute('select 1') + + cur.execute('select 1') next(cur) with pytest.raises(StopIteration): next(cur) + cur.execute('select 1') + con.commit() + next(cur) + with pytest.raises(StopIteration): + next(cur) + + with pytest.raises(_sqlite3.ProgrammingError): + cur.executemany('select 1', []) + with pytest.raises(StopIteration): + next(cur) + + cur.execute('select 1') + cur.execute('create table test(ing)') + with pytest.raises(StopIteration): + next(cur) + + cur.execute('select 1') + cur.execute('insert into test values(1)') + con.commit() + with pytest.raises(StopIteration): + next(cur) + def test_cursor_after_close(): con = _sqlite3.connect(':memory:') cur = con.execute('select 1') @@ -136,6 +159,7 @@ con.commit() except _sqlite3.OperationalError: pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK") + con.close() def test_statement_arg_checking(): con = _sqlite3.connect(':memory:') @@ -171,3 +195,4 @@ with pytest.raises(ValueError) as e: con.execute('insert into foo(x) values (?)', 2) assert str(e.value) == 'parameters are of unsupported type' + con.close() diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -107,15 +107,13 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def view_as_kwargs(self): - return self.strategy.view_as_kwargs(self) - def _add_indirections(): dict_methods = "setitem setitem_str getitem \ getitem_str delitem length \ clear w_keys values \ items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int".split() + popitem listview_str listview_unicode listview_int \ + view_as_kwargs".split() def make_method(method): def f(self, *args): @@ -123,9 +121,6 @@ f.func_name = method return f - def view_as_kwargs(self): - return self.strategy.view_as_kwargs(self) - for method in dict_methods: setattr(W_DictMultiObject, method, make_method(method)) @@ -573,6 +568,12 @@ def w_keys(self, w_dict): return self.space.newlist(self.unerase(w_dict.dstorage).keys()) + def setitem_str(self, w_dict, s, w_value): + self.setitem(w_dict, self.space.wrap(s), w_value) + + def switch_to_object_strategy(self, w_dict): + assert 0, "should be unreachable" + create_iterator_classes(ObjectDictStrategy) class StringDictStrategy(AbstractTypedStrategy, DictStrategy): diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -34,7 +34,7 @@ self.descr = descr self._is_guard = name.startswith('guard_') if self._is_guard: - self.guard_no = int(self.descr[len(') + guard_false(v0, descr=) guard_true(v0, descr=) ''') bridge = parse(''' - # bridge out of Guard 13 + # bridge out of Guard 1a [] int_add(0, 1) ''') LoopStorage().reconnect_loops([main, bridge]) assert adjust_bridges(main, {})[1].name == 'guard_true' - assert adjust_bridges(main, {'loop-13': True})[1].name == 'int_add' + assert adjust_bridges(main, {'loop-1a': True})[1].name == 'int_add' def test_parsing_strliteral(): loop = parse(""" @@ -259,7 +259,7 @@ +348: i32 = int_is_true(i31) +360: i33 = int_or(i27, i32) +364: i34 = int_is_true(i33) -guard_false(i34, descr=) [i1, i22, p2] +guard_false(i34, descr=) [i1, i22, p2] +372: i35 = int_add(i22, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +376: jump(i35, i1, p2, p4, descr=TargetToken(1081858656)) @@ -323,7 +323,7 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) @@ -336,10 +336,10 @@ i0 = int_lt(1, 2) finish(i0) ''') - bridge.comment = 'bridge out of Guard 2 with 1 ops' + bridge.comment = 'bridge out of Guard af with 1 ops' loop.comment = 'Loop 0' loops = split_trace(loop) + split_trace(bridge) - input = ['grrr:123\nasb:12\nbridge 2:1234'] + input = ['grrr:123\nasb:12\nbridge af:1234'] parse_log_counts(input, loops) assert loops[-1].count == 1234 assert loops[1].count == 123 diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -143,13 +143,9 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing + op = bk._find_current_op("is_", 2) knowntypedata = {} - fn, block, i = bk.position_key - annotator = bk.annotator - op = block.operations[i] - assert op.opname == "is_" - assert len(op.args) == 2 def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): @@ -319,11 +315,7 @@ rarithmetic.signedtype(int2.knowntype)): return r knowntypedata = {} - # XXX HACK HACK HACK - fn, block, i = getbookkeeper().position_key - op = block.operations[i] - assert op.opname == opname - assert len(op.args) == 2 + op = getbookkeeper()._find_current_op(opname=opname, arity=2) def tointtype(int0): if int0.knowntype is bool: return int diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -693,6 +693,20 @@ if emulate_enter: self.leave() + def _find_current_op(self, opname=None, arity=None, pos=None, s_type=None): + """ Find operation that is currently being annotated. Do some + sanity checks to see whether the correct op was found.""" + # XXX XXX HACK HACK HACK + fn, block, i = self.position_key + op = block.operations[i] + if opname is not None: + assert op.opname == opname or op.opname in opname + if arity is not None: + assert len(op.args) == arity + if pos is not None: + assert self.annotator.binding(op.args[pos]) == s_type + return op + def build_args(self, op, args_s): space = RPythonCallsSpace() if op == "simple_call": diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -178,15 +178,9 @@ # from bool to int, notice that isinstance( , bool|int) # is quite border case for RPython r.const = False - # XXX HACK HACK HACK - # XXX HACK HACK HACK - # XXX HACK HACK HACK bk = getbookkeeper() if variables is None: - fn, block, i = bk.position_key - op = block.operations[i] - assert op.opname == "simple_call" - assert len(op.args) == 3 + op = bk._find_current_op("simple_call", 3) assert op.args[0] == Constant(isinstance) variables = [op.args[1]] for variable in variables: diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -306,8 +306,10 @@ result = schedule(graph, inputcells) signature = getattr(self.pyobj, '_signature_', None) if signature: - result = enforce_signature_return(self, signature[1], result) - self.bookkeeper.annotator.addpendingblock(graph, graph.returnblock, [result]) + sigresult = enforce_signature_return(self, signature[1], result) + if sigresult is not None: + self.bookkeeper.annotator.addpendingblock(graph, graph.returnblock, [sigresult]) + result = sigresult # Some specializations may break the invariant of returning # annotations that are always more general than the previous time. # We restore it here: diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -233,6 +233,9 @@ def nonnoneify(self): return self.__class__(can_be_None=False, no_nul=self.no_nul) + def nonnulify(self): + return self.__class__(can_be_None=self.can_be_None, no_nul=True) + class SomeString(SomeStringOrUnicode): "Stands for an object which is known to be a string." knowntype = str diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -132,11 +132,13 @@ inputcells[:] = args_s def finish_type(paramtype, bookkeeper, func): - from rpython.rlib.types import SelfTypeMarker + from rpython.rlib.types import SelfTypeMarker, AnyTypeMarker if isinstance(paramtype, SomeObject): return paramtype elif isinstance(paramtype, SelfTypeMarker): raise Exception("%r argument declared as annotation.types.self(); class needs decorator rlib.signature.finishsigs()" % (func,)) + elif isinstance(paramtype, AnyTypeMarker): + return None else: return paramtype(bookkeeper) @@ -144,15 +146,20 @@ assert len(paramtypes) == len(actualtypes) params_s = [finish_type(paramtype, funcdesc.bookkeeper, funcdesc.pyobj) for paramtype in paramtypes] for i, (s_param, s_actual) in enumerate(zip(params_s, actualtypes)): + if s_param is None: # can be anything + continue if not s_param.contains(s_actual): raise Exception("%r argument %d:\n" "expected %s,\n" " got %s" % (funcdesc, i+1, s_param, s_actual)) - actualtypes[:] = params_s + for i, s_param in enumerate(params_s): + if s_param is None: + continue + actualtypes[i] = s_param def enforce_signature_return(funcdesc, sigtype, inferredtype): s_sigret = finish_type(sigtype, funcdesc.bookkeeper, funcdesc.pyobj) - if not s_sigret.contains(inferredtype): + if s_sigret is not None and not s_sigret.contains(inferredtype): raise Exception("%r return value:\n" "expected %s,\n" " got %s" % (funcdesc, s_sigret, inferredtype)) 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 @@ -446,6 +446,25 @@ s_item = s.listdef.listitem.s_value assert s_item.no_nul + def test_str_split_nul(self): + def f(n): + return n.split('\0')[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeString(no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeString) + assert not s.can_be_None + assert s.no_nul + + def g(n): + return n.split('\0', 1)[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(g, [annmodel.SomeString(no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeString) + assert not s.can_be_None + assert not s.no_nul + def test_str_splitlines(self): a = self.RPythonAnnotator() def f(a_str): @@ -3762,6 +3781,19 @@ assert isinstance(s, annmodel.SomeString) assert not s.can_be_None + def test_contains_no_nul(self): + def f(i): + if "\0" in i: + return None + else: + return i + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeString(no_nul=False)]) + assert isinstance(s, annmodel.SomeString) + assert s.can_be_None + assert s.no_nul + def test_no___call__(self): class X(object): def __call__(self): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -43,12 +43,7 @@ raise Exception, 'type() called with more than one argument' r = SomeType() bk = getbookkeeper() - fn, block, i = bk.position_key - annotator = bk.annotator - op = block.operations[i] - assert op.opname == "type" - assert len(op.args) == 1 - assert annotator.binding(op.args[0]) == obj + op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=obj) r.is_type_of = [op.args[0]] return r @@ -79,10 +74,7 @@ bk = getbookkeeper() knowntypedata = {} - fn, block, i = bk.position_key - op = block.operations[i] - assert op.opname == "is_true" or op.opname == "nonzero" - assert len(op.args) == 1 + op = bk._find_current_op(opname=("is_true", "nonzero"), arity=1) arg = op.args[0] s_nonnone_obj = s_obj if s_obj.can_be_none(): @@ -504,7 +496,11 @@ def method_split(str, patt, max=-1): getbookkeeper().count("str_split", str, patt) - s_item = str.basestringclass(no_nul=str.no_nul) + if max == -1 and patt.is_constant() and patt.const == "\0": + no_nul = True + else: + no_nul = str.no_nul + s_item = str.basestringclass(no_nul=no_nul) return getbookkeeper().newlist(s_item) def method_rsplit(str, patt, max=-1): @@ -520,6 +516,20 @@ result = str.basestringclass(no_nul=str.no_nul) return result + def op_contains(str, s_element): + if s_element.is_constant() and s_element.const == "\0": + r = SomeBool() + bk = getbookkeeper() + op = bk._find_current_op(opname="contains", arity=2, pos=0, s_type=str) + knowntypedata = {} + add_knowntypedata(knowntypedata, False, [op.args[0]], str.nonnulify()) + r.set_knowntypedata(knowntypedata) + return r + else: + return SomeObject.op_contains(str, s_element) + op_contains.can_only_throw = [] + + class __extend__(SomeUnicodeString): def method_encode(uni, s_enc): if not s_enc.is_constant(): diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -1,7 +1,3 @@ -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import r_uint - - FUNC_ALIGN = 8 WORD = 4 DOUBLE_WORD = 8 @@ -14,54 +10,12 @@ PC_OFFSET = 8 FORCE_INDEX_OFS = 0 -from rpython.translator.tool.cbuild import ExternalCompilationInfo -eci = ExternalCompilationInfo(post_include_bits=[""" -static int pypy__arm_int_div(int a, int b) { - return a/b; -} -static unsigned int pypy__arm_uint_div(unsigned int a, unsigned int b) { - return a/b; -} -static int pypy__arm_int_mod(int a, int b) { - return a % b; -} -"""]) - - -def arm_int_div_emulator(a, b): - return int(a / float(b)) -arm_int_div_sign = lltype.Ptr( - lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) -arm_int_div = rffi.llexternal( - "pypy__arm_int_div", [lltype.Signed, lltype.Signed], lltype.Signed, - _callable=arm_int_div_emulator, - compilation_info=eci, - _nowrapper=True, elidable_function=True) - - -def arm_uint_div_emulator(a, b): - return r_uint(a) / r_uint(b) -arm_uint_div_sign = lltype.Ptr( - lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned)) -arm_uint_div = rffi.llexternal( - "pypy__arm_uint_div", [lltype.Unsigned, lltype.Unsigned], lltype.Unsigned, - _callable=arm_uint_div_emulator, - compilation_info=eci, - _nowrapper=True, elidable_function=True) - - -def arm_int_mod_emulator(a, b): - sign = 1 - if a < 0: - a = -1 * a - sign = -1 - if b < 0: - b = -1 * b - res = a % b - return sign * res -arm_int_mod_sign = arm_int_div_sign -arm_int_mod = rffi.llexternal( - "pypy__arm_int_mod", [lltype.Signed, lltype.Signed], lltype.Signed, - _callable=arm_int_mod_emulator, - compilation_info=eci, - _nowrapper=True, elidable_function=True) +# The stack contains the force_index and the, callee saved registers and +# ABI required information +# All the rest of the data is in a GC-managed variable-size "frame". +# This jitframe object's address is always stored in the register FP +# A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME +# Stack frame fixed area +# Currently only the force_index +JITFRAME_FIXED_SIZE = 11 + 16 * 2 + 1 +# 11 GPR + 16 VFP Regs (64bit) + 1 word for alignment diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1,91 +1,64 @@ from __future__ import with_statement + import os + +from rpython.jit.backend.arm import conditions as c, registers as r +from rpython.jit.backend.arm.arch import (WORD, DOUBLE_WORD, FUNC_ALIGN, + JITFRAME_FIXED_SIZE) +from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder +from rpython.jit.backend.arm.locations import imm, StackLocation +from rpython.jit.backend.arm.opassembler import ResOpAssembler +from rpython.jit.backend.arm.regalloc import (Regalloc, + CoreRegisterManager, check_imm_arg, VFPRegisterManager, + operations as regalloc_operations, + operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.arm.helper.assembler import saved_registers -from rpython.jit.backend.arm import conditions as c -from rpython.jit.backend.arm import registers as r -from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, FUNC_ALIGN, \ - N_REGISTERS_SAVED_BY_MALLOC -from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder -from rpython.jit.backend.arm.locations import get_fp_offset -from rpython.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, - CoreRegisterManager, check_imm_arg, - operations as regalloc_operations, - operations_with_guard as regalloc_operations_with_guard) +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken -from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT -from rpython.jit.metainterp.history import BoxInt, ConstInt -from rpython.jit.metainterp.resoperation import rop, ResOperation -from rpython.rlib import rgc -from rpython.rlib.objectmodel import we_are_translated, specialize -from rpython.rtyper.annlowlevel import llhelper -from rpython.rtyper.lltypesystem import lltype, rffi, llmemory -from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.jit.backend.arm.opassembler import ResOpAssembler -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints, fatalerror) +from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT +from rpython.jit.metainterp.resoperation import rop +from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rlib.jit import AsmInfo -from rpython.rlib.objectmodel import compute_unique_id - -# XXX Move to llsupport -from rpython.jit.backend.x86.support import memcpy_fn - -DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), - ('type', lltype.Char), # 'b'ridge, 'l'abel or - # 'e'ntry point - ('number', lltype.Signed)) +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref +from rpython.rtyper.lltypesystem import lltype, rffi class AssemblerARM(ResOpAssembler): - STACK_FIXED_AREA = -1 - - debug = True + debug = False def __init__(self, cpu, translate_support_code=False): - self.cpu = cpu + ResOpAssembler.__init__(self, cpu, translate_support_code) self.setup_failure_recovery() self.mc = None - self.memcpy_addr = 0 self.pending_guards = None self._exit_code_addr = 0 self.current_clt = None self.malloc_slowpath = 0 - self.wb_slowpath = [0, 0, 0, 0] + self.wb_slowpath = [0, 0, 0, 0, 0] self._regalloc = None self.datablockwrapper = None self.propagate_exception_path = 0 self.stack_check_slowpath = 0 - self._compute_stack_size() self._debug = False self.loop_run_counters = [] self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i') - self.force_token_to_dead_frame = {} # XXX temporary hack + self.gcrootmap_retaddr_forced = 0 def set_debug(self, v): r = self._debug self._debug = v return r - def _compute_stack_size(self): - self.STACK_FIXED_AREA = len(r.callee_saved_registers) * WORD - self.STACK_FIXED_AREA += WORD # FORCE_TOKEN - self.STACK_FIXED_AREA += N_REGISTERS_SAVED_BY_MALLOC * WORD - if self.cpu.supports_floats: - self.STACK_FIXED_AREA += (len(r.callee_saved_vfp_registers) - * DOUBLE_WORD) - if self.STACK_FIXED_AREA % 8 != 0: - self.STACK_FIXED_AREA += WORD # Stack alignment - assert self.STACK_FIXED_AREA % 8 == 0 - - def setup(self, looptoken, operations): + def setup(self, looptoken): + assert self.memcpy_addr != 0, 'setup_once() not called?' + if we_are_translated(): + self.debug = False self.current_clt = looptoken.compiled_loop_token - operations = self.cpu.gc_ll_descr.rewrite_assembler(self.cpu, - operations, self.current_clt.allgcrefs) - assert self.memcpy_addr != 0, 'setup_once() not called?' self.mc = ARMv7Builder() self.pending_guards = [] assert self.datablockwrapper is None @@ -93,7 +66,6 @@ self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) self.target_tokens_currently_compiling = {} - return operations def teardown(self): self.current_clt = None @@ -102,34 +74,8 @@ self.pending_guards = None assert self.datablockwrapper is None - def setup_once(self): - # Addresses of functions called by new_xxx operations - gc_ll_descr = self.cpu.gc_ll_descr - gc_ll_descr.initialize() - self._build_wb_slowpath(False) - self._build_wb_slowpath(True) - self._build_failure_recovery(exc=True, withfloats=False) - self._build_failure_recovery(exc=False, withfloats=False) - if self.cpu.supports_floats: - self._build_wb_slowpath(False, withfloats=True) - self._build_wb_slowpath(True, withfloats=True) - self._build_failure_recovery(exc=True, withfloats=True) - self._build_failure_recovery(exc=False, withfloats=True) - self._build_propagate_exception_path() - if gc_ll_descr.get_malloc_slowpath_addr is not None: - self._build_malloc_slowpath() - self._build_stack_check_slowpath() - if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack: - self._build_release_gil(gc_ll_descr.gcrootmap) - self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn) - - if not self._debug: - # if self._debug is already set it means that someone called - # set_debug by hand before initializing the assembler. Leave it - # as it is - debug_start('jit-backend-counts') - self.set_debug(have_debug_prints()) - debug_stop('jit-backend-counts') + def setup_failure_recovery(self): + self.failure_recovery_code = [0, 0, 0, 0] def finish_once(self): if self._debug: @@ -162,18 +108,6 @@ self.loop_run_counters.append(struct) return struct - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) - @specialize.argtype(1) def _inject_debugging_code(self, looptoken, operations, tp, number): if self._debug: @@ -218,22 +152,84 @@ self.reacqgil_addr = rffi.cast(lltype.Signed, reacqgil_func) def _build_propagate_exception_path(self): - if self.cpu.propagate_exception_v < 0: + if not self.cpu.propagate_exception_descr: return # not supported (for tests, or non-translated) # mc = ARMv7Builder() - # - # Call the helper, which will return a dead frame object with - # the correct exception set, or MemoryError by default - # XXX make sure we return the correct value here - addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception()) - mc.BL(addr) - self.gen_func_epilog(mc=mc) - self.propagate_exception_path = mc.materialize(self.cpu.asmmemmgr, []) + self._store_and_reset_exception(mc, r.r0) + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + mc.LDR_ri(r.r0.value, r.fp.value, imm=ofs) + propagate_exception_descr = rffi.cast(lltype.Signed, + cast_instance_to_gcref(self.cpu.propagate_exception_descr)) + # put propagate_exception_descr into frame + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + mc.gen_load_int(r.r0.value, propagate_exception_descr) + mc.STR_ri(r.r0.value, r.fp.value, imm=ofs) + mc.MOV_rr(r.r0.value, r.fp.value) + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu.asmmemmgr, []) + self.propagate_exception_path = rawstart + + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + on_frame=False): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ + assert excvalloc is not r.ip + assert exctploc is not r.ip + tmpreg = r.lr + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if excvalloc is not None: # store + assert excvalloc.is_reg() + self.load_reg(mc, excvalloc, r.ip) + if on_frame: + # store exc_value in JITFRAME + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(ofs) + self.store_reg(mc, r.ip, r.fp, ofs) + if exctploc is not None: + # store pos_exception in exctploc + assert exctploc.is_reg() + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.load_reg(mc, exctploc, r.ip) + + # reset exception + mc.gen_load_int(tmpreg.value, 0) + + self.store_reg(mc, tmpreg, r.ip, 0) + + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, tmpreg, r.ip, 0) + + def _restore_exception(self, mc, excvalloc, exctploc): + assert excvalloc is not r.ip + assert exctploc is not r.ip + tmpreg = r.lr # use lr as a second temporary reg + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if excvalloc is not None: + assert excvalloc.is_reg() + self.store_reg(mc, excvalloc, r.ip) + else: + assert exctploc is not r.fp + # load exc_value from JITFRAME and put it in pos_exc_value + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + self.load_reg(mc, tmpreg, r.fp, ofs) + self.store_reg(mc, tmpreg, r.ip) + # reset exc_value in the JITFRAME + mc.gen_load_int(tmpreg.value, 0) + self.store_reg(mc, tmpreg, r.fp, ofs) + + # restore pos_exception from exctploc register + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, exctploc, r.ip) def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() - if slowpathaddr == 0 or self.cpu.propagate_exception_v < 0: + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: return # no stack check (for tests, or non-translated) # # make a "function" that is called immediately at the start of @@ -257,7 +253,7 @@ mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) mc.LDR_ri(r.r0.value, r.r0.value) mc.TST_rr(r.r0.value, r.r0.value) - # restore registers and return + # restore registers and return # We check for c.EQ here, meaning all bits zero in this case mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value], cond=c.EQ) # @@ -276,7 +272,7 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart - def _build_wb_slowpath(self, withcards, withfloats=False): + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): descr = self.cpu.gc_ll_descr.write_barrier_descr if descr is None: return @@ -295,12 +291,28 @@ # It must keep stack alignment accordingly. mc = ARMv7Builder() # - if withfloats: - floats = r.caller_vfp_resp + exc0 = exc1 = None + mc.PUSH([r.ip.value, r.lr.value]) # push two words to keep alignment + if not for_frame: + self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) else: - floats = [] - with saved_registers(mc, r.caller_resp + [r.ip, r.lr], floats): - mc.BL(func) + # we're possibly called from the slowpath of malloc + # save the caller saved registers + # assuming we do not collect here + exc0, exc1 = r.r4, r.r5 + mc.PUSH([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) + mc.VPUSH([vfpr.value for vfpr in r.caller_vfp_resp]) + + self._store_and_reset_exception(mc, exc0, exc1) + mc.BL(func) + # + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + self._restore_exception(mc, exc0, exc1) + mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + mc.POP([gpr.value for gpr in r.caller_resp] + + [exc0.value, exc1.value]) # if withcards: # A final TEST8 before the RET, for the caller. Careful to @@ -310,350 +322,174 @@ imm=descr.jit_wb_if_flag_byteofs) mc.TST_ri(r.ip.value, imm=0x80) # - mc.MOV_rr(r.pc.value, r.lr.value) + mc.POP([r.ip.value, r.pc.value]) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) - self.wb_slowpath[withcards + 2 * withfloats] = rawstart - - def setup_failure_recovery(self): - - #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold - def failure_recovery_func(mem_loc, frame_pointer, stack_pointer): - """mem_loc is a structure in memory describing where the values for - the failargs are stored. frame loc is the address of the frame - pointer for the frame to be decoded frame """ - vfp_registers = rffi.cast(rffi.LONGP, stack_pointer) - registers = rffi.ptradd(vfp_registers, 2*len(r.all_vfp_regs)) - registers = rffi.cast(rffi.LONGP, registers) From noreply at buildbot.pypy.org Mon Mar 18 23:19:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Mar 2013 23:19:40 +0100 (CET) Subject: [pypy-commit] buildbot default: try to shift stuff around so buildbots dont collide as much Message-ID: <20130318221940.941271C0084@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r740:1956963acd63 Date: 2013-03-18 15:19 -0700 http://bitbucket.org/pypy/buildbot/changeset/1956963acd63/ Log: try to shift stuff around so buildbots dont collide as much diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -277,12 +277,10 @@ # All the other linux tests run on allegro Nightly("nightly-0-00", [ # benchmarks - JITBENCH, # on tannit32, uses 1 core (in part exclusively) - JITBENCH64, # on tannit64, uses 1 core (in part exclusively) #JITBENCH64_2, # on speed.python.org, uses 1 core (in part exclusively) #CPYTHON_64, # on speed.python.org, uses 1 core (in part exclusively) # linux tests - LINUX32, # on allegro32, uses 20 (twenty!) core + LINUX32, # on allegro32, uses 20 (twenty!) core # other platforms MACOSX32, # on minime JITWIN32, # on aurora @@ -295,10 +293,6 @@ LINUX64, # on allegro64, uses 20 (twenty!) cores ], branch=None, hour=0, minute=45), - Nightly("nightly-1-30-py3k", [ - LINUX32, # on allegro64, uses 20 (twenty!) cores - ], branch="py3k", hour=1, minute=30), - Nightly("nightly-2-15-py3k", [ LINUX64, # on allegro64, uses 20 (twenty!) cores ], branch="py3k", hour=2, minute=15), @@ -311,16 +305,21 @@ APPLVLLINUX64, # on allegro64, uses 1 core ], branch=None, hour=3, minute=0), + Nightly("nightly-3-30", [ + JITBENCH, # on tannit32, uses 1 core (in part exclusively) + JITBENCH64, # on tannit64, uses 1 core (in part exclusively) + ], branch=None, hour=3, minute=30), + Nightly("nightly-4-00-py3k", [ - APPLVLLINUX32, # on allegro32, uses 1 core - #APPLVLLINUX64, # on allegro64, uses 1 core + #APPLVLLINUX32, # on allegro32, uses 1 core + APPLVLLINUX64, # on allegro64, uses 1 core ], branch="py3k", hour=4, minute=0), # Nightly("nighly-ppc", [ JITONLYLINUXPPC64, # on gcc1 ], branch='ppc-jit-backend', hour=1, minute=0), - # + # Nightly("nighly-arm-0-00", [ BUILDLINUXARM, # on hhu-cross-armel, uses 1 core BUILDJITLINUXARM, # on hhu-cross-armel, uses 1 core @@ -387,7 +386,7 @@ "factory": pypyTranslatedLibPythonTestFactory, "category": "linux64", #"locks": [TannitCPU.access('counting')], - }, + }, {"name": OJITLINUX32, "slavenames": ["allegro32"], "builddir": OJITLINUX32, From noreply at buildbot.pypy.org Mon Mar 18 23:34:52 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Mar 2013 23:34:52 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: translation fix Message-ID: <20130318223452.73DD21C00E4@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: indexing-by-array Changeset: r62412:dfb1838dd18b Date: 2013-03-18 15:33 -0700 http://bitbucket.org/pypy/pypy/changeset/dfb1838dd18b/ Log: translation fix diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -6,7 +6,7 @@ def base(self): raise NotImplementedError - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): raise NotImplementedError class BaseArrayIterator(object): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -229,7 +229,7 @@ def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseArrayImplementation) - return self.implementation.create_iter(shape, + return self.implementation.create_iter(shape=shape, backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): From noreply at buildbot.pypy.org Mon Mar 18 23:39:26 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Mon, 18 Mar 2013 23:39:26 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: (mattip, rguillebert) Make scalars work as indexes and implement ndarray.__int__ Message-ID: <20130318223926.9A9261C0084@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: indexing-by-array Changeset: r62413:d38bfa58e42f Date: 2013-03-18 23:35 +0100 http://bitbucket.org/pypy/pypy/changeset/d38bfa58e42f/ Log: (mattip, rguillebert) Make scalars work as indexes and implement ndarray.__int__ diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,5 +1,5 @@ -from pypy.module.micronumpy.arrayimpl import base +from pypy.module.micronumpy.arrayimpl import base, scalar from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException @@ -20,7 +20,7 @@ parent = None # JIT hints that length of all those arrays is a constant - + def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) @@ -71,7 +71,7 @@ new_shape, self, orig_array) else: return None - + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -79,7 +79,7 @@ dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) - return SliceArray(self.start, strides, backstrides, + return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) def get_imag(self, orig_array): @@ -87,7 +87,7 @@ backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type - return SliceArray(self.start + dtype.get_size(), strides, + return SliceArray(self.start + dtype.get_size(), strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag @@ -148,16 +148,12 @@ space.isinstance_w(w_idx, space.w_slice) or space.is_w(w_idx, space.w_None)): raise IndexError - if isinstance(w_idx, W_NDimArray): + if isinstance(w_idx, W_NDimArray) and not isinstance(w_idx.implementation, scalar.Scalar): raise ArrayArgumentException shape = self.get_shape() shape_len = len(shape) - if shape_len == 0: - raise OperationError(space.w_IndexError, space.wrap( - "0-d arrays can't be indexed")) view_w = None - if (space.isinstance_w(w_idx, space.w_list) or - isinstance(w_idx, W_NDimArray)): + if space.isinstance_w(w_idx, space.w_list): raise ArrayArgumentException if space.isinstance_w(w_idx, space.w_tuple): view_w = space.fixedview(w_idx) @@ -260,10 +256,10 @@ shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] - shape[axis1], shape[axis2] = shape[axis2], shape[axis1] + shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] - backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] - return W_NDimArray.new_slice(self.start, strides, + backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] + return W_NDimArray.new_slice(self.start, strides, backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): @@ -330,13 +326,13 @@ free_raw_storage(self.storage, track_allocation=False) - + class NonWritableArray(ConcreteArray): def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) - + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, orig_arr, @@ -371,7 +367,7 @@ return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return iter.OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -69,7 +69,7 @@ def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - + def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -86,7 +86,7 @@ def reshape(self, space, orig_array, new_shape): return self.set_shape(space, orig_array, new_shape) - + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -15,6 +15,7 @@ from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes from pypy.module.micronumpy.interp_arrayops import repeat, choose +from pypy.module.micronumpy.arrayimpl import scalar from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -767,6 +768,15 @@ descr_argmax = _reduce_argmax_argmin_impl("max") descr_argmin = _reduce_argmax_argmin_impl("min") + def descr_int(self, space): + shape = self.get_shape() + if len(shape) == 0: + assert isinstance(self.implementation, scalar.Scalar) + return space.wrap(self.implementation.get_scalar_value()) + if shape == [1]: + return self.descr_getitem(space, space.wrap(0)) + raise OperationError(space.w_TypeError, space.wrap("only length-1 arrays can be converted to Python scalars")) + @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, @@ -807,6 +817,7 @@ __repr__ = interp2app(W_NDimArray.descr_repr), __str__ = interp2app(W_NDimArray.descr_str), + __int__ = interp2app(W_NDimArray.descr_int), __pos__ = interp2app(W_NDimArray.descr_pos), __neg__ = interp2app(W_NDimArray.descr_neg), 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 @@ -1357,7 +1357,7 @@ assert a[1] == 'xyz' assert a.imag[0] == 'abc' raises(TypeError, 'a.imag = "qop"') - a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) + a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) assert a.real[0,1] == 2 a.real[0,1] = -20 assert a[0,1].real == -20 @@ -1367,7 +1367,7 @@ assert a[1,2].imag == 30 a.real = 13 assert a[1,1].real == 13 - a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) + a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) a.real = 13 assert a[3].real == 13 a.imag = -5 @@ -1544,29 +1544,29 @@ from numpypy import array # testcases from numpy docstring x = array([[1, 2, 3]]) - assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() + assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() x = array([[[0,1],[2,3]],[[4,5],[6,7]]]) # shape = (2, 2, 2) - assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], - [[1, 5], [3, 7]]])).all() - assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], + assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], + [[1, 5], [3, 7]]])).all() + assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], [[2, 3], [6, 7]]])).all() - assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], + assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], [[4, 6],[5, 7]]])).all() # more complex shape i.e. (2, 2, 3) - x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) - assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], - [[4, 5, 6], [10, 11, 12]]])).all() - assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], - [[3, 9], [6, 12]]])).all() - assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], - [[7, 10], [8, 11],[9, 12]]])).all() + x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) + assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], + [[4, 5, 6], [10, 11, 12]]])).all() + assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], + [[3, 9], [6, 12]]])).all() + assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], + [[7, 10], [8, 11],[9, 12]]])).all() # test slice - assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], + assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() # test virtual - assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], + assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], [[ 8, 10, 12], [20, 22, 24]]])).all() assert array(1).swapaxes(10, 12) == 1 @@ -1619,7 +1619,7 @@ from numpypy import arange, array b = arange(5) b[array([True, False, True])] = [20, 21, 0, 0, 0, 0, 0] - assert (b == [20, 1, 21, 3, 4]).all() + assert (b == [20, 1, 21, 3, 4]).all() raises(ValueError, "array([1, 2])[array([True, False, True])] = [1, 2, 3]") def test_weakref(self): @@ -1731,6 +1731,12 @@ b = array([1, 2, 3, 4]) assert (a == b) == False + def test__int__(self): + from numpypy import array + assert int(array(1)) == 1 + assert int(array([1])) == 1 + assert raises(TypeError, "int(array([1, 2]))") + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): @@ -2276,7 +2282,7 @@ BaseNumpyAppTest.setup_class.im_func(cls) cls.w_data = cls.space.wrap(struct.pack('dddd', 1, 2, 3, 4)) cls.w_fdata = cls.space.wrap(struct.pack('f', 2.3)) - cls.w_float16val = cls.space.wrap('\x00E') # 5.0 in float16 + cls.w_float16val = cls.space.wrap('\x00E') # 5.0 in float16 cls.w_float32val = cls.space.wrap(struct.pack('f', 5.2)) cls.w_float64val = cls.space.wrap(struct.pack('d', 300.4)) cls.w_ulongval = cls.space.wrap(struct.pack('L', 12)) @@ -2393,7 +2399,7 @@ from numpypy import array, arange assert array(2.0).argsort() == 0 nnp = self.non_native_prefix - for dtype in ['int', 'float', 'int16', 'float32', 'uint64', + for dtype in ['int', 'float', 'int16', 'float32', 'uint64', nnp + 'i2', complex]: a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) c = a.copy() @@ -2403,7 +2409,7 @@ assert (a == c).all() # not modified a = arange(100) assert (a.argsort() == a).all() - raises(NotImplementedError, 'arange(10,dtype="float16").argsort()') + raises(NotImplementedError, 'arange(10,dtype="float16").argsort()') def test_argsort_nd(self): from numpypy import array @@ -2419,7 +2425,7 @@ def test_argsort_axis(self): from numpypy import array - a = array([[4, 2], [1, 3]]) + a = array([[4, 2], [1, 3]]) assert (a.argsort(axis=None) == [2, 1, 3, 0]).all() assert (a.argsort(axis=-1) == [[1, 0], [0, 1]]).all() assert (a.argsort(axis=0) == [[1, 0], [0, 1]]).all() From noreply at buildbot.pypy.org Tue Mar 19 00:21:18 2013 From: noreply at buildbot.pypy.org (wlav) Date: Tue, 19 Mar 2013 00:21:18 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: o) don't use slice-indexing for STL maps, as it doesn't make any sense Message-ID: <20130318232118.716411C0084@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62414:21201b4d80e9 Date: 2013-03-18 16:20 -0700 http://bitbucket.org/pypy/pypy/changeset/21201b4d80e9/ Log: o) don't use slice-indexing for STL maps, as it doesn't make any sense o) translate (type) str -> std::basic_string for template parameters o) propagate OperationError if coming from a non- overloaded function diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -467,9 +467,14 @@ try: return cppyyfunc.call(cppthis, args_w) except OperationError, e: + # special case if there's just one function, to prevent clogging the error message + if len(self.functions) == 1: + raise errmsg += '\n '+cppyyfunc.signature()+' =>\n' errmsg += ' '+e.errorstr(self.space) except Exception, e: + # can not special case this for non-overloaded functions as we anyway need an + # OperationError error down from here errmsg += '\n '+cppyyfunc.signature()+' =>\n' errmsg += ' Exception: '+str(e) diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py --- a/pypy/module/cppyy/pythonify.py +++ b/pypy/module/cppyy/pythonify.py @@ -35,7 +35,9 @@ self._name = name def _arg_to_str(self, arg): - if type(arg) != str: + if arg == str: + arg = 'std::basic_string' + elif type(arg) != str: arg = arg.__name__ return arg @@ -322,7 +324,8 @@ pyclass.__iter__ = __iter__ # combine __getitem__ and __len__ to make a pythonized __getitem__ - if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: + if not 'std::map' in pyclass.__name__ and\ + '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: pyclass._getitem__unchecked = pyclass.__getitem__ if '__setitem__' in pyclass.__dict__ and '__iadd__' in pyclass.__dict__: pyclass.__getitem__ = python_style_sliceable_getitem diff --git a/pypy/module/cppyy/test/stltypes.h b/pypy/module/cppyy/test/stltypes.h --- a/pypy/module/cppyy/test/stltypes.h +++ b/pypy/module/cppyy/test/stltypes.h @@ -45,8 +45,10 @@ struct _CppyyMapInstances { - STLTYPE_INSTANTIATION2(map, int, int, 1); - STLTYPE_INSTANTIATION2(map, std::string, int, 2); + STLTYPE_INSTANTIATION2(map, int, int, 1); + STLTYPE_INSTANTIATION2(map, std::string, int, 2); + STLTYPE_INSTANTIATION2(map, std::string, unsigned int, 3); + STLTYPE_INSTANTIATION2(map, std::string, unsigned long, 4); }; diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py --- a/pypy/module/cppyy/test/test_stltypes.py +++ b/pypy/module/cppyy/test/test_stltypes.py @@ -342,7 +342,7 @@ cls.w_N = cls.space.wrap(13) cls.w_test_dct = cls.space.wrap(test_dct) cls.w_stlstring = cls.space.appexec([], """(): - import cppyy, math + import cppyy, math, sys return cppyy.load_reflection_info(%r)""" % (test_dct, )) def test01_builtin_map_type(self): @@ -383,8 +383,6 @@ a = std.map(std.string, int)() for i in range(self.N): a[str(i)] = i - import pdb - pdb.set_trace() assert a[str(i)] == i assert len(a) == self.N @@ -402,7 +400,7 @@ def test04_unsignedvalue_typemap_types(self): """Test assignability of maps with unsigned value types""" - import cppyy, math + import cppyy, math, sys std = cppyy.gbl.std mui = std.map(str, 'unsigned int')() @@ -418,8 +416,8 @@ mul = std.map(str, 'unsigned long')() mul['two'] = 2 assert mul['two'] == 2 - mul['maxint'] = maxvalue + 3 - assert mul['maxint'] == maxvalue + 3 + mul['maxint'] = sys.maxint + 3 + assert mul['maxint'] == sys.maxint + 3 raises(ValueError, mul.__setitem__, 'minus two', -2) From noreply at buildbot.pypy.org Tue Mar 19 00:23:28 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Tue, 19 Mar 2013 00:23:28 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: (mattip, rguillebert) Test int(array(1.5)) -> 1 Message-ID: <20130318232328.F420C1C0084@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: indexing-by-array Changeset: r62415:0c8318c09981 Date: 2013-03-19 00:09 +0100 http://bitbucket.org/pypy/pypy/changeset/0c8318c09981/ Log: (mattip, rguillebert) Test int(array(1.5)) -> 1 diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -772,9 +772,9 @@ shape = self.get_shape() if len(shape) == 0: assert isinstance(self.implementation, scalar.Scalar) - return space.wrap(self.implementation.get_scalar_value()) + return space.int(space.wrap(self.implementation.get_scalar_value())) if shape == [1]: - return self.descr_getitem(space, space.wrap(0)) + return space.int(self.descr_getitem(space, space.wrap(0))) raise OperationError(space.w_TypeError, space.wrap("only length-1 arrays can be converted to Python scalars")) 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 @@ -1736,6 +1736,7 @@ assert int(array(1)) == 1 assert int(array([1])) == 1 assert raises(TypeError, "int(array([1, 2]))") + assert int(array([1.5])) == 1 class AppTestMultiDim(BaseNumpyAppTest): From noreply at buildbot.pypy.org Tue Mar 19 00:23:30 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Tue, 19 Mar 2013 00:23:30 +0100 (CET) Subject: [pypy-commit] pypy indexing-by-array: Close indexing-by-array branch Message-ID: <20130318232330.461581C0084@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: indexing-by-array Changeset: r62416:52ae1f12f0f9 Date: 2013-03-19 00:16 +0100 http://bitbucket.org/pypy/pypy/changeset/52ae1f12f0f9/ Log: Close indexing-by-array branch From noreply at buildbot.pypy.org Tue Mar 19 00:23:31 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Tue, 19 Mar 2013 00:23:31 +0100 (CET) Subject: [pypy-commit] pypy default: (mattip, rguillebert) Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. Message-ID: <20130318232331.C4B441C0084@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: Changeset: r62417:eef3ab099ef2 Date: 2013-03-19 00:20 +0100 http://bitbucket.org/pypy/pypy/changeset/eef3ab099ef2/ Log: (mattip, rguillebert) Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -6,7 +6,7 @@ def base(self): raise NotImplementedError - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): raise NotImplementedError class BaseArrayIterator(object): diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,5 +1,5 @@ -from pypy.module.micronumpy.arrayimpl import base +from pypy.module.micronumpy.arrayimpl import base, scalar from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException @@ -20,7 +20,7 @@ parent = None # JIT hints that length of all those arrays is a constant - + def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) @@ -71,7 +71,7 @@ new_shape, self, orig_array) else: return None - + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -79,7 +79,7 @@ dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) - return SliceArray(self.start, strides, backstrides, + return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) def get_imag(self, orig_array): @@ -87,7 +87,7 @@ backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type - return SliceArray(self.start + dtype.get_size(), strides, + return SliceArray(self.start + dtype.get_size(), strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag @@ -148,16 +148,12 @@ space.isinstance_w(w_idx, space.w_slice) or space.is_w(w_idx, space.w_None)): raise IndexError - if isinstance(w_idx, W_NDimArray): + if isinstance(w_idx, W_NDimArray) and not isinstance(w_idx.implementation, scalar.Scalar): raise ArrayArgumentException shape = self.get_shape() shape_len = len(shape) - if shape_len == 0: - raise OperationError(space.w_IndexError, space.wrap( - "0-d arrays can't be indexed")) view_w = None - if (space.isinstance_w(w_idx, space.w_list) or - isinstance(w_idx, W_NDimArray)): + if space.isinstance_w(w_idx, space.w_list): raise ArrayArgumentException if space.isinstance_w(w_idx, space.w_tuple): view_w = space.fixedview(w_idx) @@ -260,10 +256,10 @@ shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] - shape[axis1], shape[axis2] = shape[axis2], shape[axis1] + shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] - backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] - return W_NDimArray.new_slice(self.start, strides, + backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] + return W_NDimArray.new_slice(self.start, strides, backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): @@ -294,12 +290,12 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is None or shape == self.get_shape(): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, backward_broadcast) return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): @@ -330,13 +326,13 @@ free_raw_storage(self.storage, track_allocation=False) - + class NonWritableArray(ConcreteArray): def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) - + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, orig_arr, @@ -362,15 +358,16 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, + backward_broadcast) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return iter.OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -38,7 +38,7 @@ def get_strides(self): return [] - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) def get_scalar_value(self): @@ -69,7 +69,7 @@ def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - + def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -86,7 +86,7 @@ def reshape(self, space, orig_array, new_shape): return self.set_shape(space, orig_array, new_shape) - + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -19,7 +19,7 @@ def get_shape(self): return self.shape - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.base(), W_NDimArray) return self.base().create_iter() diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -15,6 +15,7 @@ from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes from pypy.module.micronumpy.interp_arrayops import repeat, choose +from pypy.module.micronumpy.arrayimpl import scalar from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -79,7 +80,11 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - res = W_NDimArray.from_shape([size], self.get_dtype()) + if len(arr.get_shape()) == 1: + res_shape = [size] + self.get_shape()[1:] + else: + res_shape = [size] + res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) def setitem_filter(self, space, idx, val): @@ -223,9 +228,10 @@ s.append('])') return s.build() - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseArrayImplementation) - return self.implementation.create_iter(shape) + return self.implementation.create_iter(shape=shape, + backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) @@ -362,8 +368,11 @@ if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for compress")) + arr = self + else: + arr = self.descr_reshape(space, [space.wrap(-1)]) index = convert_to_array(space, w_obj) - return self.getitem_filter(space, index) + return arr.getitem_filter(space, index) def descr_flatten(self, space, w_order=None): if self.is_scalar(): @@ -759,6 +768,15 @@ descr_argmax = _reduce_argmax_argmin_impl("max") descr_argmin = _reduce_argmax_argmin_impl("min") + def descr_int(self, space): + shape = self.get_shape() + if len(shape) == 0: + assert isinstance(self.implementation, scalar.Scalar) + return space.int(space.wrap(self.implementation.get_scalar_value())) + if shape == [1]: + return space.int(self.descr_getitem(space, space.wrap(0))) + raise OperationError(space.w_TypeError, space.wrap("only length-1 arrays can be converted to Python scalars")) + @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, @@ -799,6 +817,7 @@ __repr__ = interp2app(W_NDimArray.descr_repr), __str__ = interp2app(W_NDimArray.descr_str), + __int__ = interp2app(W_NDimArray.descr_int), __pos__ = interp2app(W_NDimArray.descr_pos), __neg__ = interp2app(W_NDimArray.descr_neg), 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 @@ -300,9 +300,12 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter() + shapelen = len(arr.get_shape()) + if shapelen > 1 and len(index.get_shape()) < 2: + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + else: + index_iter = index.create_iter() arr_iter = arr.create_iter() - shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -40,7 +40,7 @@ rshape += shape[s:] return rshape, rstart, rstrides, rbackstrides -def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape): +def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape, backwards=False): rstrides = [] rbackstrides = [] for i in range(len(orig_shape)): @@ -50,8 +50,12 @@ else: rstrides.append(strides[i]) rbackstrides.append(backstrides[i]) - rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides - rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides + if backwards: + rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape)) + rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape)) + else: + rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides + rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides return rstrides, rbackstrides def is_single_elem(space, w_elem, is_rec_type): 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 @@ -1357,7 +1357,7 @@ assert a[1] == 'xyz' assert a.imag[0] == 'abc' raises(TypeError, 'a.imag = "qop"') - a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) + a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) assert a.real[0,1] == 2 a.real[0,1] = -20 assert a[0,1].real == -20 @@ -1367,7 +1367,7 @@ assert a[1,2].imag == 30 a.real = 13 assert a[1,1].real == 13 - a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) + a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) a.real = 13 assert a[3].real == 13 a.imag = -5 @@ -1544,29 +1544,29 @@ from numpypy import array # testcases from numpy docstring x = array([[1, 2, 3]]) - assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() + assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() x = array([[[0,1],[2,3]],[[4,5],[6,7]]]) # shape = (2, 2, 2) - assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], - [[1, 5], [3, 7]]])).all() - assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], + assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], + [[1, 5], [3, 7]]])).all() + assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], [[2, 3], [6, 7]]])).all() - assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], + assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], [[4, 6],[5, 7]]])).all() # more complex shape i.e. (2, 2, 3) - x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) - assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], - [[4, 5, 6], [10, 11, 12]]])).all() - assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], - [[3, 9], [6, 12]]])).all() - assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], - [[7, 10], [8, 11],[9, 12]]])).all() + x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) + assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], + [[4, 5, 6], [10, 11, 12]]])).all() + assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], + [[3, 9], [6, 12]]])).all() + assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], + [[7, 10], [8, 11],[9, 12]]])).all() # test slice - assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], + assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() # test virtual - assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], + assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], [[ 8, 10, 12], [20, 22, 24]]])).all() assert array(1).swapaxes(10, 12) == 1 @@ -1595,7 +1595,7 @@ assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): - from numpypy import array, arange, zeros + from numpypy import arange, zeros, array a = arange(10) a[[3, 2, 1, 5]] = zeros(4, dtype=int) assert (a == [0, 0, 0, 0, 4, 0, 6, 7, 8, 9]).all() @@ -1610,12 +1610,16 @@ assert (b[array([True, False, True])] == [0, 2]).all() raises(ValueError, "array([1, 2])[array([True, True, True])]") raises(ValueError, "b[array([[True, False], [True, False]])]") + a = array([[1,2,3],[4,5,6],[7,8,9]],int) + c = array([True,False,True],bool) + b = a[c] + assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): from numpypy import arange, array b = arange(5) b[array([True, False, True])] = [20, 21, 0, 0, 0, 0, 0] - assert (b == [20, 1, 21, 3, 4]).all() + assert (b == [20, 1, 21, 3, 4]).all() raises(ValueError, "array([1, 2])[array([True, False, True])] = [1, 2, 3]") def test_weakref(self): @@ -1727,6 +1731,13 @@ b = array([1, 2, 3, 4]) assert (a == b) == False + def test__int__(self): + from numpypy import array + assert int(array(1)) == 1 + assert int(array([1])) == 1 + assert raises(TypeError, "int(array([1, 2]))") + assert int(array([1.5])) == 1 + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): @@ -2060,7 +2071,6 @@ assert isinstance(i['data'][0], int) def test_array_indexing_one_elem(self): - skip("not yet") from numpypy import array, arange raises(IndexError, 'arange(3)[array([3.5])]') a = arange(3)[array([1])] @@ -2154,6 +2164,7 @@ a = arange(10) assert (a.compress([True, False, True]) == [0, 2]).all() assert (a.compress([1, 0, 13]) == [0, 2]).all() + assert (a.compress([1, 0, 13]) == [0, 2]).all() assert (a.compress([1, 0, 13.5]) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype='>f4')) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype=' Author: Romain Guillebert Branch: Changeset: r62418:8170a9a04586 Date: 2013-03-19 00:22 +0100 http://bitbucket.org/pypy/pypy/changeset/8170a9a04586/ Log: Update what's new 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 @@ -24,6 +24,9 @@ .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality +.. branch: indexing-by-array +Adds indexing by scalar, adds int conversion from scalar and single element array, +fixes compress, indexing by an array with a smaller shape and the indexed object. .. branch: signatures Improved RPython typing From noreply at buildbot.pypy.org Tue Mar 19 00:31:26 2013 From: noreply at buildbot.pypy.org (wlav) Date: Tue, 19 Mar 2013 00:31:26 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: ValueErrors are now ValueErrors instead of TypeErrors Message-ID: <20130318233126.8D1F71C131F@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62419:98b2a64c04e0 Date: 2013-03-18 16:30 -0700 http://bitbucket.org/pypy/pypy/changeset/98b2a64c04e0/ Log: ValueErrors are now ValueErrors instead of TypeErrors diff --git a/pypy/module/cppyy/test/fragile.h b/pypy/module/cppyy/test/fragile.h --- a/pypy/module/cppyy/test/fragile.h +++ b/pypy/module/cppyy/test/fragile.h @@ -23,6 +23,7 @@ class D { public: virtual int check() { return (int)'D'; } + virtual int check(int, int) { return (int)'D'; } void overload() {} void overload(no_such_class*) {} void overload(char, int i = 0) {} // Reflex requires a named arg diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py --- a/pypy/module/cppyy/test/test_datatypes.py +++ b/pypy/module/cppyy/test/test_datatypes.py @@ -127,7 +127,7 @@ c.m_bool = 0; assert c.get_bool() == False c.set_bool(0); assert c.m_bool == False - raises(TypeError, 'c.set_bool(10)') + raises(ValueError, 'c.set_bool(10)') # char types through functions c.set_char('c'); assert c.get_char() == 'c' @@ -143,10 +143,10 @@ c.set_uchar('e'); assert c.m_uchar == 'e' c.set_uchar(43); assert c.m_uchar == chr(43) - raises(TypeError, 'c.set_char("string")') - raises(TypeError, 'c.set_char(500)') - raises(TypeError, 'c.set_uchar("string")') -# TODO: raises(TypeError, 'c.set_uchar(-1)') + raises(ValueError, 'c.set_char("string")') + raises(ValueError, 'c.set_char(500)') + raises(ValueError, 'c.set_uchar("string")') + raises(ValueError, 'c.set_uchar(-1)') # integer types names = ['short', 'ushort', 'int', 'uint', 'long', 'ulong', 'llong', 'ullong'] From noreply at buildbot.pypy.org Tue Mar 19 00:39:23 2013 From: noreply at buildbot.pypy.org (wlav) Date: Tue, 19 Mar 2013 00:39:23 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: fix Makefile for MacOS X Message-ID: <20130318233923.8E2FA1C00E4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62420:26033cd8f0a7 Date: 2013-03-18 16:38 -0700 http://bitbucket.org/pypy/pypy/changeset/26033cd8f0a7/ Log: fix Makefile for MacOS X diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -19,7 +19,7 @@ PLATFORM := $(shell uname -s) ifeq ($(PLATFORM),Darwin) - cppflags+=-dynamiclib -single_module -arch x86_64 + cppflags+=-dynamiclib -single_module -arch x86_64 -undefined dynamic_lookup endif ifeq ($(CINT),) From noreply at buildbot.pypy.org Tue Mar 19 01:02:03 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Mar 2013 01:02:03 +0100 (CET) Subject: [pypy-commit] pypy default: SSL's options macros use longs. thanks kcr Message-ID: <20130319000203.DDAA11C00E4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62421:5aac4a270cd4 Date: 2013-03-18 17:01 -0700 http://bitbucket.org/pypy/pypy/changeset/5aac4a270cd4/ Log: SSL's options macros use longs. thanks kcr diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -219,10 +219,10 @@ ssl_external('SSLv23_method', [], SSL_METHOD) ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT) ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT) -ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.INT, macro=True) -ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) +ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.LONG, macro=True) +ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.LONG], rffi.LONG, macro=True) if HAVE_SSL_CTX_CLEAR_OPTIONS: - ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, + ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.LONG], rffi.LONG, macro=True) ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT) ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void) From noreply at buildbot.pypy.org Tue Mar 19 01:04:05 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Mar 2013 01:04:05 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130319000405.A02761C131F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62422:f5e4536eeca7 Date: 2013-03-18 17:03 -0700 http://bitbucket.org/pypy/pypy/changeset/f5e4536eeca7/ Log: merge default 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 @@ -24,6 +24,9 @@ .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality +.. branch: indexing-by-array +Adds indexing by scalar, adds int conversion from scalar and single element array, +fixes compress, indexing by an array with a smaller shape and the indexed object. .. branch: signatures Improved RPython typing diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -6,7 +6,7 @@ def base(self): raise NotImplementedError - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): raise NotImplementedError class BaseArrayIterator(object): diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,5 +1,5 @@ -from pypy.module.micronumpy.arrayimpl import base +from pypy.module.micronumpy.arrayimpl import base, scalar from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException @@ -20,7 +20,7 @@ parent = None # JIT hints that length of all those arrays is a constant - + def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) @@ -71,7 +71,7 @@ new_shape, self, orig_array) else: return None - + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -79,7 +79,7 @@ dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) - return SliceArray(self.start, strides, backstrides, + return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) def get_imag(self, orig_array): @@ -87,7 +87,7 @@ backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type - return SliceArray(self.start + dtype.get_size(), strides, + return SliceArray(self.start + dtype.get_size(), strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag @@ -148,16 +148,12 @@ space.isinstance_w(w_idx, space.w_slice) or space.is_w(w_idx, space.w_None)): raise IndexError - if isinstance(w_idx, W_NDimArray): + if isinstance(w_idx, W_NDimArray) and not isinstance(w_idx.implementation, scalar.Scalar): raise ArrayArgumentException shape = self.get_shape() shape_len = len(shape) - if shape_len == 0: - raise OperationError(space.w_IndexError, space.wrap( - "0-d arrays can't be indexed")) view_w = None - if (space.isinstance_w(w_idx, space.w_list) or - isinstance(w_idx, W_NDimArray)): + if space.isinstance_w(w_idx, space.w_list): raise ArrayArgumentException if space.isinstance_w(w_idx, space.w_tuple): view_w = space.fixedview(w_idx) @@ -260,10 +256,10 @@ shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] - shape[axis1], shape[axis2] = shape[axis2], shape[axis1] + shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] - backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] - return W_NDimArray.new_slice(self.start, strides, + backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] + return W_NDimArray.new_slice(self.start, strides, backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): @@ -294,12 +290,12 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is None or shape == self.get_shape(): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, backward_broadcast) return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): @@ -330,13 +326,13 @@ free_raw_storage(self.storage, track_allocation=False) - + class NonWritableArray(ConcreteArray): def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) - + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, orig_arr, @@ -362,15 +358,16 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, + backward_broadcast) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return iter.OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -38,7 +38,7 @@ def get_strides(self): return [] - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) def get_scalar_value(self): @@ -69,7 +69,7 @@ def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - + def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -86,7 +86,7 @@ def reshape(self, space, orig_array, new_shape): return self.set_shape(space, orig_array, new_shape) - + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -19,7 +19,7 @@ def get_shape(self): return self.shape - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.base(), W_NDimArray) return self.base().create_iter() diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -15,6 +15,7 @@ from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes from pypy.module.micronumpy.interp_arrayops import repeat, choose +from pypy.module.micronumpy.arrayimpl import scalar from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -79,7 +80,11 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - res = W_NDimArray.from_shape([size], self.get_dtype()) + if len(arr.get_shape()) == 1: + res_shape = [size] + self.get_shape()[1:] + else: + res_shape = [size] + res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) def setitem_filter(self, space, idx, val): @@ -223,9 +228,10 @@ s.append('])') return s.build() - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseArrayImplementation) - return self.implementation.create_iter(shape) + return self.implementation.create_iter(shape=shape, + backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) @@ -362,8 +368,11 @@ if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for compress")) + arr = self + else: + arr = self.descr_reshape(space, [space.wrap(-1)]) index = convert_to_array(space, w_obj) - return self.getitem_filter(space, index) + return arr.getitem_filter(space, index) def descr_flatten(self, space, w_order=None): if self.is_scalar(): @@ -759,6 +768,15 @@ descr_argmax = _reduce_argmax_argmin_impl("max") descr_argmin = _reduce_argmax_argmin_impl("min") + def descr_int(self, space): + shape = self.get_shape() + if len(shape) == 0: + assert isinstance(self.implementation, scalar.Scalar) + return space.int(space.wrap(self.implementation.get_scalar_value())) + if shape == [1]: + return space.int(self.descr_getitem(space, space.wrap(0))) + raise OperationError(space.w_TypeError, space.wrap("only length-1 arrays can be converted to Python scalars")) + @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, @@ -799,6 +817,7 @@ __repr__ = interp2app(W_NDimArray.descr_repr), __str__ = interp2app(W_NDimArray.descr_str), + __int__ = interp2app(W_NDimArray.descr_int), __pos__ = interp2app(W_NDimArray.descr_pos), __neg__ = interp2app(W_NDimArray.descr_neg), 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 @@ -300,9 +300,12 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter() + shapelen = len(arr.get_shape()) + if shapelen > 1 and len(index.get_shape()) < 2: + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + else: + index_iter = index.create_iter() arr_iter = arr.create_iter() - shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -40,7 +40,7 @@ rshape += shape[s:] return rshape, rstart, rstrides, rbackstrides -def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape): +def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape, backwards=False): rstrides = [] rbackstrides = [] for i in range(len(orig_shape)): @@ -50,8 +50,12 @@ else: rstrides.append(strides[i]) rbackstrides.append(backstrides[i]) - rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides - rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides + if backwards: + rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape)) + rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape)) + else: + rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides + rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides return rstrides, rbackstrides def is_single_elem(space, w_elem, is_rec_type): 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 @@ -1357,7 +1357,7 @@ assert a[1] == 'xyz' assert a.imag[0] == 'abc' raises(TypeError, 'a.imag = "qop"') - a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) + a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) assert a.real[0,1] == 2 a.real[0,1] = -20 assert a[0,1].real == -20 @@ -1367,7 +1367,7 @@ assert a[1,2].imag == 30 a.real = 13 assert a[1,1].real == 13 - a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) + a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) a.real = 13 assert a[3].real == 13 a.imag = -5 @@ -1544,29 +1544,29 @@ from numpypy import array # testcases from numpy docstring x = array([[1, 2, 3]]) - assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() + assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() x = array([[[0,1],[2,3]],[[4,5],[6,7]]]) # shape = (2, 2, 2) - assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], - [[1, 5], [3, 7]]])).all() - assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], + assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], + [[1, 5], [3, 7]]])).all() + assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], [[2, 3], [6, 7]]])).all() - assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], + assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], [[4, 6],[5, 7]]])).all() # more complex shape i.e. (2, 2, 3) - x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) - assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], - [[4, 5, 6], [10, 11, 12]]])).all() - assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], - [[3, 9], [6, 12]]])).all() - assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], - [[7, 10], [8, 11],[9, 12]]])).all() + x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) + assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], + [[4, 5, 6], [10, 11, 12]]])).all() + assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], + [[3, 9], [6, 12]]])).all() + assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], + [[7, 10], [8, 11],[9, 12]]])).all() # test slice - assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], + assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() # test virtual - assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], + assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], [[ 8, 10, 12], [20, 22, 24]]])).all() assert array(1).swapaxes(10, 12) == 1 @@ -1595,7 +1595,7 @@ assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): - from numpypy import array, arange, zeros + from numpypy import arange, zeros, array a = arange(10) a[[3, 2, 1, 5]] = zeros(4, dtype=int) assert (a == [0, 0, 0, 0, 4, 0, 6, 7, 8, 9]).all() @@ -1610,12 +1610,16 @@ assert (b[array([True, False, True])] == [0, 2]).all() raises(ValueError, "array([1, 2])[array([True, True, True])]") raises(ValueError, "b[array([[True, False], [True, False]])]") + a = array([[1,2,3],[4,5,6],[7,8,9]],int) + c = array([True,False,True],bool) + b = a[c] + assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): from numpypy import arange, array b = arange(5) b[array([True, False, True])] = [20, 21, 0, 0, 0, 0, 0] - assert (b == [20, 1, 21, 3, 4]).all() + assert (b == [20, 1, 21, 3, 4]).all() raises(ValueError, "array([1, 2])[array([True, False, True])] = [1, 2, 3]") def test_weakref(self): @@ -1727,6 +1731,13 @@ b = array([1, 2, 3, 4]) assert (a == b) == False + def test__int__(self): + from numpypy import array + assert int(array(1)) == 1 + assert int(array([1])) == 1 + assert raises(TypeError, "int(array([1, 2]))") + assert int(array([1.5])) == 1 + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): @@ -2060,7 +2071,6 @@ assert isinstance(i['data'][0], int) def test_array_indexing_one_elem(self): - skip("not yet") from numpypy import array, arange raises(IndexError, 'arange(3)[array([3.5])]') a = arange(3)[array([1])] @@ -2154,6 +2164,7 @@ a = arange(10) assert (a.compress([True, False, True]) == [0, 2]).all() assert (a.compress([1, 0, 13]) == [0, 2]).all() + assert (a.compress([1, 0, 13]) == [0, 2]).all() assert (a.compress([1, 0, 13.5]) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype='>f4')) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype=' Author: Christian Hudon Branch: pycon2013-doc-fixes Changeset: r62423:77f67a0dcbc6 Date: 2013-03-18 15:37 -0700 http://bitbucket.org/pypy/pypy/changeset/77f67a0dcbc6/ Log: Documentation fixes after going through said doc: mention that Pygame and Graphviz should be the CPython ones; recommend cffi over ctypes or Cython; mention RPython in more titles; stackless support is not deprecated (anymore); progress on getting JIT for ARMv7. diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: From noreply at buildbot.pypy.org Tue Mar 19 01:06:16 2013 From: noreply at buildbot.pypy.org (chrish42) Date: Tue, 19 Mar 2013 01:06:16 +0100 (CET) Subject: [pypy-commit] pypy pycon2013-doc-fixes: Update whatsnew file for pycon2013-doc-fixes branch. Message-ID: <20130319000616.8D7441C131F@cobra.cs.uni-duesseldorf.de> Author: Christian Hudon Branch: pycon2013-doc-fixes Changeset: r62424:36324253c8c5 Date: 2013-03-18 16:52 -0700 http://bitbucket.org/pypy/pypy/changeset/36324253c8c5/ Log: Update whatsnew file for pycon2013-doc-fixes branch. 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 @@ -91,3 +91,6 @@ Moves optimized JIT frames from stack to heap. As a side effect it enables stackless to work well with the JIT on PyPy. Also removes a bunch of code from the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. From noreply at buildbot.pypy.org Tue Mar 19 01:06:17 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Mar 2013 01:06:17 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in chrish42/pypy/pycon2013-doc-fixes (pull request #136) Message-ID: <20130319000617.B780E1C131F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62425:0d7e2fc9f423 Date: 2013-03-18 17:06 -0700 http://bitbucket.org/pypy/pypy/changeset/0d7e2fc9f423/ Log: Merged in chrish42/pypy/pycon2013-doc-fixes (pull request #136) Documentation fixes diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: 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 @@ -94,3 +94,6 @@ Moves optimized JIT frames from stack to heap. As a side effect it enables stackless to work well with the JIT on PyPy. Also removes a bunch of code from the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. From noreply at buildbot.pypy.org Tue Mar 19 01:13:10 2013 From: noreply at buildbot.pypy.org (Karl Ramm) Date: Tue, 19 Mar 2013 01:13:10 +0100 (CET) Subject: [pypy-commit] pypy py3k: Leftover errnos were causing error misinterpretation Message-ID: <20130319001310.7270D1C00E4@cobra.cs.uni-duesseldorf.de> Author: Karl Ramm Branch: py3k Changeset: r62426:425cf5d5e4b5 Date: 2013-03-18 17:26 -0400 http://bitbucket.org/pypy/pypy/changeset/425cf5d5e4b5/ Log: Leftover errnos were causing error misinterpretation diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -8,7 +8,7 @@ from rpython.rlib.rarithmetic import intmask from rpython.rlib import rpoll, rsocket from rpython.rlib.ropenssl import * -from rpython.rlib.rposix import get_errno +from rpython.rlib.rposix import get_errno, set_errno from pypy.module._socket import interp_socket import weakref @@ -185,6 +185,8 @@ else: keyfile = space.str_w(w_keyfile) + set_errno(0) + ret = libssl_SSL_CTX_use_certificate_chain_file(self.ctx, certfile) if ret != 1: errno = get_errno() @@ -222,6 +224,7 @@ if cafile is None and capath is None: raise OperationError(space.w_TypeError, space.wrap( "cafile and capath cannot be both omitted")) + set_errno(0) ret = libssl_SSL_CTX_load_verify_locations( self.ctx, cafile, capath) if ret != 1: From noreply at buildbot.pypy.org Tue Mar 19 01:13:11 2013 From: noreply at buildbot.pypy.org (Karl Ramm) Date: Tue, 19 Mar 2013 01:13:11 +0100 (CET) Subject: [pypy-commit] pypy py3k: this should exercise the problem fixed in 383f13f771fe Message-ID: <20130319001311.B3FB01C00E4@cobra.cs.uni-duesseldorf.de> Author: Karl Ramm Branch: py3k Changeset: r62427:b7d7b92541e4 Date: 2013-03-18 17:46 -0400 http://bitbucket.org/pypy/pypy/changeset/b7d7b92541e4/ Log: this should exercise the problem fixed in 383f13f771fe diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -185,13 +185,21 @@ tmpfile = udir / "cert.pem" tmpfile.write(SSL_CERTIFICATE) cls.w_cert = cls.space.wrap(str(tmpfile)) + tmpfile = udir / "badcert.pem" + tmpfile.write(SSL_BADCERT) + cls.w_badcert = cls.space.wrap(str(tmpfile)) + tmpfile = udir / "emptycert.pem" + tmpfile.write(SSL_EMPTYCERT) + cls.w_emptycert = cls.space.wrap(str(tmpfile)) def test_load_cert_chain(self): import _ssl ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) - raises(IOError, ctx.load_cert_chain, "inexistent.pem") ctx.load_cert_chain(self.keycert) ctx.load_cert_chain(self.cert, self.key) + raises(IOError, ctx.load_cert_chain, "inexistent.pem") + raises(_ssl.SSLError, ctx.load_cert_chain, self.badcert) + raises(_ssl.SSLError, ctx.load_cert_chain, self.emptycert) def test_load_verify_locations(self): import _ssl @@ -241,3 +249,42 @@ SPIXQuT8RMPDVNQ= -----END PRIVATE KEY----- """ +SSL_BADCERT = """ +-----BEGIN RSA PRIVATE KEY----- +MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L +opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH +fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB +AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU +D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA +IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM +oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0 +ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/ +loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j +oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA +z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq +ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV +q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +Just bad cert data +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L +opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH +fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB +AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU +D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA +IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM +oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0 +ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/ +loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j +oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA +z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq +ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV +q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +Just bad cert data +-----END CERTIFICATE----- +""" +SSL_EMPTYCERT = "" From noreply at buildbot.pypy.org Tue Mar 19 01:13:12 2013 From: noreply at buildbot.pypy.org (Karl Ramm) Date: Tue, 19 Mar 2013 01:13:12 +0100 (CET) Subject: [pypy-commit] pypy py3k: Accepting that CTX_get_options was signed was causing headaches Message-ID: <20130319001312.E51951C00E4@cobra.cs.uni-duesseldorf.de> Author: Karl Ramm Branch: py3k Changeset: r62428:5ad6caf22d37 Date: 2013-03-18 18:02 -0400 http://bitbucket.org/pypy/pypy/changeset/5ad6caf22d37/ Log: Accepting that CTX_get_options was signed was causing headaches The flags in the python interpreter(s) are treated as positive numbers, but if the high bit is set it comes back out of openssl as negative. This is pedantically incorrect but produces sanity- enhancing results. (CTX_set_options is also altered similarly for consiswtency as it's the same underlying function behind the macro) diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -212,6 +212,12 @@ raises(ValueError, _ssl._SSLContext, -1) raises(ValueError, _ssl._SSLContext, 42) + def test_options(self): + import _ssl + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + assert _ssl.OP_ALL == ctx.options + + SSL_CERTIFICATE = """ -----BEGIN CERTIFICATE----- diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -219,8 +219,8 @@ ssl_external('SSLv23_method', [], SSL_METHOD) ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT) ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT) -ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.INT, macro=True) -ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) +ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.UINT, macro=True) +ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.UINT, macro=True) if HAVE_SSL_CTX_CLEAR_OPTIONS: ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) From noreply at buildbot.pypy.org Tue Mar 19 01:13:14 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Mar 2013 01:13:14 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge kcr's ssl fixes Message-ID: <20130319001314.2BF511C00E4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62429:08881cb00b0b Date: 2013-03-18 17:12 -0700 http://bitbucket.org/pypy/pypy/changeset/08881cb00b0b/ Log: merge kcr's ssl fixes diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -8,7 +8,7 @@ from rpython.rlib.rarithmetic import intmask from rpython.rlib import rpoll, rsocket from rpython.rlib.ropenssl import * -from rpython.rlib.rposix import get_errno +from rpython.rlib.rposix import get_errno, set_errno from pypy.module._socket import interp_socket import weakref @@ -185,6 +185,8 @@ else: keyfile = space.str_w(w_keyfile) + set_errno(0) + ret = libssl_SSL_CTX_use_certificate_chain_file(self.ctx, certfile) if ret != 1: errno = get_errno() @@ -222,6 +224,7 @@ if cafile is None and capath is None: raise OperationError(space.w_TypeError, space.wrap( "cafile and capath cannot be both omitted")) + set_errno(0) ret = libssl_SSL_CTX_load_verify_locations( self.ctx, cafile, capath) if ret != 1: diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -185,13 +185,21 @@ tmpfile = udir / "cert.pem" tmpfile.write(SSL_CERTIFICATE) cls.w_cert = cls.space.wrap(str(tmpfile)) + tmpfile = udir / "badcert.pem" + tmpfile.write(SSL_BADCERT) + cls.w_badcert = cls.space.wrap(str(tmpfile)) + tmpfile = udir / "emptycert.pem" + tmpfile.write(SSL_EMPTYCERT) + cls.w_emptycert = cls.space.wrap(str(tmpfile)) def test_load_cert_chain(self): import _ssl ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) - raises(IOError, ctx.load_cert_chain, "inexistent.pem") ctx.load_cert_chain(self.keycert) ctx.load_cert_chain(self.cert, self.key) + raises(IOError, ctx.load_cert_chain, "inexistent.pem") + raises(_ssl.SSLError, ctx.load_cert_chain, self.badcert) + raises(_ssl.SSLError, ctx.load_cert_chain, self.emptycert) def test_load_verify_locations(self): import _ssl @@ -204,6 +212,12 @@ raises(ValueError, _ssl._SSLContext, -1) raises(ValueError, _ssl._SSLContext, 42) + def test_options(self): + import _ssl + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + assert _ssl.OP_ALL == ctx.options + + SSL_CERTIFICATE = """ -----BEGIN CERTIFICATE----- @@ -241,3 +255,42 @@ SPIXQuT8RMPDVNQ= -----END PRIVATE KEY----- """ +SSL_BADCERT = """ +-----BEGIN RSA PRIVATE KEY----- +MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L +opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH +fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB +AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU +D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA +IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM +oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0 +ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/ +loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j +oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA +z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq +ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV +q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +Just bad cert data +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L +opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH +fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB +AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU +D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA +IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM +oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0 +ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/ +loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j +oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA +z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq +ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV +q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +Just bad cert data +-----END CERTIFICATE----- +""" +SSL_EMPTYCERT = "" From noreply at buildbot.pypy.org Tue Mar 19 01:20:21 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 19 Mar 2013 01:20:21 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): fix translation Message-ID: <20130319002021.5F9E21C00E4@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62430:d140a900b01c Date: 2013-03-18 17:18 -0700 http://bitbucket.org/pypy/pypy/changeset/d140a900b01c/ Log: (alex, fijal): fix translation diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,8 +106,15 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) + def setitem(self, w_key, w_value): + self.strategy.setitem(self, w_key, w_value) + + def setitem_str(self, key, w_value): + self.strategy.setitem_str(self, key, w_value) + + def _add_indirections(): - dict_methods = "setitem setitem_str getitem \ + dict_methods = "getitem \ getitem_str delitem length \ clear w_keys values \ items iterkeys itervalues iteritems setdefault \ diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py --- a/pypy/objspace/std/kwargsdict.py +++ b/pypy/objspace/std/kwargsdict.py @@ -43,7 +43,6 @@ return self.space.newlist([self.space.wrap(key) for key in self.unerase(w_dict.dstorage)[0]]) def setitem(self, w_dict, w_key, w_value): - space = self.space if self.is_correct_type(w_key): self.setitem_str(w_dict, self.unwrap(w_key), w_value) return From noreply at buildbot.pypy.org Tue Mar 19 01:20:22 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 19 Mar 2013 01:20:22 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130319002022.ACD991C00E4@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62431:d343da0c55a8 Date: 2013-03-18 17:20 -0700 http://bitbucket.org/pypy/pypy/changeset/d343da0c55a8/ Log: merged upstream diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: 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 @@ -94,3 +94,6 @@ Moves optimized JIT frames from stack to heap. As a side effect it enables stackless to work well with the JIT on PyPy. Also removes a bunch of code from the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -219,10 +219,10 @@ ssl_external('SSLv23_method', [], SSL_METHOD) ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT) ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT) -ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.INT, macro=True) -ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) +ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.LONG, macro=True) +ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.LONG], rffi.LONG, macro=True) if HAVE_SSL_CTX_CLEAR_OPTIONS: - ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, + ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.LONG], rffi.LONG, macro=True) ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT) ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void) From noreply at buildbot.pypy.org Tue Mar 19 01:28:00 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Mar 2013 01:28:00 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130319002800.985051C13F8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62432:c2a09b94050d Date: 2013-03-18 17:27 -0700 http://bitbucket.org/pypy/pypy/changeset/c2a09b94050d/ Log: merge default diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: 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 @@ -94,3 +94,6 @@ Moves optimized JIT frames from stack to heap. As a side effect it enables stackless to work well with the JIT on PyPy. Also removes a bunch of code from the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -107,8 +107,15 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) + def setitem(self, w_key, w_value): + self.strategy.setitem(self, w_key, w_value) + + def setitem_str(self, key, w_value): + self.strategy.setitem_str(self, key, w_value) + + def _add_indirections(): - dict_methods = "setitem setitem_str getitem \ + dict_methods = "getitem \ getitem_str delitem length \ clear w_keys values \ items iterkeys itervalues iteritems setdefault \ diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py --- a/pypy/objspace/std/kwargsdict.py +++ b/pypy/objspace/std/kwargsdict.py @@ -43,7 +43,6 @@ return self.space.newlist([self.space.wrap(key) for key in self.unerase(w_dict.dstorage)[0]]) def setitem(self, w_dict, w_key, w_value): - space = self.space if self.is_correct_type(w_key): self.setitem_str(w_dict, self.unwrap(w_key), w_value) return From noreply at buildbot.pypy.org Tue Mar 19 02:42:25 2013 From: noreply at buildbot.pypy.org (wlav) Date: Tue, 19 Mar 2013 02:42:25 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: fix sliced indexing to allow for STL-like classes Message-ID: <20130319014225.2D0571C0084@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62433:3c6f61f3f1ef Date: 2013-03-18 17:34 -0700 http://bitbucket.org/pypy/pypy/changeset/3c6f61f3f1ef/ Log: fix sliced indexing to allow for STL-like classes diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py --- a/pypy/module/cppyy/pythonify.py +++ b/pypy/module/cppyy/pythonify.py @@ -270,11 +270,16 @@ # pythonization by decoration (move to their own file?) def python_style_getitem(self, idx): # python-style indexing: check for size and allow indexing from the back - sz = len(self) - if idx < 0: idx = sz + idx - if idx < sz: - return self._getitem__unchecked(idx) - raise IndexError('index out of range: %d requested for %s of size %d' % (idx, str(self), sz)) + try: + sz = len(self) + if idx < 0: idx = sz + idx + if idx < sz: + return self._getitem__unchecked(idx) + raise IndexError( + 'index out of range: %d requested for %s of size %d' % (idx, str(self), sz)) + except TypeError: + pass + return self._getitem__unchecked(idx) def python_style_sliceable_getitem(self, slice_or_idx): if type(slice_or_idx) == types.SliceType: @@ -324,8 +329,7 @@ pyclass.__iter__ = __iter__ # combine __getitem__ and __len__ to make a pythonized __getitem__ - if not 'std::map' in pyclass.__name__ and\ - '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: + if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: pyclass._getitem__unchecked = pyclass.__getitem__ if '__setitem__' in pyclass.__dict__ and '__iadd__' in pyclass.__dict__: pyclass.__getitem__ = python_style_sliceable_getitem diff --git a/pypy/module/cppyy/test/stltypes.h b/pypy/module/cppyy/test/stltypes.h --- a/pypy/module/cppyy/test/stltypes.h +++ b/pypy/module/cppyy/test/stltypes.h @@ -10,6 +10,35 @@ int m_i; }; +//- class with lots of std::string handling +class stringy_class { +public: + stringy_class(const char* s); + + std::string get_string1(); + void get_string2(std::string& s); + + void set_string1(const std::string& s); + void set_string2(std::string s); + + std::string m_string; +}; + +//- class that has an STL-like interface +class no_dict_available; + +template +class stl_like_class { +public: + no_dict_available* begin() { return 0; } + no_dict_available* end() { return 0; } + int size() { return 4; } + int operator[](int i) { return i; } + std::string operator[](double) { return "double"; } + std::string operator[](const std::string&) { return "string"; } +}; + + #define STLTYPE_INSTANTIATION(STLTYPE, TTYPE, N) \ std::STLTYPE STLTYPE##_##N; \ std::STLTYPE::iterator STLTYPE##_##N##_i; \ @@ -52,6 +81,8 @@ }; + stl_like_class stlc_1; + } // unnamed namespace #define STLTYPES_EXPLICIT_INSTANTIATION_DECL_COMPS(STLTYPE, TTYPE) \ @@ -65,18 +96,3 @@ // comps for int only to allow testing: normal use of vector is looping over a // range-checked version of __getitem__ STLTYPES_EXPLICIT_INSTANTIATION_DECL_COMPS(vector, int) - - -//- class with lots of std::string handling -class stringy_class { -public: - stringy_class(const char* s); - - std::string get_string1(); - void get_string2(std::string& s); - - void set_string1(const std::string& s); - void set_string2(std::string s); - - std::string m_string; -}; diff --git a/pypy/module/cppyy/test/stltypes.xml b/pypy/module/cppyy/test/stltypes.xml --- a/pypy/module/cppyy/test/stltypes.xml +++ b/pypy/module/cppyy/test/stltypes.xml @@ -26,5 +26,6 @@ + diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py --- a/pypy/module/cppyy/test/test_stltypes.py +++ b/pypy/module/cppyy/test/test_stltypes.py @@ -421,3 +421,12 @@ raises(ValueError, mul.__setitem__, 'minus two', -2) + def test05_STL_like_class_indexing_overloads(self): + """Test overloading of operator[] in STL like class""" + + import cppyy + stl_like_class = cppyy.gbl.stl_like_class + + a = stl_like_class(int)() + assert a["some string" ] == 'string' + assert a[3.1415] == 'double' From noreply at buildbot.pypy.org Tue Mar 19 02:42:26 2013 From: noreply at buildbot.pypy.org (wlav) Date: Tue, 19 Mar 2013 02:42:26 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: bring std::map into CINT backend Message-ID: <20130319014226.691CF1C131F@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62434:7cf1f9e13c4e Date: 2013-03-18 18:41 -0700 http://bitbucket.org/pypy/pypy/changeset/7cf1f9e13c4e/ Log: bring std::map into CINT backend diff --git a/pypy/module/cppyy/__init__.py b/pypy/module/cppyy/__init__.py --- a/pypy/module/cppyy/__init__.py +++ b/pypy/module/cppyy/__init__.py @@ -10,6 +10,7 @@ '_resolve_name' : 'interp_cppyy.resolve_name', '_scope_byname' : 'interp_cppyy.scope_byname', '_template_byname' : 'interp_cppyy.template_byname', + '_std_string_name' : 'interp_cppyy.std_string_name', '_set_class_generator' : 'interp_cppyy.set_class_generator', '_register_class' : 'interp_cppyy.register_class', '_is_static' : 'interp_cppyy.is_static', diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py --- a/pypy/module/cppyy/capi/__init__.py +++ b/pypy/module/cppyy/capi/__init__.py @@ -7,6 +7,7 @@ identify = backend.identify pythonize = backend.pythonize register_pythonizations = backend.register_pythonizations +std_string_name = backend.std_string_name ts_reflect = backend.ts_reflect ts_call = backend.ts_call diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py --- a/pypy/module/cppyy/capi/cint_capi.py +++ b/pypy/module/cppyy/capi/cint_capi.py @@ -10,7 +10,7 @@ from rpython.rlib import libffi, rdynload -__all__ = ['identify', 'eci', 'c_load_dictionary'] +__all__ = ['identify', 'std_string_name', 'eci', 'c_load_dictionary'] pkgpath = py.path.local(__file__).dirpath().join(os.pardir) srcpath = pkgpath.join("src") @@ -37,6 +37,8 @@ ts_memory = False ts_helper = False +std_string_name = 'string' + # force loading in global mode of core libraries, rather than linking with # them as PyPy uses various version of dlopen in various places; note that # this isn't going to fly on Windows (note that locking them in objects and diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi/reflex_capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -3,7 +3,7 @@ from rpython.rlib import libffi from rpython.translator.tool.cbuild import ExternalCompilationInfo -__all__ = ['identify', 'eci', 'c_load_dictionary'] +__all__ = ['identify', 'std_string_name', 'eci', 'c_load_dictionary'] pkgpath = py.path.local(__file__).dirpath().join(os.pardir) srcpath = pkgpath.join("src") @@ -35,6 +35,8 @@ ts_memory = 'auto' ts_helper = 'auto' +std_string_name = 'std::basic_string' + eci = ExternalCompilationInfo( separate_module_files=[srcpath.join("reflexcwrapper.cxx")], include_dirs=[incpath] + rootincpath, diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -82,6 +82,9 @@ return None +def std_string_name(space): + return space.wrap(capi.std_string_name) + @unwrap_spec(w_callback=W_Root) def set_class_generator(space, w_callback): state = space.fromcache(State) diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py --- a/pypy/module/cppyy/pythonify.py +++ b/pypy/module/cppyy/pythonify.py @@ -36,7 +36,7 @@ def _arg_to_str(self, arg): if arg == str: - arg = 'std::basic_string' + arg = cppyy._std_string_name() elif type(arg) != str: arg = arg.__name__ return arg @@ -336,8 +336,8 @@ else: pyclass.__getitem__ = python_style_getitem - # string comparisons (note: CINT backend requires the simple name 'string') - if pyclass.__name__ == 'std::basic_string' or pyclass.__name__ == 'string': + # string comparisons + if pyclass.__name__ == cppyy._std_string_name(): def eq(self, other): if type(other) == pyclass: return self.c_str() == other.c_str() @@ -347,7 +347,7 @@ pyclass.__str__ = pyclass.c_str # std::pair unpacking through iteration - if 'std::pair' in pyclass.__name__: + if 'std::pair' == pyclass.__name__[:9] or 'pair' == pyclass.__name__[:4]: def getitem(self, idx): if idx == 0: return self.first if idx == 1: return self.second diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx --- a/pypy/module/cppyy/src/cintcwrapper.cxx +++ b/pypy/module/cppyy/src/cintcwrapper.cxx @@ -310,6 +310,10 @@ if (!G__defined_templateclass((char*)template_name)) return (cppyy_type_t)NULL; + // #include for specific, pre-compiled STL classes + if (strcmp(template_name, "std::map") == 0) + gROOT->ProcessLine("#include "); + // the following yields a dummy TClassRef, but its name can be queried ClassRefs_t::size_type sz = g_classrefs.size(); g_classref_indices[template_name] = sz; diff --git a/pypy/module/cppyy/test/stltypes.h b/pypy/module/cppyy/test/stltypes.h --- a/pypy/module/cppyy/test/stltypes.h +++ b/pypy/module/cppyy/test/stltypes.h @@ -74,7 +74,9 @@ struct _CppyyMapInstances { +#ifndef __CINT__ STLTYPE_INSTANTIATION2(map, int, int, 1); +#endif STLTYPE_INSTANTIATION2(map, std::string, int, 2); STLTYPE_INSTANTIATION2(map, std::string, unsigned int, 3); STLTYPE_INSTANTIATION2(map, std::string, unsigned long, 4); diff --git a/pypy/module/cppyy/test/stltypes_LinkDef.h b/pypy/module/cppyy/test/stltypes_LinkDef.h --- a/pypy/module/cppyy/test/stltypes_LinkDef.h +++ b/pypy/module/cppyy/test/stltypes_LinkDef.h @@ -8,7 +8,18 @@ #pragma link C++ class std::vector::iterator; #pragma link C++ class std::vector::const_iterator; +#pragma link C++ class map; +#pragma link C++ class map::iterator; +#pragma link C++ class map::const_iterator; +#pragma link C++ class pair; + +#pragma link C++ class map; +#pragma link C++ class map::iterator; +#pragma link C++ class map::const_iterator; +#pragma link C++ class pair; + #pragma link C++ class just_a_class; #pragma link C++ class stringy_class; +#pragma link C++ class stl_like_class; #endif From noreply at buildbot.pypy.org Tue Mar 19 06:02:58 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 06:02:58 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test Message-ID: <20130319050258.DC9D11C13F8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62435:bcb957f2c397 Date: 2013-03-18 22:02 -0700 http://bitbucket.org/pypy/pypy/changeset/bcb957f2c397/ Log: fix this test diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -1,13 +1,13 @@ from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.history import JitCellToken -from rpython.jit.backend.test.calling_convention_test import TestCallingConv, parse +from rpython.jit.backend.test.calling_convention_test import CallingConvTests, parse from rpython.rtyper.lltypesystem import lltype from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests skip_unless_run_slow_tests() -class TestARMCallingConvention(TestCallingConv): +class TestARMCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py def test_call_argument_spilling(self): From noreply at buildbot.pypy.org Tue Mar 19 06:05:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 06:05:49 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test too Message-ID: <20130319050549.197ED1C131F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62436:e282c55cfd4e Date: 2013-03-18 22:03 -0700 http://bitbucket.org/pypy/pypy/changeset/e282c55cfd4e/ Log: fix this test too 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 @@ -35,7 +35,7 @@ self.operations = [] for op in operations: if op.getdescr() is not None: - if op.is_guard(): + if op.is_guard() or op.getopnum() == rop.FINISH: newdescr = op.getdescr() else: newdescr = WeakrefDescr(op.getdescr()) From noreply at buildbot.pypy.org Tue Mar 19 06:06:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 06:06:57 +0100 (CET) Subject: [pypy-commit] pypy default: skip this test on 32bit Message-ID: <20130319050657.29DC71C131F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62437:cc48c9196071 Date: 2013-03-18 22:06 -0700 http://bitbucket.org/pypy/pypy/changeset/cc48c9196071/ Log: skip this test on 32bit diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -381,6 +381,8 @@ raise NotImplementedError def test_call_aligned_explicit_check(self): + if sys.maxint == 2 ** 31 - 1: + py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') From noreply at buildbot.pypy.org Tue Mar 19 06:43:01 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:01 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: branch to fix jit logs after merge of jitframe-on-heap Message-ID: <20130319054301.5AABC1C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62438:52be3c83ad7f Date: 2013-03-17 12:21 +0400 http://bitbucket.org/pypy/pypy/changeset/52be3c83ad7f/ Log: branch to fix jit logs after merge of jitframe-on-heap From noreply at buildbot.pypy.org Tue Mar 19 06:43:02 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:02 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: fix different bridge logging in arm and x86 Message-ID: <20130319054302.A314C1C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62439:7a0706d3f218 Date: 2013-03-17 12:29 +0400 http://bitbucket.org/pypy/pypy/changeset/7a0706d3f218/ Log: fix different bridge logging in arm and x86 diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -14,6 +14,7 @@ VFPRegisterManager, operations as regalloc_operations, operations_with_guard as regalloc_operations_with_guard) +from rpython.jit.backend.llsupport.assembler import debug_bridge from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.codewriter import longlong @@ -734,11 +735,7 @@ self.update_frame_depth(frame_depth) self.teardown() - debug_start("jit-backend-addr") - debug_print("bridge out of Guard %d has address 0x%x to 0x%x" % - (descr_number, r_uint(rawstart), - r_uint(rawstart + codeendpos))) - debug_stop("jit-backend-addr") + debug_bridge(descr_number, rawstart, codeendpos) return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -203,3 +203,12 @@ # XXX here should be emitted guard_not_forced, but due # to incompatibilities in how it's done, we leave it for the # caller to deal with + + +def debug_bridge(descr_number, rawstart, codeendpos): + debug_start("jit-backend-addr") + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart), + r_uint(rawstart + codeendpos))) + debug_stop("jit-backend-addr") + diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1,7 +1,8 @@ import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe -from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler +from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler, + debug_bridge) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt @@ -554,11 +555,7 @@ rawstart = self.materialize_loop(original_loop_token) self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, rawstart) - debug_start("jit-backend-addr") - debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % - (r_uint(descr_number), r_uint(rawstart), - r_uint(rawstart + codeendpos))) - debug_stop("jit-backend-addr") + debug_bridge(descr_number, rawstart, codeendpos) self.patch_pending_failure_recoveries(rawstart) # patch the jump from original guard self.patch_jump_for_descr(faildescr, rawstart) From noreply at buildbot.pypy.org Tue Mar 19 06:43:03 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:03 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: fix parse_log_count - use integer values here, as before Message-ID: <20130319054303.CDA181C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62440:e4e6938e287b Date: 2013-03-17 12:39 +0400 http://bitbucket.org/pypy/pypy/changeset/e4e6938e287b/ Log: fix parse_log_count - use integer values here, as before diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -414,7 +414,8 @@ def split_trace(trace): labels = [0] if trace.comment and 'Guard' in trace.comment: - descrs = ['bridge ' + re.search('Guard ([\da-f]+)', trace.comment).group(1)] + descrs = ['bridge %d' % int( + re.search('Guard ([\da-f]+)', trace.comment).group(1), 16)] else: descrs = ['entry ' + re.search('Loop (\d+)', trace.comment).group(1)] for i, op in enumerate(trace.operations): From noreply at buildbot.pypy.org Tue Mar 19 06:43:05 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:05 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: adresses are with 0x now Message-ID: <20130319054305.1C60B1C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62441:22fcf60f4283 Date: 2013-03-17 12:39 +0400 http://bitbucket.org/pypy/pypy/changeset/22fcf60f4283/ Log: adresses are with 0x now diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -364,15 +364,16 @@ def import_log(logname, ParserCls=SimpleParser): log = parse_log_file(logname) + hex_re = '0x([\da-f]+)' addrs = {} for entry in extract_category(log, 'jit-backend-addr'): - m = re.search('bootstrap ([-\da-f]+)', entry) + m = re.search('bootstrap ' + hex_re, entry) if not m: # a bridge - m = re.search('has address ([-\da-f]+)', entry) + m = re.search('has address ' + hex_re, entry) addr = int(m.group(1), 16) entry = entry.lower() - m = re.search('guard [\da-f]+', entry) + m = re.search('guard ' + hex_re, entry) name = m.group(0) else: name = entry[:entry.find('(') - 1].lower() From noreply at buildbot.pypy.org Tue Mar 19 06:43:06 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:06 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: fix jitlogparser tests to match current log format Message-ID: <20130319054306.4829E1C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62442:ac2defef83a4 Date: 2013-03-17 12:57 +0400 http://bitbucket.org/pypy/pypy/changeset/ac2defef83a4/ Log: fix jitlogparser tests to match current log format diff --git a/pypy/tool/jitlogparser/test/logtest.log b/pypy/tool/jitlogparser/test/logtest.log --- a/pypy/tool/jitlogparser/test/logtest.log +++ b/pypy/tool/jitlogparser/test/logtest.log @@ -5,7 +5,7 @@ CODE_DUMP @7f3b0b2e63d5 +0 554889E5534154415541564157488DA500000000488B042590C5540148C7042590C554010000000048898570FFFFFF488B042598C5540148C7042598C554010000000048898568FFFFFF488B0425A0C5540148C70425A0C554010000000048898560FFFFFF488B0425A8C5540148C70425A8C554010000000048898558FFFFFF4C8B3C2550525B0149BB3050920D3B7F00004D8B334983C60149BB3050920D3B7F00004D89334981FF102700000F8D000000004983C7014C8B342580F76A024983EE014C89342580F76A024983FE000F8C00000000E9AEFFFFFF488B042588F76A024829E0483B042580EC3C01760D49BB05632E0B3B7F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E954FFFFFF49BB00602E0B3B7F000041FFD34440484C3D030300000049BB00602E0B3B7F000041FFD34440484C3D070304000000 [11f210b949b3] jit-backend-dump} [11f210b949b4] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 7f3b0b2e645d to 7f3b0b2e64af (bootstrap 7f3b0b2e63d5) +Loop 0 ( #9 LOAD_FAST) has address 0x7f3b0b2e645d to 0x7f3b0b2e64af (bootstrap 0x7f3b0b2e63d5) [11f210bab188] jit-backend-addr} [11f210bab189] jit-backend} [11f210bacbb7] {jit-log-opt-loop diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -42,7 +42,7 @@ CODE_DUMP @7f8907a0b3d5 +0 554889E5534154415541564157488DA500000000488B042590C2540148C7042590C254010000000048898570FFFFFF488B042598C2540148C7042598C254010000000048898568FFFFFF488B0425A0C2540148C70425A0C254010000000048898560FFFFFF488B0425A8C2540148C70425A8C254010000000048898558FFFFFF4C8B3C25D04D5B0149BB30B00C0A897F00004D8B334983C60149BB30B00C0A897F00004D89334981FF102700000F8D000000004D89FE4983E7024983FF000F85000000004983C6034C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C000000004D89F7E99AFFFFFF488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E940FFFFFF49BB00B0A007897F000041FFD34440484C3D030300000049BB00B0A007897F000041FFD34440484C3D39030400000049BB00B0A007897F000041FFD34440484C3907070305000000 [1f5fe73276a] jit-backend-dump} [1f5fe73438f] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 7f8907a0b45d to 7f8907a0b4c3 (bootstrap 7f8907a0b3d5) +Loop 0 ( #9 LOAD_FAST) has address 0x7f8907a0b45d to 0x7f8907a0b4c3 (bootstrap 0x7f8907a0b3d5) [1f5fe7369af] jit-backend-addr} [1f5fe737940] {jit-backend-dump BACKEND x86_64 @@ -103,7 +103,7 @@ CODE_DUMP @7f8907a0b565 +0 554889E5534154415541564157488DA5000000004C8B3C2590C2540148C7042590C25401000000004C8B342598C2540148C7042598C25401000000004C8B2C25A0C2540148C70425A0C25401000000004C8B2425A8C2540148C70425A8C25401000000004C8B1425D04D5B014C8B0C25B8C2540148C70425B8C25401000000004C8B0425E04D5B01488B3C25E84D5B01488B3425D0C2540148C70425D0C2540100000000488B1C25D8C2540148C70425D8C2540100000000488B1425E0C2540148C70425E0C254010000000049BB38B00C0A897F0000498B0B4883C10149BB38B00C0A897F000049890B4983F8010F85000000004883FE017206813E980700000F85000000004983FA000F850000000049BBA8F0B407897F00004D39DC0F8500000000488B56084881FA102700000F8D000000004989D44883E2024883FA000F85000000004983C403488B1425A0536B024883EA0148891425A0536B024883FA000F8C000000004C89BD70FFFFFF4C89B568FFFFFF4C89AD60FFFFFF4C898D58FFFFFF4D89E749BB5DB4A007897F000041FFE3488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4989FF4989F64989D54989CC4D89C24C8B5D104D89D84C8B5D184C89DF4C8B5D204C89DE4C8B5D284C89DB4C8B5D304C89DAE9CCFEFFFF49BB00B0A007897F000041FFD321383C343029241D180C08030600000049BB00B0A007897F000041FFD3383C18343029240C08030700000049BB00B0A007897F000041FFD329383C3430241808030800000049BB00B0A007897F000041FFD3383C3034241808030900000049BB00B0A007897F000041FFD3383C183424030A00000049BB00B0A007897F000041FFD3383C34241809030B00000049BB00B0A007897F000041FFD3383C34243107030C000000 [1f5fee2e673] jit-backend-dump} [1f5fee2f38d] {jit-backend-addr -Loop 1 ( #9 LOAD_FAST) has address 7f8907a0b631 to 7f8907a0b6f8 (bootstrap 7f8907a0b565) +Loop 1 ( #9 LOAD_FAST) has address 0x7f8907a0b631 to 0x7f8907a0b6f8 (bootstrap 0x7f8907a0b565) [1f5fee312e3] jit-backend-addr} [1f5fee320ed] {jit-backend-dump BACKEND x86_64 @@ -189,7 +189,7 @@ CODE_DUMP @7f8907a0b817 +0 554889E5534154415541564157488DA500000000488B042590C2540148C7042590C254010000000048898570FFFFFF488B042598C2540148C7042598C254010000000048898568FFFFFF488B0425A0C2540148C70425A0C254010000000048898560FFFFFF488B0425A8C2540148C70425A8C254010000000048898558FFFFFF4C8B3C25D04D5B0149BB40B00C0A897F00004D8B334983C60149BB40B00C0A897F00004D89334981FF102700000F8D000000004D89FE4983E7024983FF000F85000000004983C6034C8B3C25A0536B024983EF024C893C25A0536B024983FF000F8C000000004D89F7E99AFFFFFF488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E940FFFFFF49BB00B0A007897F000041FFD34440484C3D030D00000049BB00B0A007897F000041FFD34440484C3D39030E00000049BB00B0A007897F000041FFD34440484C390707030F000000 [1f60076fd90] jit-backend-dump} [1f600770f30] {jit-backend-addr -Loop 2 ( #9 LOAD_FAST) has address 7f8907a0b89f to 7f8907a0b905 (bootstrap 7f8907a0b817) +Loop 2 ( #9 LOAD_FAST) has address 0x7f8907a0b89f to 0x7f8907a0b905 (bootstrap 0x7f8907a0b817) [1f6007730fc] jit-backend-addr} [1f600773fde] {jit-backend-dump BACKEND x86_64 @@ -249,7 +249,7 @@ CODE_DUMP @7f8907a0b9b7 +0 488DA50000000049BB48B00C0A897F00004D8B3B4983C70149BB48B00C0A897F00004D893B4D89F74983C6010F80000000004C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C00000000488B0425704F3D01488D5010483B1425784F3D01761A49BB10B2A007897F000041FFD349BB8EB2A007897F000041FFD348C7009807000048891425704F3D014C89700848898550FFFFFF4C8BBD70FFFFFF4C8BB568FFFFFF4C8BAD60FFFFFF49BBA8F0B407897F00004D89DC49C7C2000000004C8B8D58FFFFFF49C7C00100000048C7C709000000488BB550FFFFFF48C7C30000000048C7C20000000049BB31B6A007897F000041FFE349BB00B0A007897F000041FFD3444039484C3D031000000049BB00B0A007897F000041FFD34440484C39070311000000 [1f60086ba5a] jit-backend-dump} [1f60086d36e] {jit-backend-addr -Bridge out of guard 4 has address 7f8907a0b9b7 to 7f8907a0bab1 +Bridge out of guard 0x4 has address 0x7f8907a0b9b7 to 0x7f8907a0bab1 [1f60086ffd2] jit-backend-addr} [1f600870dca] {jit-backend-dump BACKEND x86_64 diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -339,7 +339,7 @@ bridge.comment = 'bridge out of Guard af with 1 ops' loop.comment = 'Loop 0' loops = split_trace(loop) + split_trace(bridge) - input = ['grrr:123\nasb:12\nbridge af:1234'] + input = ['grrr:123\nasb:12\nbridge 175:1234'] parse_log_counts(input, loops) assert loops[-1].count == 1234 assert loops[1].count == 123 From noreply at buildbot.pypy.org Tue Mar 19 06:43:07 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:07 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: guard is in hex in comments now Message-ID: <20130319054307.7DE001C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62443:351043f9909d Date: 2013-03-17 13:10 +0400 http://bitbucket.org/pypy/pypy/changeset/351043f9909d/ Log: guard is in hex in comments now diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -396,8 +396,8 @@ comm = loop.comment comm = comm.lower() if comm.startswith('# bridge'): - m = re.search('guard (\d+)', comm) - name = 'guard ' + hex(int(m.group(1)))[2:] + m = re.search('guard ([\da-f]+)', comm) + name = 'guard ' + m.group(1) elif "(" in comm: name = comm[2:comm.find('(')-1] else: From noreply at buildbot.pypy.org Tue Mar 19 06:43:08 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:08 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: hex_re is different now, we need to get rid of 0x here Message-ID: <20130319054308.A61921C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62444:ca4800067846 Date: 2013-03-17 13:10 +0400 http://bitbucket.org/pypy/pypy/changeset/ca4800067846/ Log: hex_re is different now, we need to get rid of 0x here diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -374,7 +374,7 @@ addr = int(m.group(1), 16) entry = entry.lower() m = re.search('guard ' + hex_re, entry) - name = m.group(0) + name = 'guard ' + m.group(1) else: name = entry[:entry.find('(') - 1].lower() addr = int(m.group(1), 16) From noreply at buildbot.pypy.org Tue Mar 19 06:43:09 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:09 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: guard with clearly non-10-base address in tests Message-ID: <20130319054309.C56BD1C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62445:e4e2d36e416b Date: 2013-03-17 13:12 +0400 http://bitbucket.org/pypy/pypy/changeset/e4e2d36e416b/ Log: guard with clearly non-10-base address in tests diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -249,7 +249,7 @@ CODE_DUMP @7f8907a0b9b7 +0 488DA50000000049BB48B00C0A897F00004D8B3B4983C70149BB48B00C0A897F00004D893B4D89F74983C6010F80000000004C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C00000000488B0425704F3D01488D5010483B1425784F3D01761A49BB10B2A007897F000041FFD349BB8EB2A007897F000041FFD348C7009807000048891425704F3D014C89700848898550FFFFFF4C8BBD70FFFFFF4C8BB568FFFFFF4C8BAD60FFFFFF49BBA8F0B407897F00004D89DC49C7C2000000004C8B8D58FFFFFF49C7C00100000048C7C709000000488BB550FFFFFF48C7C30000000048C7C20000000049BB31B6A007897F000041FFE349BB00B0A007897F000041FFD3444039484C3D031000000049BB00B0A007897F000041FFD34440484C39070311000000 [1f60086ba5a] jit-backend-dump} [1f60086d36e] {jit-backend-addr -Bridge out of guard 0x4 has address 0x7f8907a0b9b7 to 0x7f8907a0bab1 +Bridge out of guard 0x4a has address 0x7f8907a0b9b7 to 0x7f8907a0bab1 [1f60086ffd2] jit-backend-addr} [1f600870dca] {jit-backend-dump BACKEND x86_64 @@ -273,7 +273,7 @@ [1f600878f4e] jit-backend-dump} [1f600884c12] jit-backend} [1f60088780a] {jit-log-opt-bridge -# bridge out of Guard 4 with 16 ops +# bridge out of Guard 4a with 16 ops [p0, p1, p2, p3, i4, i5] debug_merge_point(0, ' #31 LOAD_FAST') debug_merge_point(0, ' #34 LOAD_CONST') From noreply at buildbot.pypy.org Tue Mar 19 06:43:11 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 19 Mar 2013 06:43:11 +0100 (CET) Subject: [pypy-commit] pypy fix-jit-logs: merge default Message-ID: <20130319054311.F0C051C00E4@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: fix-jit-logs Changeset: r62446:39cee1ab7e40 Date: 2013-03-19 09:34 +0400 http://bitbucket.org/pypy/pypy/changeset/39cee1ab7e40/ Log: merge default diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -61,6 +61,7 @@ g['SO'] = _get_so_extension() or ".so" g['SOABI'] = g['SO'].rsplit('.')[0] g['LIBDIR'] = os.path.join(sys.prefix, 'lib') + g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check global _config_vars _config_vars = g diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -364,9 +364,10 @@ self._in_transaction = False self.isolation_level = isolation_level - self._cursors = [] + self.__cursors = [] + self.__cursors_counter = 0 self.__statements = [] - self.__statement_counter = 0 + self.__statements_counter = 0 self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} @@ -394,10 +395,7 @@ def close(self): self._check_thread() - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._finalize() + self.__do_all_statements(Statement._finalize, True) if self._db: ret = _lib.sqlite3_close(self._db) @@ -469,13 +467,33 @@ exc.error_code = error_code return exc + def _remember_cursor(self, cursor): + self.__cursors.append(weakref.ref(cursor)) + self.__cursors_counter += 1 + if self.__cursors_counter < 200: + return + self.__cursors_counter = 0 + self.__cursors = [r for r in self.__cursors if r() is not None] + def _remember_statement(self, statement): self.__statements.append(weakref.ref(statement)) - self.__statement_counter += 1 + self.__statements_counter += 1 + if self.__statements_counter < 200: + return + self.__statements_counter = 0 + self.__statements = [r for r in self.__statements if r() is not None] - if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements - if ref() is not None] + def __do_all_statements(self, action, reset_cursors): + for weakref in self.__statements: + statement = weakref() + if statement is not None: + action(statement) + + if reset_cursors: + for weakref in self.__cursors: + cursor = weakref() + if cursor is not None: + cursor._reset = True @_check_thread_wrap @_check_closed_wrap @@ -528,10 +546,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() + self.__do_all_statements(Statement._reset, False) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, @@ -552,15 +567,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() - - for cursor_ref in self._cursors: - cursor = cursor_ref() - if cursor: - cursor._reset = True + self.__do_all_statements(Statement._reset, True) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, @@ -787,14 +794,9 @@ __statement = None def __init__(self, con): - self.__initialized = True - self.__connection = con - if not isinstance(con, Connection): raise TypeError - con._check_thread() - con._check_closed() - con._cursors.append(weakref.ref(self)) + self.__connection = con self.arraysize = 1 self.row_factory = None @@ -804,11 +806,12 @@ self.__description = None self.__rowcount = -1 + con._check_thread() + con._remember_cursor(self) + + self.__initialized = True + def __del__(self): - try: - self.__connection._cursors.remove(weakref.ref(self)) - except (AttributeError, ValueError): - pass if self.__statement: self.__statement._reset() @@ -883,7 +886,6 @@ self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False - return self @__check_cursor_wrap @@ -921,9 +923,10 @@ if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement) if rc == _lib.SQLITE_OK: - return self + break else: raise self.__connection._get_exception(rc) + rc = _lib.sqlite3_finalize(statement) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -1000,6 +1003,7 @@ def __init__(self, connection, sql): self.__con = connection + self.__con._remember_statement(self) if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") @@ -1027,10 +1031,9 @@ ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(sql)) self._kind = Statement._DQL - if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) - self.__con._remember_statement(self) + sql = sql.value.decode('utf-8') if _check_remaining_sql(sql): raise Warning("You can only execute one statement at a time.") diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: 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 @@ -24,6 +24,9 @@ .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality +.. branch: indexing-by-array +Adds indexing by scalar, adds int conversion from scalar and single element array, +fixes compress, indexing by an array with a smaller shape and the indexed object. .. branch: signatures Improved RPython typing @@ -91,3 +94,6 @@ Moves optimized JIT frames from stack to heap. As a side effect it enables stackless to work well with the JIT on PyPy. Also removes a bunch of code from the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -1,7 +1,14 @@ -import os, sys +import cStringIO +import os +import sys +import traceback +from errno import EINTR + from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated -from errno import EINTR + +from pypy.interpreter import debug + AUTO_DEBUG = os.getenv('PYPY_DEBUG') RECORD_INTERPLEVEL_TRACEBACK = True @@ -61,7 +68,7 @@ if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -95,7 +102,8 @@ def print_application_traceback(self, space, file=None): "NOT_RPYTHON: Dump a standard application-level traceback." - if file is None: file = sys.stderr + if file is None: + file = sys.stderr self.print_app_tb_only(file) print >> file, self.errorstr(space) @@ -130,8 +138,8 @@ def print_detailed_traceback(self, space=None, file=None): """NOT_RPYTHON: Dump a nice detailed interpreter- and application-level traceback, useful to debug the interpreter.""" - import traceback, cStringIO - if file is None: file = sys.stderr + if file is None: + file = sys.stderr f = cStringIO.StringIO() for i in range(len(self.debug_excs)-1, -1, -1): print >> f, "Traceback (interpreter-level):" @@ -144,7 +152,6 @@ self.print_app_tb_only(file) print >> file, '(application-level)', self.errorstr(space) if AUTO_DEBUG: - import debug debug.fire(self) @jit.unroll_safe @@ -174,7 +181,7 @@ # ("string", ...) ("string", ...) deprecated # (inst, None) (inst.__class__, inst) no # - w_type = self.w_type + w_type = self.w_type w_value = self.get_w_value(space) while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -211,7 +218,7 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type + self.w_type = w_type self._w_value = w_value def _exception_getclass(self, space, w_inst): @@ -327,7 +334,7 @@ from rpython.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(enumerate(attrs)) - # + class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): self.setup(w_type) @@ -336,6 +343,7 @@ for i, attr in entries: setattr(self, attr, args[i]) assert w_type is not None + def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -1,11 +1,13 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter import function, pycode, pyframe -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.astcompiler import consts from rpython.rlib import jit from rpython.tool.uid import uid +from pypy.interpreter import function, pycode, pyframe +from pypy.interpreter.astcompiler import consts +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule + + class Cell(Wrappable): "A simple container for a wrapped value." @@ -20,7 +22,7 @@ def get(self): if self.w_value is None: - raise ValueError, "get() from an empty cell" + raise ValueError("get() from an empty cell") return self.w_value def set(self, w_value): @@ -28,9 +30,9 @@ def delete(self): if self.w_value is None: - raise ValueError, "delete() on an empty cell" + raise ValueError("delete() on an empty cell") self.w_value = None - + def descr__cmp__(self, space, w_other): other = space.interpclass_w(w_other) if not isinstance(other, Cell): @@ -46,10 +48,10 @@ return space.cmp(self.w_value, other.w_value) def descr__reduce__(self, space): - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('cell_new') - if self.w_value is None: #when would this happen? + if self.w_value is None: # when would this happen? return space.newtuple([new_inst, space.newtuple([])]) tup = [self.w_value] return space.newtuple([new_inst, space.newtuple([]), @@ -57,7 +59,7 @@ def descr__setstate__(self, space, w_state): self.w_value = space.getitem(w_state, space.wrap(0)) - + def __repr__(self): """ representation for debugging purposes """ if self.w_value is None: @@ -74,10 +76,9 @@ raise OperationError(space.w_ValueError, space.wrap("Cell is empty")) - super_initialize_frame_scopes = pyframe.PyFrame.initialize_frame_scopes -super_fast2locals = pyframe.PyFrame.fast2locals -super_locals2fast = pyframe.PyFrame.locals2fast +super_fast2locals = pyframe.PyFrame.fast2locals +super_locals2fast = pyframe.PyFrame.locals2fast class __extend__(pyframe.PyFrame): @@ -132,7 +133,7 @@ def fast2locals(self): super_fast2locals(self) # cellvars are values exported to inner scopes - # freevars are values coming from outer scopes + # freevars are values coming from outer scopes freevarnames = list(self.pycode.co_cellvars) if self.pycode.co_flags & consts.CO_OPTIMIZED: freevarnames.extend(self.pycode.co_freevars) @@ -197,11 +198,11 @@ except ValueError: varname = self.getfreevarname(varindex) if self.iscellvar(varindex): - message = "local variable '%s' referenced before assignment"%varname + message = "local variable '%s' referenced before assignment" % varname w_exc_type = self.space.w_UnboundLocalError else: message = ("free variable '%s' referenced before assignment" - " in enclosing scope"%varname) + " in enclosing scope" % varname) w_exc_type = self.space.w_NameError raise OperationError(w_exc_type, self.space.wrap(message)) else: diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -29,7 +29,6 @@ if self.sthread is not None: raise geterror(self.space, "continulet already __init__ialized") sthread = build_sthread(self.space) - #workaround_disable_jit(sthread) # # hackish: build the frame "by hand", passing it the correct arguments space = self.space @@ -72,8 +71,7 @@ global_state.clear() raise geterror(self.space, "continulet already finished") self.check_sthread() - #workaround_disable_jit(self.sthread) - # + global_state.origin = self if to is None: # simple switch: going to self.h @@ -266,16 +264,6 @@ sthread = ec.stacklet_thread = SThread(space, ec) return sthread -def workaround_disable_jit(sthread): - # A bad workaround to kill the JIT anywhere in this thread. - # This forces all the frames. It's a bad workaround because - # it takes O(depth) time, and it will cause some "abort: - # vable escape" in the JIT. The goal is to prevent any frame - # from being still virtuals, because the JIT generates code - # to un-virtualizable them "on demand" by loading values based - # on FORCE_TOKEN, which is an address in the stack. - sthread.ec.force_all_frames() - # ____________________________________________________________ def permute(space, args_w): diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -350,7 +350,11 @@ def remove(self, w_iobase): holder = w_iobase.streamholder if holder is not None: - del self.streams[holder] + try: + del self.streams[holder] + except KeyError: + # this can happen in daemon threads + pass def flush_all(self, space): while self.streams: diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -6,7 +6,7 @@ def base(self): raise NotImplementedError - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): raise NotImplementedError class BaseArrayIterator(object): diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,5 +1,5 @@ -from pypy.module.micronumpy.arrayimpl import base +from pypy.module.micronumpy.arrayimpl import base, scalar from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException @@ -20,7 +20,7 @@ parent = None # JIT hints that length of all those arrays is a constant - + def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) @@ -71,7 +71,7 @@ new_shape, self, orig_array) else: return None - + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -79,7 +79,7 @@ dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) - return SliceArray(self.start, strides, backstrides, + return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) def get_imag(self, orig_array): @@ -87,7 +87,7 @@ backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type - return SliceArray(self.start + dtype.get_size(), strides, + return SliceArray(self.start + dtype.get_size(), strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag @@ -148,16 +148,12 @@ space.isinstance_w(w_idx, space.w_slice) or space.is_w(w_idx, space.w_None)): raise IndexError - if isinstance(w_idx, W_NDimArray): + if isinstance(w_idx, W_NDimArray) and not isinstance(w_idx.implementation, scalar.Scalar): raise ArrayArgumentException shape = self.get_shape() shape_len = len(shape) - if shape_len == 0: - raise OperationError(space.w_IndexError, space.wrap( - "0-d arrays can't be indexed")) view_w = None - if (space.isinstance_w(w_idx, space.w_list) or - isinstance(w_idx, W_NDimArray)): + if space.isinstance_w(w_idx, space.w_list): raise ArrayArgumentException if space.isinstance_w(w_idx, space.w_tuple): view_w = space.fixedview(w_idx) @@ -260,10 +256,10 @@ shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] - shape[axis1], shape[axis2] = shape[axis2], shape[axis1] + shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] - backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] - return W_NDimArray.new_slice(self.start, strides, + backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] + return W_NDimArray.new_slice(self.start, strides, backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): @@ -294,12 +290,12 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is None or shape == self.get_shape(): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, backward_broadcast) return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): @@ -330,13 +326,13 @@ free_raw_storage(self.storage, track_allocation=False) - + class NonWritableArray(ConcreteArray): def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) - + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, orig_arr, @@ -362,15 +358,16 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, + backward_broadcast) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return iter.OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -38,7 +38,7 @@ def get_strides(self): return [] - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) def get_scalar_value(self): @@ -69,7 +69,7 @@ def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - + def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -86,7 +86,7 @@ def reshape(self, space, orig_array, new_shape): return self.set_shape(space, orig_array, new_shape) - + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -19,7 +19,7 @@ def get_shape(self): return self.shape - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.base(), W_NDimArray) return self.base().create_iter() diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -15,6 +15,7 @@ from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes from pypy.module.micronumpy.interp_arrayops import repeat, choose +from pypy.module.micronumpy.arrayimpl import scalar from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -79,7 +80,11 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - res = W_NDimArray.from_shape([size], self.get_dtype()) + if len(arr.get_shape()) == 1: + res_shape = [size] + self.get_shape()[1:] + else: + res_shape = [size] + res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) def setitem_filter(self, space, idx, val): @@ -223,9 +228,10 @@ s.append('])') return s.build() - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseArrayImplementation) - return self.implementation.create_iter(shape) + return self.implementation.create_iter(shape=shape, + backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) @@ -362,8 +368,11 @@ if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for compress")) + arr = self + else: + arr = self.descr_reshape(space, [space.wrap(-1)]) index = convert_to_array(space, w_obj) - return self.getitem_filter(space, index) + return arr.getitem_filter(space, index) def descr_flatten(self, space, w_order=None): if self.is_scalar(): @@ -759,6 +768,15 @@ descr_argmax = _reduce_argmax_argmin_impl("max") descr_argmin = _reduce_argmax_argmin_impl("min") + def descr_int(self, space): + shape = self.get_shape() + if len(shape) == 0: + assert isinstance(self.implementation, scalar.Scalar) + return space.int(space.wrap(self.implementation.get_scalar_value())) + if shape == [1]: + return space.int(self.descr_getitem(space, space.wrap(0))) + raise OperationError(space.w_TypeError, space.wrap("only length-1 arrays can be converted to Python scalars")) + @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, @@ -799,6 +817,7 @@ __repr__ = interp2app(W_NDimArray.descr_repr), __str__ = interp2app(W_NDimArray.descr_str), + __int__ = interp2app(W_NDimArray.descr_int), __pos__ = interp2app(W_NDimArray.descr_pos), __neg__ = interp2app(W_NDimArray.descr_neg), 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 @@ -300,9 +300,12 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter() + shapelen = len(arr.get_shape()) + if shapelen > 1 and len(index.get_shape()) < 2: + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + else: + index_iter = index.create_iter() arr_iter = arr.create_iter() - shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -40,7 +40,7 @@ rshape += shape[s:] return rshape, rstart, rstrides, rbackstrides -def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape): +def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape, backwards=False): rstrides = [] rbackstrides = [] for i in range(len(orig_shape)): @@ -50,8 +50,12 @@ else: rstrides.append(strides[i]) rbackstrides.append(backstrides[i]) - rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides - rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides + if backwards: + rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape)) + rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape)) + else: + rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides + rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides return rstrides, rbackstrides def is_single_elem(space, w_elem, is_rec_type): 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 @@ -1357,7 +1357,7 @@ assert a[1] == 'xyz' assert a.imag[0] == 'abc' raises(TypeError, 'a.imag = "qop"') - a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) + a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) assert a.real[0,1] == 2 a.real[0,1] = -20 assert a[0,1].real == -20 @@ -1367,7 +1367,7 @@ assert a[1,2].imag == 30 a.real = 13 assert a[1,1].real == 13 - a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) + a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) a.real = 13 assert a[3].real == 13 a.imag = -5 @@ -1544,29 +1544,29 @@ from numpypy import array # testcases from numpy docstring x = array([[1, 2, 3]]) - assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() + assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() x = array([[[0,1],[2,3]],[[4,5],[6,7]]]) # shape = (2, 2, 2) - assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], - [[1, 5], [3, 7]]])).all() - assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], + assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], + [[1, 5], [3, 7]]])).all() + assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], [[2, 3], [6, 7]]])).all() - assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], + assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], [[4, 6],[5, 7]]])).all() # more complex shape i.e. (2, 2, 3) - x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) - assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], - [[4, 5, 6], [10, 11, 12]]])).all() - assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], - [[3, 9], [6, 12]]])).all() - assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], - [[7, 10], [8, 11],[9, 12]]])).all() + x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) + assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], + [[4, 5, 6], [10, 11, 12]]])).all() + assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], + [[3, 9], [6, 12]]])).all() + assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], + [[7, 10], [8, 11],[9, 12]]])).all() # test slice - assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], + assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() # test virtual - assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], + assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], [[ 8, 10, 12], [20, 22, 24]]])).all() assert array(1).swapaxes(10, 12) == 1 @@ -1595,7 +1595,7 @@ assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): - from numpypy import array, arange, zeros + from numpypy import arange, zeros, array a = arange(10) a[[3, 2, 1, 5]] = zeros(4, dtype=int) assert (a == [0, 0, 0, 0, 4, 0, 6, 7, 8, 9]).all() @@ -1610,12 +1610,16 @@ assert (b[array([True, False, True])] == [0, 2]).all() raises(ValueError, "array([1, 2])[array([True, True, True])]") raises(ValueError, "b[array([[True, False], [True, False]])]") + a = array([[1,2,3],[4,5,6],[7,8,9]],int) + c = array([True,False,True],bool) + b = a[c] + assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): from numpypy import arange, array b = arange(5) b[array([True, False, True])] = [20, 21, 0, 0, 0, 0, 0] - assert (b == [20, 1, 21, 3, 4]).all() + assert (b == [20, 1, 21, 3, 4]).all() raises(ValueError, "array([1, 2])[array([True, False, True])] = [1, 2, 3]") def test_weakref(self): @@ -1727,6 +1731,13 @@ b = array([1, 2, 3, 4]) assert (a == b) == False + def test__int__(self): + from numpypy import array + assert int(array(1)) == 1 + assert int(array([1])) == 1 + assert raises(TypeError, "int(array([1, 2]))") + assert int(array([1.5])) == 1 + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): @@ -2060,7 +2071,6 @@ assert isinstance(i['data'][0], int) def test_array_indexing_one_elem(self): - skip("not yet") from numpypy import array, arange raises(IndexError, 'arange(3)[array([3.5])]') a = arange(3)[array([1])] @@ -2154,6 +2164,7 @@ a = arange(10) assert (a.compress([True, False, True]) == [0, 2]).all() assert (a.compress([1, 0, 13]) == [0, 2]).all() + assert (a.compress([1, 0, 13]) == [0, 2]).all() assert (a.compress([1, 0, 13.5]) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype='>f4')) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype=' lr # @@ -755,7 +729,6 @@ self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), expected_size=expected_size) - def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. @@ -949,7 +922,7 @@ effectinfo = op.getdescr().get_extra_info() oopspecindex = effectinfo.oopspecindex asm_llong_operations[oopspecindex](self, op, arglocs, regalloc, fcond) - return fcond + return fcond def regalloc_emit_math(self, op, arglocs, fcond, regalloc): effectinfo = op.getdescr().get_extra_info() @@ -1072,7 +1045,6 @@ assert 0, 'unsupported case' def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL): - pushed = False if loc.is_reg(): assert prev_loc.type != FLOAT, 'trying to load from an \ incompatible location into a core register' @@ -1296,7 +1268,6 @@ self.store_reg(mc, r.ip, r.fp, ofs) - def not_implemented(msg): os.write(2, '[ARM/asm] %s\n' % msg) raise NotImplementedError(msg) diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -1,13 +1,13 @@ from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.history import JitCellToken -from rpython.jit.backend.test.calling_convention_test import TestCallingConv, parse +from rpython.jit.backend.test.calling_convention_test import CallingConvTests, parse from rpython.rtyper.lltypesystem import lltype from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests skip_unless_run_slow_tests() -class TestARMCallingConvention(TestCallingConv): +class TestARMCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py def test_call_argument_spilling(self): 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 @@ -35,7 +35,7 @@ self.operations = [] for op in operations: if op.getdescr() is not None: - if op.is_guard(): + if op.is_guard() or op.getopnum() == rop.FINISH: newdescr = op.getdescr() else: newdescr = WeakrefDescr(op.getdescr()) diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,14 +1,24 @@ - +from rpython.jit.backend.llsupport import jitframe +from rpython.jit.backend.llsupport.memcpy import memcpy_fn +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.metainterp.history import (INT, REF, FLOAT, JitCellToken, + ConstInt, BoxInt) +from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib import rgc +from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints, + debug_print) from rpython.rlib.rarithmetic import r_uint -from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.backend.llsupport import jitframe -from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.jit.backend.llsupport.memcpy import memcpy_fn -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints) + + +DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', + # 'b'ridge, 'l'abel or # 'e'ntry point + ('i', lltype.Signed), + ('type', lltype.Char), + ('number', lltype.Signed) +) + class GuardToken(object): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, @@ -204,6 +214,18 @@ # to incompatibilities in how it's done, we leave it for the # caller to deal with + def _append_debugging_code(self, operations, tp, number, token): + counter = self._register_counter(tp, number, token) + c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) + box = BoxInt() + box2 = BoxInt() + ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], + box, descr=self.debug_counter_descr), + ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), + ResOperation(rop.SETFIELD_RAW, [c_adr, box2], + None, descr=self.debug_counter_descr)] + operations.extend(ops) + def debug_bridge(descr_number, rawstart, codeendpos): debug_start("jit-backend-addr") diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -381,6 +381,8 @@ raise NotImplementedError def test_call_aligned_explicit_check(self): + if sys.maxint == 2 ** 31 - 1: + py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1,11 +1,12 @@ +import sys +import os -import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler, - debug_bridge) + DEBUG_COUNTER, debug_bridge) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap -from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt +from rpython.jit.metainterp.history import Const, Box from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop @@ -24,7 +25,7 @@ imm0, imm1, FloatImmedLoc, RawEbpLoc, RawEspLoc) from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.backend.x86 import rx86, codebuf -from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.x86 import support from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rlib import rgc @@ -35,17 +36,15 @@ from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import compute_unique_id + # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, # better safe than sorry CALL_ALIGN = 16 // WORD + def align_stack_words(words): return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) -DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), - ('type', lltype.Char), # 'b'ridge, 'l'abel or - # 'e'ntry point - ('number', lltype.Signed)) class Assembler386(BaseAssembler): _regalloc = None @@ -744,18 +743,6 @@ targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None - def _append_debugging_code(self, operations, tp, number, token): - counter = self._register_counter(tp, number, token) - c_adr = ConstInt(rffi.cast(lltype.Signed, counter)) - box = BoxInt() - box2 = BoxInt() - ops = [ResOperation(rop.GETFIELD_RAW, [c_adr], - box, descr=self.debug_counter_descr), - ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2), - ResOperation(rop.SETFIELD_RAW, [c_adr, box2], - None, descr=self.debug_counter_descr)] - operations.extend(ops) - @specialize.argtype(1) def _inject_debugging_code(self, looptoken, operations, tp, number): if self._debug: @@ -2231,7 +2218,7 @@ def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mc.CMP_mi((eax.value, ofs), value) + self.mc.CMP(mem(eax, ofs), imm(value)) # patched later self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' return self.mc.get_relative_pos() diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -1,6 +1,5 @@ - from rpython.rtyper.tool import rffi_platform -from rpython.rtyper.lltypesystem import rffi, lltype, llmemory +from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rposix from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.nonconst import NonConstant @@ -12,10 +11,7 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" -_LINUX = "linux" in sys.platform _64BIT = "64bit" in platform.architecture()[0] -_ARM = platform.machine().startswith('arm') -_PPC = platform.machine().startswith('ppc') _CYGWIN = "cygwin" == sys.platform class RValueError(Exception): @@ -30,7 +26,7 @@ if _POSIX: includes += ['unistd.h', 'sys/mman.h'] elif _MS_WINDOWS: - includes += ['winsock2.h','windows.h'] + includes += ['winsock2.h', 'windows.h'] class CConfig: _compilation_info_ = ExternalCompilationInfo( @@ -78,7 +74,7 @@ from rpython.rlib.rwin32 import NULL_HANDLE, INVALID_HANDLE_VALUE from rpython.rlib.rwin32 import DWORD, WORD, DWORD_PTR, LPDWORD from rpython.rlib.rwin32 import BOOL, LPVOID, LPCSTR, SIZE_T - from rpython.rlib.rwin32 import INT, LONG, PLONG + from rpython.rlib.rwin32 import LONG, PLONG # export the constants inside and outside. see __init__.py cConfig = rffi_platform.configure(CConfig) @@ -128,7 +124,7 @@ if _POSIX: has_mremap = cConfig['has_mremap'] c_mmap, c_mmap_safe = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, - rffi.INT, off_t], PTR, macro=True) + rffi.INT, off_t], PTR, macro=True) # 'mmap' on linux32 is a macro that calls 'mmap64' _, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT) c_msync, _ = external('msync', [PTR, size_t, rffi.INT], rffi.INT) @@ -138,7 +134,7 @@ # this one is always safe _pagesize = rffi_platform.getintegerfunctionresult('getpagesize', - includes=includes) + includes=includes) _get_allocation_granularity = _get_page_size = lambda: _pagesize elif _MS_WINDOWS: @@ -150,13 +146,13 @@ 'SYSINFO_STRUCT', ("wProcessorArchitecture", WORD), ("wReserved", WORD), - ) + ) SYSINFO_UNION = rffi.CStruct( 'union SYSINFO_UNION', ("dwOemId", DWORD), ("_struct_", SYSINFO_STRUCT), - ) + ) # sorry, I can't find a way to insert the above # because the union field has no name SYSTEM_INFO = rffi_platform.Struct( @@ -209,7 +205,6 @@ VirtualFree = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) - def _get_page_size(): try: si = rffi.make(SYSTEM_INFO) @@ -493,14 +488,6 @@ # this is not checked return res elif _POSIX: -## XXX why is this code here? There is no equivalent in CPython -## if _LINUX: -## # alignment of the address -## value = cast(self.data, c_void_p).value -## aligned_value = value & ~(PAGESIZE - 1) -## # the size should be increased too. otherwise the final -## # part is not "msynced" -## new_size = size + value & (PAGESIZE - 1) res = c_msync(start, size, MS_SYNC) if res == -1: errno = rposix.get_errno() @@ -515,7 +502,7 @@ # check boundings if (src < 0 or dest < 0 or count < 0 or - src + count > self.size or dest + count > self.size): + src + count > self.size or dest + count > self.size): raise RValueError("source or destination out of range") datasrc = self.getptr(src) @@ -567,10 +554,9 @@ SetEndOfFile(self.file_handle) # create another mapping object and remap the file view res = CreateFileMapping(self.file_handle, NULL, PAGE_READWRITE, - newsize_high, newsize_low, self.tagname) + newsize_high, newsize_low, self.tagname) self.map_handle = res - dwErrCode = 0 if self.map_handle: data = MapViewOfFile(self.map_handle, FILE_MAP_WRITE, offset_high, offset_low, newsize) @@ -603,7 +589,7 @@ if len(value) != 1: raise RValueError("mmap assignment must be " - "single-character string") + "single-character string") if index < 0: index += self.size self.data[index] = value[0] @@ -614,12 +600,12 @@ if _POSIX: def mmap(fileno, length, flags=MAP_SHARED, - prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0): + prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0): fd = fileno # check access is not there when flags and prot are there - if access != _ACCESS_DEFAULT and ((flags != MAP_SHARED) or\ + if access != _ACCESS_DEFAULT and ((flags != MAP_SHARED) or (prot != (PROT_WRITE | PROT_READ))): raise RValueError("mmap can't specify both access and flags, prot.") @@ -771,8 +757,8 @@ pass # ignore non-seeking files and errors and trust map_size else: if not high and low <= sys.maxint: - size = low - else: + size = low + else: # not so sure if the signed/unsigned strictness is a good idea: high = rffi.cast(lltype.Unsigned, high) low = rffi.cast(lltype.Unsigned, low) @@ -866,7 +852,7 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT|MEM_RESERVE, + res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -219,10 +219,10 @@ ssl_external('SSLv23_method', [], SSL_METHOD) ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT) ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT) -ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.INT, macro=True) -ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) +ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.LONG, macro=True) +ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.LONG], rffi.LONG, macro=True) if HAVE_SSL_CTX_CLEAR_OPTIONS: - ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, + ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.LONG], rffi.LONG, macro=True) ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT) ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void) diff --git a/rpython/rlib/test/test_signature.py b/rpython/rlib/test/test_signature.py --- a/rpython/rlib/test/test_signature.py +++ b/rpython/rlib/test/test_signature.py @@ -248,3 +248,39 @@ exc = py.test.raises(Exception, annotate_at, C.incomplete_sig_meth).value assert 'incomplete_sig_meth' in repr(exc.args) assert 'finishsigs' in repr(exc.args) + +def test_any_as_argument(): + @signature(types.any(), types.int(), returns=types.float()) + def f(x, y): + return x + y + @signature(types.int(), returns=types.float()) + def g(x): + return f(x, x) + sig = getsig(g) + assert sig == [model.SomeInteger(), model.SomeFloat()] + + @signature(types.float(), returns=types.float()) + def g(x): + return f(x, 4) + sig = getsig(g) + assert sig == [model.SomeFloat(), model.SomeFloat()] + + @signature(types.str(), returns=types.int()) + def cannot_add_string(x): + return f(x, 2) + exc = py.test.raises(Exception, annotate_at, cannot_add_string).value + assert 'Blocked block' in repr(exc.args) + +def test_return_any(): + @signature(types.int(), returns=types.any()) + def f(x): + return x + sig = getsig(f) + assert sig == [model.SomeInteger(), model.SomeInteger()] + + @signature(types.str(), returns=types.any()) + def cannot_add_string(x): + return f(3) + x + exc = py.test.raises(Exception, annotate_at, cannot_add_string).value + assert 'Blocked block' in repr(exc.args) + assert 'cannot_add_string' in repr(exc.args) diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py --- a/rpython/rlib/types.py +++ b/rpython/rlib/types.py @@ -63,3 +63,10 @@ def self(): return SelfTypeMarker() + + +class AnyTypeMarker(object): + pass + +def any(): + return AnyTypeMarker() diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -44,7 +44,6 @@ _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" -_LINUX = "linux" in sys.platform _64BIT = "64bit" in host_platform.architecture()[0] @@ -70,7 +69,7 @@ return ctype() def do_allocation_in_far_regions(): - """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on Linux, + """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on POSIX, which helps test this module for address values that are signed or unsigned. @@ -87,18 +86,20 @@ if _64BIT: PIECESIZE = 0x80000000 else: - if _LINUX: + if _POSIX: PIECESIZE = 0x10000000 else: PIECESIZE = 0x08000000 PIECES = 10 flags = (0,) - if _LINUX: + if _POSIX: flags = (rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS|rmmap.MAP_NORESERVE, rmmap.PROT_READ|rmmap.PROT_WRITE) - if _MS_WINDOWS: + elif _MS_WINDOWS: flags = (rmmap.MEM_RESERVE,) # XXX seems not to work + else: + assert False # should always generate flags m = rmmap.mmap(-1, PIECES * PIECESIZE, *flags) m.close = lambda : None # leak instead of giving a spurious # error at CPython's shutdown From noreply at buildbot.pypy.org Tue Mar 19 06:43:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 06:43:13 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in kostialopuhin/pypy/fix-jit-logs (pull request #133) Message-ID: <20130319054313.3F2691C00E4@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62447:b81a1cf579e0 Date: 2013-03-18 22:42 -0700 http://bitbucket.org/pypy/pypy/changeset/b81a1cf579e0/ Log: Merged in kostialopuhin/pypy/fix-jit-logs (pull request #133) Fix jitlogparser after changes in jit logging from jitframe-on-heap branch diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -364,16 +364,17 @@ def import_log(logname, ParserCls=SimpleParser): log = parse_log_file(logname) + hex_re = '0x([\da-f]+)' addrs = {} for entry in extract_category(log, 'jit-backend-addr'): - m = re.search('bootstrap ([-\da-f]+)', entry) + m = re.search('bootstrap ' + hex_re, entry) if not m: # a bridge - m = re.search('has address ([-\da-f]+)', entry) + m = re.search('has address ' + hex_re, entry) addr = int(m.group(1), 16) entry = entry.lower() - m = re.search('guard [\da-f]+', entry) - name = m.group(0) + m = re.search('guard ' + hex_re, entry) + name = 'guard ' + m.group(1) else: name = entry[:entry.find('(') - 1].lower() addr = int(m.group(1), 16) @@ -395,8 +396,8 @@ comm = loop.comment comm = comm.lower() if comm.startswith('# bridge'): - m = re.search('guard (\d+)', comm) - name = 'guard ' + hex(int(m.group(1)))[2:] + m = re.search('guard ([\da-f]+)', comm) + name = 'guard ' + m.group(1) elif "(" in comm: name = comm[2:comm.find('(')-1] else: @@ -414,7 +415,8 @@ def split_trace(trace): labels = [0] if trace.comment and 'Guard' in trace.comment: - descrs = ['bridge ' + re.search('Guard ([\da-f]+)', trace.comment).group(1)] + descrs = ['bridge %d' % int( + re.search('Guard ([\da-f]+)', trace.comment).group(1), 16)] else: descrs = ['entry ' + re.search('Loop (\d+)', trace.comment).group(1)] for i, op in enumerate(trace.operations): diff --git a/pypy/tool/jitlogparser/test/logtest.log b/pypy/tool/jitlogparser/test/logtest.log --- a/pypy/tool/jitlogparser/test/logtest.log +++ b/pypy/tool/jitlogparser/test/logtest.log @@ -5,7 +5,7 @@ CODE_DUMP @7f3b0b2e63d5 +0 554889E5534154415541564157488DA500000000488B042590C5540148C7042590C554010000000048898570FFFFFF488B042598C5540148C7042598C554010000000048898568FFFFFF488B0425A0C5540148C70425A0C554010000000048898560FFFFFF488B0425A8C5540148C70425A8C554010000000048898558FFFFFF4C8B3C2550525B0149BB3050920D3B7F00004D8B334983C60149BB3050920D3B7F00004D89334981FF102700000F8D000000004983C7014C8B342580F76A024983EE014C89342580F76A024983FE000F8C00000000E9AEFFFFFF488B042588F76A024829E0483B042580EC3C01760D49BB05632E0B3B7F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E954FFFFFF49BB00602E0B3B7F000041FFD34440484C3D030300000049BB00602E0B3B7F000041FFD34440484C3D070304000000 [11f210b949b3] jit-backend-dump} [11f210b949b4] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 7f3b0b2e645d to 7f3b0b2e64af (bootstrap 7f3b0b2e63d5) +Loop 0 ( #9 LOAD_FAST) has address 0x7f3b0b2e645d to 0x7f3b0b2e64af (bootstrap 0x7f3b0b2e63d5) [11f210bab188] jit-backend-addr} [11f210bab189] jit-backend} [11f210bacbb7] {jit-log-opt-loop diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -42,7 +42,7 @@ CODE_DUMP @7f8907a0b3d5 +0 554889E5534154415541564157488DA500000000488B042590C2540148C7042590C254010000000048898570FFFFFF488B042598C2540148C7042598C254010000000048898568FFFFFF488B0425A0C2540148C70425A0C254010000000048898560FFFFFF488B0425A8C2540148C70425A8C254010000000048898558FFFFFF4C8B3C25D04D5B0149BB30B00C0A897F00004D8B334983C60149BB30B00C0A897F00004D89334981FF102700000F8D000000004D89FE4983E7024983FF000F85000000004983C6034C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C000000004D89F7E99AFFFFFF488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E940FFFFFF49BB00B0A007897F000041FFD34440484C3D030300000049BB00B0A007897F000041FFD34440484C3D39030400000049BB00B0A007897F000041FFD34440484C3907070305000000 [1f5fe73276a] jit-backend-dump} [1f5fe73438f] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 7f8907a0b45d to 7f8907a0b4c3 (bootstrap 7f8907a0b3d5) +Loop 0 ( #9 LOAD_FAST) has address 0x7f8907a0b45d to 0x7f8907a0b4c3 (bootstrap 0x7f8907a0b3d5) [1f5fe7369af] jit-backend-addr} [1f5fe737940] {jit-backend-dump BACKEND x86_64 @@ -103,7 +103,7 @@ CODE_DUMP @7f8907a0b565 +0 554889E5534154415541564157488DA5000000004C8B3C2590C2540148C7042590C25401000000004C8B342598C2540148C7042598C25401000000004C8B2C25A0C2540148C70425A0C25401000000004C8B2425A8C2540148C70425A8C25401000000004C8B1425D04D5B014C8B0C25B8C2540148C70425B8C25401000000004C8B0425E04D5B01488B3C25E84D5B01488B3425D0C2540148C70425D0C2540100000000488B1C25D8C2540148C70425D8C2540100000000488B1425E0C2540148C70425E0C254010000000049BB38B00C0A897F0000498B0B4883C10149BB38B00C0A897F000049890B4983F8010F85000000004883FE017206813E980700000F85000000004983FA000F850000000049BBA8F0B407897F00004D39DC0F8500000000488B56084881FA102700000F8D000000004989D44883E2024883FA000F85000000004983C403488B1425A0536B024883EA0148891425A0536B024883FA000F8C000000004C89BD70FFFFFF4C89B568FFFFFF4C89AD60FFFFFF4C898D58FFFFFF4D89E749BB5DB4A007897F000041FFE3488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4989FF4989F64989D54989CC4D89C24C8B5D104D89D84C8B5D184C89DF4C8B5D204C89DE4C8B5D284C89DB4C8B5D304C89DAE9CCFEFFFF49BB00B0A007897F000041FFD321383C343029241D180C08030600000049BB00B0A007897F000041FFD3383C18343029240C08030700000049BB00B0A007897F000041FFD329383C3430241808030800000049BB00B0A007897F000041FFD3383C3034241808030900000049BB00B0A007897F000041FFD3383C183424030A00000049BB00B0A007897F000041FFD3383C34241809030B00000049BB00B0A007897F000041FFD3383C34243107030C000000 [1f5fee2e673] jit-backend-dump} [1f5fee2f38d] {jit-backend-addr -Loop 1 ( #9 LOAD_FAST) has address 7f8907a0b631 to 7f8907a0b6f8 (bootstrap 7f8907a0b565) +Loop 1 ( #9 LOAD_FAST) has address 0x7f8907a0b631 to 0x7f8907a0b6f8 (bootstrap 0x7f8907a0b565) [1f5fee312e3] jit-backend-addr} [1f5fee320ed] {jit-backend-dump BACKEND x86_64 @@ -189,7 +189,7 @@ CODE_DUMP @7f8907a0b817 +0 554889E5534154415541564157488DA500000000488B042590C2540148C7042590C254010000000048898570FFFFFF488B042598C2540148C7042598C254010000000048898568FFFFFF488B0425A0C2540148C70425A0C254010000000048898560FFFFFF488B0425A8C2540148C70425A8C254010000000048898558FFFFFF4C8B3C25D04D5B0149BB40B00C0A897F00004D8B334983C60149BB40B00C0A897F00004D89334981FF102700000F8D000000004D89FE4983E7024983FF000F85000000004983C6034C8B3C25A0536B024983EF024C893C25A0536B024983FF000F8C000000004D89F7E99AFFFFFF488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E940FFFFFF49BB00B0A007897F000041FFD34440484C3D030D00000049BB00B0A007897F000041FFD34440484C3D39030E00000049BB00B0A007897F000041FFD34440484C390707030F000000 [1f60076fd90] jit-backend-dump} [1f600770f30] {jit-backend-addr -Loop 2 ( #9 LOAD_FAST) has address 7f8907a0b89f to 7f8907a0b905 (bootstrap 7f8907a0b817) +Loop 2 ( #9 LOAD_FAST) has address 0x7f8907a0b89f to 0x7f8907a0b905 (bootstrap 0x7f8907a0b817) [1f6007730fc] jit-backend-addr} [1f600773fde] {jit-backend-dump BACKEND x86_64 @@ -249,7 +249,7 @@ CODE_DUMP @7f8907a0b9b7 +0 488DA50000000049BB48B00C0A897F00004D8B3B4983C70149BB48B00C0A897F00004D893B4D89F74983C6010F80000000004C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C00000000488B0425704F3D01488D5010483B1425784F3D01761A49BB10B2A007897F000041FFD349BB8EB2A007897F000041FFD348C7009807000048891425704F3D014C89700848898550FFFFFF4C8BBD70FFFFFF4C8BB568FFFFFF4C8BAD60FFFFFF49BBA8F0B407897F00004D89DC49C7C2000000004C8B8D58FFFFFF49C7C00100000048C7C709000000488BB550FFFFFF48C7C30000000048C7C20000000049BB31B6A007897F000041FFE349BB00B0A007897F000041FFD3444039484C3D031000000049BB00B0A007897F000041FFD34440484C39070311000000 [1f60086ba5a] jit-backend-dump} [1f60086d36e] {jit-backend-addr -Bridge out of guard 4 has address 7f8907a0b9b7 to 7f8907a0bab1 +Bridge out of guard 0x4a has address 0x7f8907a0b9b7 to 0x7f8907a0bab1 [1f60086ffd2] jit-backend-addr} [1f600870dca] {jit-backend-dump BACKEND x86_64 @@ -273,7 +273,7 @@ [1f600878f4e] jit-backend-dump} [1f600884c12] jit-backend} [1f60088780a] {jit-log-opt-bridge -# bridge out of Guard 4 with 16 ops +# bridge out of Guard 4a with 16 ops [p0, p1, p2, p3, i4, i5] debug_merge_point(0, ' #31 LOAD_FAST') debug_merge_point(0, ' #34 LOAD_CONST') diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -339,7 +339,7 @@ bridge.comment = 'bridge out of Guard af with 1 ops' loop.comment = 'Loop 0' loops = split_trace(loop) + split_trace(bridge) - input = ['grrr:123\nasb:12\nbridge af:1234'] + input = ['grrr:123\nasb:12\nbridge 175:1234'] parse_log_counts(input, loops) assert loops[-1].count == 1234 assert loops[1].count == 123 diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -13,7 +13,7 @@ operations as regalloc_operations, operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER, debug_bridge from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.codewriter.effectinfo import EffectInfo @@ -709,11 +709,7 @@ self.update_frame_depth(frame_depth) self.teardown() - debug_start("jit-backend-addr") - debug_print("bridge out of Guard %d has address 0x%x to 0x%x" % - (descr_number, r_uint(rawstart), - r_uint(rawstart + codeendpos))) - debug_stop("jit-backend-addr") + debug_bridge(descr_number, rawstart, codeendpos) return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -5,7 +5,8 @@ ConstInt, BoxInt) from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib import rgc -from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints +from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints, + debug_print) from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype @@ -224,3 +225,12 @@ ResOperation(rop.SETFIELD_RAW, [c_adr, box2], None, descr=self.debug_counter_descr)] operations.extend(ops) + + +def debug_bridge(descr_number, rawstart, codeendpos): + debug_start("jit-backend-addr") + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart), + r_uint(rawstart + codeendpos))) + debug_stop("jit-backend-addr") + diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2,7 +2,8 @@ import os from rpython.jit.backend.llsupport import symbolic, jitframe -from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler, DEBUG_COUNTER +from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler, + DEBUG_COUNTER, debug_bridge) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box @@ -553,11 +554,7 @@ rawstart = self.materialize_loop(original_loop_token) self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, rawstart) - debug_start("jit-backend-addr") - debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % - (r_uint(descr_number), r_uint(rawstart), - r_uint(rawstart + codeendpos))) - debug_stop("jit-backend-addr") + debug_bridge(descr_number, rawstart, codeendpos) self.patch_pending_failure_recoveries(rawstart) # patch the jump from original guard self.patch_jump_for_descr(faildescr, rawstart) From noreply at buildbot.pypy.org Tue Mar 19 06:44:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 06:44:33 +0100 (CET) Subject: [pypy-commit] pypy default: fix a bunch of overly specific tests Message-ID: <20130319054433.E92E71C00E4@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62448:b596c6158bb6 Date: 2013-03-18 22:44 -0700 http://bitbucket.org/pypy/pypy/changeset/b596c6158bb6/ Log: fix a bunch of overly specific tests diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -496,7 +496,7 @@ i10 = getfield_raw(..., descr=<.* pypysig_long_struct.c_value .*>) i14 = int_lt(i10, 0) guard_false(i14, descr=...) - jump(p0, p1, p2, p3, i8, descr=...) + jump(..., descr=...) """) # assert loop.match(""" @@ -504,7 +504,7 @@ guard_true(i6, descr=...) i8 = int_add(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i8, descr=...) + jump(..., descr=...) """) # py.test.raises(InvalidMatch, loop.match, """ @@ -512,7 +512,7 @@ guard_true(i6) i8 = int_add(i5, 1) # variable mismatch --TICK-- - jump(p0, p1, p2, p3, i8, descr=...) + jump(..., descr=...) """) def test_match_by_id(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_array.py b/pypy/module/pypyjit/test_pypy_c/test_array.py --- a/pypy/module/pypyjit/test_pypy_c/test_array.py +++ b/pypy/module/pypyjit/test_pypy_c/test_array.py @@ -22,7 +22,7 @@ guard_true(i7, descr=...) i9 = int_add(i5, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i9, i6, descr=...) + jump(..., descr=...) """) def test_array_sum(self): @@ -47,7 +47,7 @@ guard_no_overflow(descr=...) i18 = int_add(i7, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i18, i16, p8, i9, i10, descr=...) + jump(..., descr=...) """) def test_array_intimg(self): @@ -85,7 +85,7 @@ setarrayitem_raw(i11, i8, _, descr=) i28 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p5, p6, i28, i15, p9, i10, i11, descr=...) + jump(..., descr=...) """) def test_array_of_doubles(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py --- a/pypy/module/pypyjit/test_pypy_c/test_call.py +++ b/pypy/module/pypyjit/test_pypy_c/test_call.py @@ -101,7 +101,7 @@ i15 = int_add_ovf(i12, 1) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i15, i6, p7, p8, descr=...) + jump(..., descr=...) """) def test_method_call(self): @@ -144,7 +144,7 @@ i19 = int_add_ovf(i10, i17) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i19, p7, i17, i9, i10, p11, p12, p13, descr=...) + jump(..., descr=...) """) def test_static_classmethod_call(self): @@ -369,12 +369,12 @@ assert loop.match_by_id('call', opcode='CALL_FUNCTION', expected_src=""" # make sure that the "block" is not allocated ... - i20 = force_token() + p20 = force_token() p22 = new_with_vtable(...) p24 = new_array(1, descr=) p26 = new_with_vtable(ConstClass(W_ListObject)) {{{ - setfield_gc(p0, i20, descr=) + setfield_gc(p0, p20, descr=) setfield_gc(p22, 1, descr=) setfield_gc(p26, ConstPtr(ptr22), descr=) setarrayitem_gc(p24, 0, p26, descr=) @@ -467,7 +467,7 @@ p22 = new_with_vtable(ConstClass(W_IntObject)) setfield_gc(p22, i13, descr=) setfield_gc(p4, p22, descr=) - jump(p0, p1, p2, p3, p4, p7, p22, p7, descr=...) + jump(..., descr=...) """) def test_kwargs_virtual(self): 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 @@ -115,7 +115,7 @@ i35 = int_add_ovf(i5, i34) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i35, p13, i7, descr=...) + jump(..., descr=...) """) def test_floatlist_unpack_without_calls(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py --- a/pypy/module/pypyjit/test_pypy_c/test_instance.py +++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py @@ -27,7 +27,7 @@ i9 = int_add_ovf(i5, 2) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i9, i6, descr=...) + jump(..., descr=...) """) def test_load_attr(self): @@ -52,7 +52,7 @@ i10 = int_add_ovf(i5, i7) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i10, i6, i7, p8, descr=...) + jump(..., descr=...) """) def test_getattr_with_dynamic_attribute(self): @@ -127,7 +127,7 @@ p20 = new_with_vtable(ConstClass(W_IntObject)) setfield_gc(p20, i11, descr=) setfield_gc(ConstPtr(ptr21), p20, descr=) - jump(p0, p1, p2, p3, p4, p20, p6, i7, p20, descr=...) + jump(..., descr=...) """) def test_oldstyle_newstyle_mix(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_intbound.py b/pypy/module/pypyjit/test_pypy_c/test_intbound.py --- a/pypy/module/pypyjit/test_pypy_c/test_intbound.py +++ b/pypy/module/pypyjit/test_pypy_c/test_intbound.py @@ -97,7 +97,7 @@ guard_no_overflow(descr=...) i17 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i14, i12, i17, p8, i9, descr=...) + jump(..., descr=...) """) def test_intbound_sub_lt(self): @@ -121,7 +121,7 @@ guard_no_overflow(descr=...) i13 = int_add(i5, 1) --TICK-- - jump(p0, p1, p2, p3, i11, i13, descr=...) + jump(..., descr=...) """) def test_intbound_addsub_ge(self): @@ -150,7 +150,7 @@ guard_no_overflow(descr=...) i19 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i16, i14, i19, p8, i9, descr=...) + jump(..., descr=...) """) def test_intbound_addmul_ge(self): @@ -178,7 +178,7 @@ guard_no_overflow(descr=...) i21 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i18, i14, i21, p8, descr=...) + jump(..., descr=...) """) def test_intbound_eq(self): @@ -210,7 +210,7 @@ guard_no_overflow(descr=...) i16 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p6, i14, i16, p8, descr=...) + jump(..., descr=...) """) def test_intbound_mul(self): @@ -236,7 +236,7 @@ guard_no_overflow(descr=...) i14 = int_add(i6, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i12, i14, descr=...) + jump(..., descr=...) """) def test_assert(self): @@ -257,7 +257,7 @@ guard_no_overflow(descr=...) i12 = int_add(i6, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i10, i12, descr=...) + jump(..., descr=...) """) def test_xor(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_min_max.py b/pypy/module/pypyjit/test_pypy_c/test_min_max.py --- a/pypy/module/pypyjit/test_pypy_c/test_min_max.py +++ b/pypy/module/pypyjit/test_pypy_c/test_min_max.py @@ -22,7 +22,7 @@ guard_no_overflow(descr=...) i11 = int_add(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i11, i9, descr=...) + jump(..., descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -31,7 +31,7 @@ i13 = int_add_ovf(i6, i12) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i13, i11, i8, descr=...) + jump(..., descr=...) """ assert loop0.match(expected) # XXX: The retracing fails to form a loop since j @@ -56,7 +56,7 @@ guard_no_overflow(descr=...) i10 = int_sub(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i10, i8, descr=...) + jump(..., descr=...) """) # log = self.run(fact, [25], threshold=20) @@ -71,7 +71,7 @@ guard_no_exception(descr=...) i13 = int_sub(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i13, p11, descr=...) + jump(..., descr=...) """) @@ -91,7 +91,7 @@ guard_true(i9, descr=...) f10 = float_add(f8, f5) --TICK-- - jump(p0, p1, p2, p3, p4, f10, p6, f7, f8, descr=...) + jump(..., descr=...) """) @@ -252,7 +252,7 @@ i28 = int_add_ovf(i10, i25) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, p6, i28, i25, p9, p10, p11, p12, i19, descr=...) + jump(..., descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -49,7 +49,7 @@ guard_true(i32, descr=...) i34 = int_add(i6, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i34, p7, p8, i9, i10, p11, i12, p13, descr=...) + jump(..., descr=...) """ % (-sys.maxint-1, SHIFT)) def test_long(self): @@ -115,7 +115,7 @@ i58 = int_add_ovf(i6, i57) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i58, i7, descr=...) + jump(..., descr=...) """ % (-sys.maxint-1, SHIFT)) def test_str_mod(self): @@ -164,7 +164,7 @@ guard_no_overflow(descr=...) i40 = int_sub(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i40, i38, descr=...) + jump(..., descr=...) """) def test_getattr_promote(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py b/pypy/module/pypyjit/test_pypy_c/test_thread.py --- a/pypy/module/pypyjit/test_pypy_c/test_thread.py +++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py @@ -46,5 +46,5 @@ guard_no_overflow(descr=...) --TICK-- i58 = arraylen_gc(p43, descr=...) - jump(p0, p1, p3, p5, p10, p12, p14, i54, i27, i47, p45, p43, descr=...) + jump(..., descr=...) """) From noreply at buildbot.pypy.org Tue Mar 19 07:18:18 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 19 Mar 2013 07:18:18 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: whoops, missing parts of commit Message-ID: <20130319061818.443991C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62449:047dfd1e999f Date: 2013-03-18 23:17 -0700 http://bitbucket.org/pypy/pypy/changeset/047dfd1e999f/ Log: whoops, missing parts of commit 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 @@ -73,6 +73,25 @@ reds = 'auto') def setslice(space, shape, target, source): + if target.dtype.is_str_or_unicode(): + return setslice_from(space, shape, target, source) + return setslice_to(space, shape, target, source) + +def setslice_to(space, shape, target, source): + # note that unlike everything else, target and source here are + # array implementations, not arrays + target_iter = target.create_iter(shape) + source_iter = source.create_iter(shape) + dtype = target.dtype + shapelen = len(shape) + while not target_iter.done(): + setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(source_iter.getitem().convert_to(dtype)) + target_iter.next() + source_iter.next() + return target + +def setslice_from(space, shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -81,7 +100,7 @@ shapelen = len(shape) while not target_iter.done(): setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) - target_iter.setitem(source_iter.getitem().convert_to(dtype)) + target_iter.setitem(dtype.convert_from(space, source_iter.getitem())) target_iter.next() source_iter.next() return target From noreply at buildbot.pypy.org Tue Mar 19 07:41:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 07:41:40 +0100 (CET) Subject: [pypy-commit] pypy default: I should install pyflakes Message-ID: <20130319064140.B845A1C071B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62450:242db1afac0e Date: 2013-03-18 23:41 -0700 http://bitbucket.org/pypy/pypy/changeset/242db1afac0e/ Log: I should install pyflakes diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -10,6 +10,7 @@ from rpython.jit.backend.detect_cpu import getcpuclass from rpython.jit.backend.test.runner_test import Runner import py +import sys def boxfloat(x): return BoxFloat(longlong.getfloatstorage(x)) From noreply at buildbot.pypy.org Tue Mar 19 07:42:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Mar 2013 07:42:10 +0100 (CET) Subject: [pypy-commit] pypy default: fix the test Message-ID: <20130319064210.ED6451C071B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62451:9f1099167f6a Date: 2013-03-18 23:41 -0700 http://bitbucket.org/pypy/pypy/changeset/9f1099167f6a/ Log: fix the test 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 @@ -11,6 +11,8 @@ .. branch: callback-jit Callbacks from C are now better JITted +.. branch: fix-jit-logs + .. branch: remove-globals-in-jit .. branch: length-hint From noreply at buildbot.pypy.org Tue Mar 19 23:12:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Mar 2013 23:12:13 +0100 (CET) Subject: [pypy-commit] pypy gc-del: No-op refactoring. Message-ID: <20130319221213.AA6791C04AB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62509:904b011232dd Date: 2013-03-19 15:11 -0700 http://bitbucket.org/pypy/pypy/changeset/904b011232dd/ Log: No-op refactoring. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1243,25 +1243,12 @@ # 'old_objects_pointing_to_young'. self.collect_roots_in_nursery() # - while True: - # If we are using card marking, do a partial trace of the arrays - # that are flagged with GCFLAG_CARDS_SET. - if self.card_page_indices > 0: - self.collect_cardrefs_to_nursery() - # - # Now trace objects from 'old_objects_pointing_to_young'. - # All nursery objects they reference are copied out of the - # nursery, and again added to 'old_objects_pointing_to_young'. - # All young raw-malloced object found are flagged GCFLAG_VISITED. - # We proceed until 'old_objects_pointing_to_young' is empty. - self.collect_oldrefs_to_nursery() - # - # We have to loop back if collect_oldrefs_to_nursery caused - # new objects to show up in old_objects_with_cards_set - if self.card_page_indices > 0: - if self.old_objects_with_cards_set.non_empty(): - continue - break + # Now trace objects from 'old_objects_pointing_to_young'. + # All nursery objects they reference are copied out of the + # nursery, and again added to 'old_objects_pointing_to_young'. + # All young raw-malloced object found are flagged GCFLAG_VISITED. + # We proceed until 'old_objects_pointing_to_young' is empty. + self.collect_oldrefs_to_nursery() # # Now all live nursery objects should be out. Update the young # weakrefs' targets. @@ -1367,23 +1354,38 @@ # Follow the old_objects_pointing_to_young list and move the # young objects they point to out of the nursery. oldlist = self.old_objects_pointing_to_young - while oldlist.non_empty(): - obj = oldlist.pop() + while True: + if oldlist.non_empty(): + # Common case: we loop here until 'oldlist' is empty. + obj = oldlist.pop() + # + # Check that the flags are correct: we must not have + # GCFLAG_TRACK_YOUNG_PTRS so far. + ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS == 0, + "old_objects_pointing_to_young contains obj with " + "GCFLAG_TRACK_YOUNG_PTRS") + # + # Add the flag GCFLAG_TRACK_YOUNG_PTRS. All live objects + # should have this flag set after a nursery collection. + self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS + # + # Trace the 'obj' to replace pointers to nursery with pointers + # outside the nursery, possibly forcing nursery objects out + # and adding them to 'old_objects_pointing_to_young' as well. + self.trace_and_drag_out_of_nursery(obj) # - # Check that the flags are correct: we must not have - # GCFLAG_TRACK_YOUNG_PTRS so far. - ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS == 0, - "old_objects_pointing_to_young contains obj with " - "GCFLAG_TRACK_YOUNG_PTRS") - # - # Add the flag GCFLAG_TRACK_YOUNG_PTRS. All live objects should - # have this flag set after a nursery collection. - self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS - # - # Trace the 'obj' to replace pointers to nursery with pointers - # outside the nursery, possibly forcing nursery objects out - # and adding them to 'old_objects_pointing_to_young' as well. - self.trace_and_drag_out_of_nursery(obj) + else: + # If we are using card marking, do a partial trace of the + # arrays that are flagged with GCFLAG_CARDS_SET. + if (self.card_page_indices > 0 and + self.old_objects_with_cards_set.non_empty()): + self.collect_cardrefs_to_nursery() + # + else: + # Both 'old_objects_pointing_to_young' and + # 'old_objects_with_cards_set' are now empty: done + break + def trace_and_drag_out_of_nursery(self, obj): """obj must not be in the nursery. This copies all the From noreply at buildbot.pypy.org Tue Mar 19 23:18:17 2013 From: noreply at buildbot.pypy.org (vkryachko) Date: Tue, 19 Mar 2013 23:18:17 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: add rjust Message-ID: <20130319221817.EDCB31C1016@cobra.cs.uni-duesseldorf.de> Author: Vladimir Kryachko Branch: remove-string-smm Changeset: r62510:e268e40ce2ee Date: 2013-03-19 15:18 -0700 http://bitbucket.org/pypy/pypy/changeset/e268e40ce2ee/ Log: add rjust diff --git a/pypy/objspace/std/bytearrayinterface.py b/pypy/objspace/std/bytearrayinterface.py --- a/pypy/objspace/std/bytearrayinterface.py +++ b/pypy/objspace/std/bytearrayinterface.py @@ -1,13 +1,14 @@ from pypy.objspace.std.model import W_Object from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.objspace.std.inttype import wrapint class W_AbstractBytearrayObject(W_Object): pass -class ByteArrayInterface(object) : +class BytearrayInterface(object) : @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) def ljust(w_self, space, arg, fillchar=' '): """S.ljust(width[, fillchar]) -> string @@ -15,8 +16,8 @@ Return S left justified in a string of length width. Padding is done using the specified fill character (default is a space). """ + assert isinstance(w_self, W_AbstractBytearrayObject) u_self = w_self.data - assert isinstance(w_self, W_AbstractBytearrayObject) if len(fillchar) != 1: raise OperationError(space.w_TypeError, space.wrap("ljust() argument 2 must be a single character")) @@ -33,8 +34,34 @@ return space.newbytearray(lst) + @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) + def rjust(w_self, space, arg, fillchar=' '): + """S.rjust(width[, fillchar]) -> string + + Return S right justified in a string of length width. Padding + is done using the specified fill character (default is a space). + """ + u_self = w_self.data + assert isinstance(w_self, W_AbstractBytearrayObject) + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("rjust() argument 2 must be a single character")) + + d = arg - len(u_self) + if d > 0: + lst = [0] * max(arg, len(u_self)) + fillchar = fillchar[0] # annotator hint: it's a single character + for i in range(d): + lst[i] = fillchar + lst[len(u_self)-1:] = u_self + else: + lst = u_self.data[:] + + return space.newbytearray(lst) + def bytearray_interface_methods(): + """Convenience function which collects all BytearrayInterface methods into a dict""" return dict((name, interp2app(method)) for - name, method in ByteArrayInterface.__dict__.items() + name, method in BytearrayInterface.__dict__.items() if not name.startswith('_')) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -482,12 +482,6 @@ w_res = stringobject.str_capitalize__String(space, w_str) return String2Bytearray(space, w_res) -def str_rjust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar): - w_str = str__Bytearray(space, w_bytearray) - w_res = stringobject.str_rjust__String_ANY_ANY(space, w_str, w_width, - w_fillchar) - return String2Bytearray(space, w_res) - def str_center__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar): w_str = str__Bytearray(space, w_bytearray) w_res = stringobject.str_center__String_ANY_ANY(space, w_str, w_width, diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -10,7 +10,7 @@ str_startswith, str_endswith, str_islower, str_isupper, str_isalpha, str_isalnum, str_isdigit, str_isspace, str_istitle, str_upper, str_lower, str_title, str_swapcase, str_capitalize, - str_expandtabs, str_rjust, str_center, str_zfill, + str_expandtabs, str_center, str_zfill, str_join, str_split, str_rsplit, str_partition, str_rpartition, str_splitlines, str_translate) from pypy.objspace.std.listtype import ( From noreply at buildbot.pypy.org Wed Mar 20 00:12:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Mar 2013 00:12:47 +0100 (CET) Subject: [pypy-commit] pypy default: StackletThread instances must not be seen during translation. Message-ID: <20130319231247.F107B1C04AB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62511:997a2d3c74b2 Date: 2013-03-19 16:12 -0700 http://bitbucket.org/pypy/pypy/changeset/997a2d3c74b2/ Log: StackletThread instances must not be seen during translation. diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py --- a/rpython/rlib/rstacklet.py +++ b/rpython/rlib/rstacklet.py @@ -47,6 +47,10 @@ def get_null_handle(self): return self._gcrootfinder.get_null_handle() + def _freeze_(self): + raise Exception("StackletThread instances must not be seen during" + " translation.") + class StackletThreadDeleter(object): # quick hack: the __del__ is on another object, so that From noreply at buildbot.pypy.org Wed Mar 20 00:25:26 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 00:25:26 +0100 (CET) Subject: [pypy-commit] pypy fast-newarray: random progress Message-ID: <20130319232526.45EA81C03A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: fast-newarray Changeset: r62512:8dc4f4ba085c Date: 2013-03-19 16:25 -0700 http://bitbucket.org/pypy/pypy/changeset/8dc4f4ba085c/ Log: random progress diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -72,7 +72,8 @@ self._build_wb_slowpath(True, withfloats=True) self._build_propagate_exception_path() if gc_ll_descr.get_malloc_slowpath_addr is not None: - self._build_malloc_slowpath() + self.malloc_slowpath = self._build_malloc_slowpath(varsize=False) + self.malloc_slowpath_varsize = self._build_malloc_slowpath(varsize=True) self._build_stack_check_slowpath() if gc_ll_descr.gcrootmap: self._build_release_gil(gc_ll_descr.gcrootmap) diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -128,7 +128,6 @@ elif (self.gc_ll_descr.can_use_nursery_malloc(1) and self.gen_malloc_nursery_varsize(arraydescr.itemsize, v_length, op.result, arraydescr)): - self.gen_initialize_tid(op.result, arraydescr.tid) self.gen_initialize_len(op.result, v_length, arraydescr.lendescr) return if (total_size >= 0 and @@ -304,9 +303,8 @@ self.emitting_an_operation_that_can_collect() op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE, [ConstInt(itemsize), v_length], - v_result) + v_result, descr=arraydescr) self.newops.append(op) - self.recent_mallocs[v_result] = None return True def gen_malloc_nursery_varsize_small(self, sizebox, v_result): 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 @@ -247,24 +247,48 @@ def test_malloc_nursery_varsize(self): self.cpu = self.getcpu(None) + A = lltype.GcArray(lltype.Signed) + arraydescr = self.cpu.arraydescrof(A) + arraydescr.tid = 15 ops = ''' [i0, i1, i2] - p0 = call_malloc_nursery_varsize(8, i0) - p1 = call_malloc_nursery_varsize(5, i1) - p2 = call_malloc_nursery_varsize(7, i2) - guard_true(i0) [p0, p1, p2] + p0 = call_malloc_nursery_varsize(8, i0, descr=arraydescr) + p1 = call_malloc_nursery_varsize(5, i1, descr=arraydescr) + guard_true(i0) [p0, p1] ''' - self.interpret(ops, [1, 2, 3]) + self.interpret(ops, [1, 2, 3], + namespace={'arraydescr': arraydescr}) # check the returned pointers gc_ll_descr = self.cpu.gc_ll_descr nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 2*WORD + 8*1 - assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 2*WORD + 8*1 + 2*WORD + 5*2 + # check the nursery content and state + assert gc_ll_descr.nursery[0] == 15 + assert gc_ll_descr.nursery[2 + 8 / WORD] == 15 + assert gc_ll_descr.addrs[0] == nurs_adr + 4 * WORD + 8*1 + 5*2 + # slowpath never called + assert gc_ll_descr.calls == [] + + def test_malloc_nursery_varsize_slowpath(self): + self.cpu = self.getcpu(None) + ops = ''' + [i0, i1, i2] + p0 = call_malloc_nursery_varsize(8, i0) + p1 = call_malloc_nursery_varsize(5, i1) + guard_true(i0) [p0, p1] + ''' + self.interpret(ops, [10, 2, 3]) + # check the returned pointers + gc_ll_descr = self.cpu.gc_ll_descr + nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) + ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) + assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 + assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 2*WORD + 8*1 # check the nursery content and state gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.addrs[0] == nurs_adr + 64 + assert gc_ll_descr.addrs[0] == nurs_adr + 4 * WORD + 8*1 + 5*2 # slowpath never called assert gc_ll_descr.calls == [] diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py --- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py @@ -93,8 +93,8 @@ type_system=self.type_system, boxkinds=boxkinds) - def interpret(self, ops, args, run=True): - loop = self.parse(ops) + def interpret(self, ops, args, run=True, namespace=None): + loop = self.parse(ops, namespace=namespace) self.loop = loop looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -408,8 +408,7 @@ jump(i0) """, """ [i0] - p0 = call_malloc_nursery_varsize(1, i0) - setfield_gc(p0, %(bdescr.tid)d, descr=tiddescr) + p0 = call_malloc_nursery_varsize(1, i0, descr=bdescr) setfield_gc(p0, i0, descr=blendescr) jump(i0) """) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -60,6 +60,7 @@ self.float_const_neg_addr = 0 self.float_const_abs_addr = 0 self.malloc_slowpath = 0 + self.malloc_slowpath_varsize = 0 self.wb_slowpath = [0, 0, 0, 0, 0] self.setup_failure_recovery() self._debug = False @@ -176,7 +177,7 @@ mc.RET() self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, []) - def _build_malloc_slowpath(self): + def _build_malloc_slowpath(self, varsize): """ While arriving on slowpath, we have a gcpattern on stack, nursery_head in eax and the size in edi - eax """ @@ -190,13 +191,16 @@ mc.SUB_rr(edi.value, eax.value) # compute the size we want # the arg is already in edi mc.SUB_ri(esp.value, 16 - WORD) - if IS_X86_32: - mc.MOV_sr(0, edi.value) - if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): - mc.MOV_sr(WORD, ebp.value) - elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'): - # for tests only - mc.MOV_rr(esi.value, ebp.value) + if not varsize: + if IS_X86_32: + mc.MOV_sr(0, edi.value) + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_sr(WORD, ebp.value) + elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + # for tests only + mc.MOV_rr(esi.value, ebp.value) + else: + return 0 extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') mc.MOV_bi(extra_ofs, 16) mc.CALL(imm(addr)) @@ -224,7 +228,7 @@ mc.JMP(imm(self.propagate_exception_path)) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) - self.malloc_slowpath = rawstart + return rawstart def _build_propagate_exception_path(self): if not self.cpu.propagate_exception_descr: @@ -651,7 +655,7 @@ if expected_size == -1: mc.MOV_si(WORD, 0xffffff) else: - mc.MOV_si(WORD, expected_size) + mc.MOV_si(WORD, expected_size) ofs2 = mc.get_relative_pos() - 4 self.push_gcmap(mc, gcmap, mov=True) mc.CALL(imm(self._frame_realloc_slowpath)) @@ -689,7 +693,7 @@ mc = codebuf.MachineCodeBlockWrapper() mc.writeimm32(allocated_depth) mc.copy_to_raw_memory(adr) - + def get_asmmemmgr_blocks(self, looptoken): clt = looptoken.compiled_loop_token if clt.asmmemmgr_blocks is None: @@ -718,7 +722,7 @@ struct.number = compute_unique_id(token) self.loop_run_counters.append(struct) return struct - + def patch_jump_for_descr(self, faildescr, adr_new_target): adr_jump_offset = faildescr._x86_adr_jump_offset assert adr_jump_offset != 0 @@ -946,7 +950,7 @@ else: assert isinstance(to_loc, RawEspLoc) self.mc.MOV32_si(to_loc.value, low_part) - self.mc.MOV32_si(to_loc.value + 4, high_part) + self.mc.MOV32_si(to_loc.value + 4, high_part) def regalloc_perform(self, op, arglocs, resloc): genop_list[op.getopnum()](self, op, arglocs, resloc) @@ -1792,7 +1796,7 @@ if exctploc is not None: assert exctploc.is_reg() mc.MOV(exctploc, heap(self.cpu.pos_exception())) - + mc.MOV(heap(self.cpu.pos_exception()), imm0) mc.MOV(heap(self.cpu.pos_exc_value()), imm0) @@ -2461,15 +2465,16 @@ self.mc.MOV(heap(nursery_free_adr), edi) def malloc_cond_varsize(self, nursery_free_adr, nursery_top_adr, - lengthloc, itemsize, maxlength, gcmap): + lengthloc, itemsize, maxlength, gcmap, + arraydescr): self.mc.CMP(lengthloc, imm(maxlength)) - self.mc.J_il8(rx86.Conditions['L'], 0) # patched later + self.mc.J_il8(rx86.Conditions['G'], 0) # patched later jmp_adr0 = self.mc.get_relative_pos() self.mc.MOV(edi, heap(nursery_free_adr)) self.mc.MOV(eax, edi) self.mc.MOV(edi, lengthloc) self.mc.IMUL(edi, imm(itemsize)) - self.mc.ADD(edi, eax) + self.mc.ADD(edi, heap(nursery_free_adr)) self.mc.ADD(edi, imm(WORD * 2)) self.mc.CMP(edi, heap(nursery_top_adr)) self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later @@ -2479,7 +2484,7 @@ self.mc.overwrite(jmp_adr0-1, chr(offset)) # save the gcmap self.push_gcmap(self.mc, gcmap, mov=True) - self.mc.CALL(imm(0)) + self.mc.CALL(imm(self.malloc_slowpath_varsize)) offset = self.mc.get_relative_pos() - jmp_adr1 assert 0 < offset <= 127 self.mc.overwrite(jmp_adr1-1, chr(offset)) 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 @@ -54,7 +54,7 @@ class X86_64_RegisterManager(X86RegisterManager): # r11 omitted because it's used as scratch all_regs = [ecx, eax, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14, r15] - + no_lower_byte_regs = [] save_around_call_regs = [eax, ecx, edx, esi, edi, r8, r9, r10] @@ -103,7 +103,7 @@ def __init__(self, base_ofs): FrameManager.__init__(self) self.base_ofs = base_ofs - + def frame_pos(self, i, box_type): return FrameLoc(i, get_ebp_ofs(self.base_ofs, i), box_type) @@ -872,6 +872,7 @@ def consider_call_malloc_nursery_varsize(self, op): length_box = op.getarg(1) + arraydescr = op.getdescr() assert isinstance(length_box, BoxInt) # we cannot have a const here! # looking at the result self.rm.force_allocate_reg(op.result, selected_reg=eax) @@ -890,7 +891,7 @@ self.assembler.malloc_cond_varsize( gc_ll_descr.get_nursery_free_addr(), gc_ll_descr.get_nursery_top_addr(), - lengthloc, itemsize, maxlength, gcmap) + lengthloc, itemsize, maxlength, gcmap, arraydescr) def get_gcmap(self, forbidden_regs=[], noregs=False): frame_depth = self.fm.get_frame_depth() @@ -1335,7 +1336,7 @@ #jump_op = self.final_jump_op #if jump_op is not None and jump_op.getdescr() is descr: # self._compute_hint_frame_locations_from_descr(descr) - + def consider_keepalive(self, op): pass diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -529,7 +529,7 @@ 'CALL_PURE/*d', # removed before it's passed to the backend 'CALL_MALLOC_GC/*d', # like CALL, but NULL => propagate MemoryError 'CALL_MALLOC_NURSERY/1', # nursery malloc, const number of bytes, zeroed - 'CALL_MALLOC_NURSERY_VARSIZE/2', + 'CALL_MALLOC_NURSERY_VARSIZE/2d', 'CALL_MALLOC_NURSERY_VARSIZE_SMALL/1', # nursery malloc, non-const number of bytes, zeroed # note that the number of bytes must be well known to be small enough From noreply at buildbot.pypy.org Wed Mar 20 00:37:45 2013 From: noreply at buildbot.pypy.org (vkryachko) Date: Wed, 20 Mar 2013 00:37:45 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Add str.rjust and str.join methods Message-ID: <20130319233745.212941C03A7@cobra.cs.uni-duesseldorf.de> Author: Vladimir Kryachko Branch: remove-string-smm Changeset: r62513:25d514ae998b Date: 2013-03-19 16:37 -0700 http://bitbucket.org/pypy/pypy/changeset/25d514ae998b/ Log: Add str.rjust and str.join methods diff --git a/pypy/objspace/std/bytearrayinterface.py b/pypy/objspace/std/bytearrayinterface.py --- a/pypy/objspace/std/bytearrayinterface.py +++ b/pypy/objspace/std/bytearrayinterface.py @@ -8,7 +8,7 @@ pass -class BytearrayInterface(object) : +class BytearrayInterface(object): @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) def ljust(w_self, space, arg, fillchar=' '): """S.ljust(width[, fillchar]) -> string diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -11,7 +11,7 @@ str_isalnum, str_isdigit, str_isspace, str_istitle, str_upper, str_lower, str_title, str_swapcase, str_capitalize, str_expandtabs, str_center, str_zfill, - str_join, str_split, str_rsplit, str_partition, str_rpartition, + str_split, str_rsplit, str_partition, str_rpartition, str_splitlines, str_translate) from pypy.objspace.std.listtype import ( list_append, list_extend) @@ -20,6 +20,7 @@ str_ljust = SMM('ljust', 3, defaults=(' ',)) +str_join = SMM('join', 2, defaults=(None,-1)) bytearray_insert = SMM('insert', 3, doc="B.insert(index, int) -> None\n\n" diff --git a/pypy/objspace/std/contiguousstring.py b/pypy/objspace/std/contiguousstring.py --- a/pypy/objspace/std/contiguousstring.py +++ b/pypy/objspace/std/contiguousstring.py @@ -1,6 +1,8 @@ """Common methods for string types (bytes and unicode)""" -from pypy.interpreter.error import OperationError +from rpython.rlib import jit +from pypy.interpreter.error import OperationError, operationerrfmt +from rpython.rlib.rstring import StringBuilder, split class StringMethods(object): @@ -18,3 +20,65 @@ u_self += d * fillchar return space.wrap(u_self) + + def rjust(self, space, arg, fillchar=' '): + u_self = self._value + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("rjust() argument 2 must be a single character")) + + d = arg - len(u_self) + if d>0: + fillchar = fillchar[0] # annotator hint: it's a single character + u_self = d * fillchar + u_self + + return space.wrap(u_self) + + def join(self, space, w_list): + l = space.listview_str(w_list) + if l is not None: + if len(l) == 1: + return space.wrap(l[0]) + return space.wrap(self._value.join(l)) + list_w = space.listview(w_list) + size = len(list_w) + + if size == 0: + return space.wrap("") + + if size == 1: + w_s = list_w[0] + # only one item, return it if it's not a subclass of str + if (space.is_w(space.type(w_s), space.w_str) or + space.is_w(space.type(w_s), space.w_unicode)): + return w_s + + return _str_join_many_items(space, self, list_w, size) + + + at jit.look_inside_iff(lambda space, w_self, list_w, size: + jit.loop_unrolling_heuristic(list_w, size)) +def _str_join_many_items(space, w_self, list_w, size): + self = w_self._value + reslen = len(self) * (size - 1) + for i in range(size): + w_s = list_w[i] + if not space.isinstance_w(w_s, space.w_str): + if space.isinstance_w(w_s, space.w_unicode): + # we need to rebuild w_list here, because the original + # w_list might be an iterable which we already consumed + w_list = space.newlist(list_w) + w_u = space.call_function(space.w_unicode, w_self) + return space.call_method(w_u, "join", w_list) + raise operationerrfmt( + space.w_TypeError, + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space)) + reslen += len(space.str_w(w_s)) + + sb = StringBuilder(reslen) + for i in range(size): + if self and i != 0: + sb.append(self) + sb.append(space.str_w(list_w[i])) + return space.wrap(sb.build()) \ No newline at end of file diff --git a/pypy/objspace/std/stringinterface.py b/pypy/objspace/std/stringinterface.py --- a/pypy/objspace/std/stringinterface.py +++ b/pypy/objspace/std/stringinterface.py @@ -4,6 +4,7 @@ from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from rpython.rlib.objectmodel import compute_unique_id +from pypy.interpreter.error import OperationError class W_AbstractStringObject(W_Object): @@ -39,6 +40,16 @@ class StringInterface(object): + @unwrap_spec(w_self=W_Root) + def join(w_self, space, w_list): + """S.join(sequence) -> string + + Return a string which is + the concatenation of the strings in the sequence. + The separator between elements is S.""" + assert isinstance(w_self, W_AbstractStringObject) + return w_self.join(space, w_list) + @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) def ljust(w_self, space, arg, fillchar=' '): """S.ljust(width[, fillchar]) -> string @@ -49,8 +60,20 @@ assert isinstance(w_self, W_AbstractStringObject) return w_self.ljust(space, arg, fillchar) + @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) + def rjust(w_self, space, arg, fillchar=' '): + """S.rjust(width[, fillchar]) -> string + + Return S + right justified in a string of length width. + Padding is done using the specified fill character + (default is a space)""" + assert isinstance(w_self, W_AbstractStringObject) + return w_self.rjust(space, arg, fillchar) + def string_interface_methods(): return dict((name, interp2app(method)) for name, method in StringInterface.__dict__.items() if not name.startswith('_')) + diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py --- a/pypy/objspace/std/stringobject.py +++ b/pypy/objspace/std/stringobject.py @@ -348,69 +348,6 @@ str_rsplit__String_String_ANY = make_rsplit_with_delim('str_rsplit__String_String_ANY', sliced) -def str_join__String_ANY(space, w_self, w_list): - l = space.listview_str(w_list) - if l is not None: - if len(l) == 1: - return space.wrap(l[0]) - return space.wrap(w_self._value.join(l)) - list_w = space.listview(w_list) - size = len(list_w) - - if size == 0: - return W_StringObject.EMPTY - - if size == 1: - w_s = list_w[0] - # only one item, return it if it's not a subclass of str - if (space.is_w(space.type(w_s), space.w_str) or - space.is_w(space.type(w_s), space.w_unicode)): - return w_s - - return _str_join_many_items(space, w_self, list_w, size) - - at jit.look_inside_iff(lambda space, w_self, list_w, size: - jit.loop_unrolling_heuristic(list_w, size)) -def _str_join_many_items(space, w_self, list_w, size): - self = w_self._value - reslen = len(self) * (size - 1) - for i in range(size): - w_s = list_w[i] - if not space.isinstance_w(w_s, space.w_str): - if space.isinstance_w(w_s, space.w_unicode): - # we need to rebuild w_list here, because the original - # w_list might be an iterable which we already consumed - w_list = space.newlist(list_w) - w_u = space.call_function(space.w_unicode, w_self) - return space.call_method(w_u, "join", w_list) - raise operationerrfmt( - space.w_TypeError, - "sequence item %d: expected string, %s " - "found", i, space.type(w_s).getname(space)) - reslen += len(space.str_w(w_s)) - - sb = StringBuilder(reslen) - for i in range(size): - if self and i != 0: - sb.append(self) - sb.append(space.str_w(list_w[i])) - return space.wrap(sb.build()) - -def str_rjust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): - u_arg = space.int_w(w_arg) - u_self = w_self._value - fillchar = space.str_w(w_fillchar) - if len(fillchar) != 1: - raise OperationError(space.w_TypeError, - space.wrap("rjust() argument 2 must be a single character")) - - d = u_arg - len(u_self) - if d>0: - fillchar = fillchar[0] # annotator hint: it's a single character - u_self = d * fillchar + u_self - - return space.wrap(u_self) - @specialize.arg(4) def _convert_idx_params(space, w_self, w_start, w_end, upper_bound=False): diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -46,10 +46,6 @@ else: return wrapstr(space, str1 + str2) -str_join = SMM('join', 2, - doc='S.join(sequence) -> string\n\nReturn a string which is' - ' the concatenation of the strings in the\nsequence. ' - ' The separator between elements is S.') str_split = SMM('split', 3, defaults=(None,-1), doc='S.split([sep [,maxsplit]]) -> list of strings\n\nReturn' ' a list of the words in the string S, using sep as' @@ -96,11 +92,6 @@ doc='S.isalnum() -> bool\n\nReturn True if all characters' ' in S are alphanumeric\nand there is at least one' ' character in S, False otherwise.') -str_rjust = SMM('rjust', 3, defaults=(' ',), - doc='S.rjust(width[, fillchar]) -> string\n\nReturn S' - ' right justified in a string of length width.' - ' Padding is\ndone using the specified fill character' - ' (default is a space)') str_upper = SMM('upper', 1, doc='S.upper() -> string\n\nReturn a copy of the string S' ' converted to uppercase.') From noreply at buildbot.pypy.org Wed Mar 20 00:43:35 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 00:43:35 +0100 (CET) Subject: [pypy-commit] pypy scalar_get_set: test, add set_real, set_imag for scalars. Also add composite() to types.ComplexType to create complex from real, imag boxes Message-ID: <20130319234335.A1E8A1C04AB@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: scalar_get_set Changeset: r62514:bc351ea348e1 Date: 2013-03-19 16:41 -0700 http://bitbucket.org/pypy/pypy/changeset/bc351ea348e1/ Log: test, add set_real, set_imag for scalars. Also add composite() to types.ComplexType to create complex from real, imag boxes diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -82,6 +82,10 @@ return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) + def set_real(self, space, orig_array, w_value): + tmp = self.get_real(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -98,6 +102,10 @@ impl.fill(self.dtype.box(0)) return impl + def set_imag(self, space, orig_array, w_value): + tmp = self.get_imag(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + # -------------------- applevel get/setitem ----------------------- @jit.unroll_safe diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -1,6 +1,6 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.base import W_NDimArray, convert_to_array from pypy.module.micronumpy import support from pypy.interpreter.error import OperationError @@ -68,6 +68,24 @@ return scalar return self + def set_real(self, space, orig_array, w_val): + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type or self.dtype + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + if self.dtype.is_complex_type(): + #imag = dtype.itemtype.unbox(self.value.convert_imag_to(dtype)) + #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). + # convert_to(dtype)) + #self.value = self.dtype.box_complex(val, imag) + self.value = self.dtype.itemtype.composite(w_arr.get_scalar_value().convert_to(dtype), + self.value.convert_imag_to(dtype)) + else: + self.value = w_arr.get_scalar_value() + def get_imag(self, orig_array): if self.dtype.is_complex_type(): scalar = Scalar(self.dtype.float_type) @@ -80,6 +98,25 @@ scalar.value = scalar.dtype.itemtype.box(0) return scalar + def set_imag(self, space, orig_array, w_val): + #Only called on complex dtype + assert self.dtype.is_complex_type() + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + #real = dtype.itemtype.unbox(self.value.convert_real_to(dtype)) + #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). + # convert_to(dtype)) + #self.value = self.dtype.box_complex(real, val) + self.value = self.dtype.itemtype.composite( + self.value.convert_real_to(dtype), + w_arr.get_scalar_value(), + ) + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) 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 @@ -71,7 +71,6 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) - def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -272,16 +272,14 @@ def descr_set_real(self, space, w_value): # copy (broadcast) values into self - tmp = self.implementation.get_real(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_real(space, self, w_value) def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) - tmp = self.implementation.get_imag(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_imag(space, self, w_value) def descr_reshape(self, space, args_w): """reshape(...) 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 @@ -520,16 +520,22 @@ assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real + b[0] = 1024 + assert a[0].real == 1024 assert b.dtype == dtype(float) a = array(complex(3.0, 4.0)) b = a.real assert b == array(3) + a.real = 1024 + assert a.real == 1024 assert a.imag == array(4) assert b.dtype == dtype(float) a = array(4.0) b = a.imag assert b == 0 assert b.dtype == dtype(float) + raises(TypeError, 'a.imag = 1024') + raises(ValueError, 'a.real = [1, 3]') a = array('abc') assert str(a.real) == 'abc' # numpy imag for flexible types returns self 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 @@ -1150,6 +1150,14 @@ return rfloat.NAN, rfloat.NAN return rfloat.INFINITY, rfloat.INFINITY + @specialize.argtype(1) + def composite(self, v1, v2): + assert isinstance(v1, self.ComponentBoxType) + assert isinstance(v2, self.ComponentBoxType) + real = v1.value + imag = v2.value + return self.box_complex(real, imag) + @complex_unary_op def pos(self, v): return v From noreply at buildbot.pypy.org Wed Mar 20 00:54:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 00:54:57 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: (alex, arigo, fijal) start removing strange stuff on lists (multimethods in Message-ID: <20130319235457.9C80C1C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62515:bbb0aca228e5 Date: 2013-03-19 16:54 -0700 http://bitbucket.org/pypy/pypy/changeset/bbb0aca228e5/ Log: (alex, arigo, fijal) start removing strange stuff on lists (multimethods in particular) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -159,8 +159,13 @@ self.orig_arg() def visit__W_Root(self, el, app_sig): + argname = self.orig_arg() + if argname == 'self': + # for W_ListObject and similar to be possible to have + # unwrap_spec in methods + app_sig.append(argname) + return assert el is W_Root, "%s is not W_Root (forgotten to put .im_func in interp2app argument?)" % (el,) - argname = self.orig_arg() assert argname.startswith('w_'), ( "argument %s of built-in function %r should " "start with 'w_'" % (argname, self.func)) diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -14,7 +14,7 @@ # ____________________________________________________________ -def sorted(lst, cmp=None, key=None, reverse=None): +def sorted(lst, cmp=None, key=None, reverse=False): "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list" sorted_lst = list(lst) sorted_lst.sort(cmp, key, reverse) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -9,8 +9,7 @@ from rpython.rlib.debug import check_annotation from pypy.objspace.std import stringobject from pypy.objspace.std.intobject import W_IntObject -from pypy.objspace.std.listobject import get_positive_index -from pypy.objspace.std.listtype import get_list_index +from pypy.objspace.std.listobject import get_positive_index, get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.strutil import ParseStringError diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -13,8 +13,8 @@ str_expandtabs, str_ljust, str_rjust, str_center, str_zfill, str_join, str_split, str_rsplit, str_partition, str_rpartition, str_splitlines, str_translate) -from pypy.objspace.std.listtype import ( - list_append, list_extend) +from pypy.objspace.std.listobject import list_append, list_extend + from rpython.rlib.objectmodel import newlist_hint, resizelist_hint 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 @@ -4,7 +4,6 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.generator import GeneratorIterator from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.interpreter import gateway, baseobjspace @@ -14,6 +13,8 @@ from rpython.rlib.listsort import make_timsort_class from rpython.rlib import rerased, jit, debug from rpython.tool.sourcetools import func_with_new_name +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM +from sys import maxint UNROLL_CUTOFF = 5 @@ -122,8 +123,6 @@ return type(w_object) is W_FloatObject class W_ListObject(W_AbstractListObject): - from pypy.objspace.std.listtype import list_typedef as typedef - def __init__(w_self, space, wrappeditems, sizehint=-1): assert isinstance(wrappeditems, list) w_self.space = space @@ -324,6 +323,80 @@ argument reverse. Argument must be unwrapped.""" self.strategy.sort(self, reverse) + @gateway.unwrap_spec(reverse=bool) + def descr_sort(self, space, w_cmp=None, w_key=None, reverse=False): + """ L.sort(cmp=None, key=None, reverse=False) -- stable + sort *IN PLACE*; + cmp(x, y) -> -1, 0, 1""" + has_cmp = not space.is_none(w_cmp) + has_key = not space.is_none(w_key) + + # create and setup a TimSort instance + if has_cmp: + if has_key: + sorterclass = CustomKeyCompareSort + else: + sorterclass = CustomCompareSort + else: + if has_key: + sorterclass = CustomKeySort + else: + if self.strategy is space.fromcache(ObjectListStrategy): + sorterclass = SimpleSort + else: + self.sort(reverse) + return space.w_None + + sorter = sorterclass(self.getitems(), self.length()) + sorter.space = space + sorter.w_cmp = w_cmp + + try: + # The list is temporarily made empty, so that mutations performed + # by comparison functions can't affect the slice of memory we're + # sorting (allowing mutations during sorting is an IndexError or + # core-dump factory, since the storage may change). + self.__init__(space, []) + + # wrap each item in a KeyContainer if needed + if has_key: + for i in range(sorter.listlength): + w_item = sorter.list[i] + w_keyitem = space.call_function(w_key, w_item) + sorter.list[i] = KeyContainer(w_keyitem, w_item) + + # Reverse sort stability achieved by initially reversing the list, + # applying a stable forward sort, then reversing the final result. + if reverse: + sorter.list.reverse() + + # perform the sort + sorter.sort() + + # reverse again + if reverse: + sorter.list.reverse() + + finally: + # unwrap each item if needed + if has_key: + for i in range(sorter.listlength): + w_obj = sorter.list[i] + if isinstance(w_obj, KeyContainer): + sorter.list[i] = w_obj.w_item + + # check if the user mucked with the list during the sort + mucked = self.length() > 0 + + # put the items back into the list + self.__init__(space, sorter.list) + + if mucked: + raise OperationError(space.w_ValueError, + space.wrap("list modified during sort")) + + return space.w_None + registerimplementation(W_ListObject) @@ -1560,78 +1633,57 @@ assert isinstance(b, KeyContainer) return CustomCompareSort.lt(self, a.w_key, b.w_key) -def list_sort__List_ANY_ANY_ANY(space, w_list, w_cmp, w_keyfunc, w_reverse): +def list_reversed__ANY(space, w_list): + from pypy.objspace.std.iterobject import W_ReverseSeqIterObject + return W_ReverseSeqIterObject(space, w_list, -1) - has_cmp = not space.is_w(w_cmp, space.w_None) - has_key = not space.is_w(w_keyfunc, space.w_None) - has_reverse = space.is_true(w_reverse) +# ____________________________________________________________ - # create and setup a TimSort instance - if has_cmp: - if has_key: - sorterclass = CustomKeyCompareSort - else: - sorterclass = CustomCompareSort - else: - if has_key: - sorterclass = CustomKeySort - else: - if w_list.strategy is space.fromcache(ObjectListStrategy): - sorterclass = SimpleSort - else: - w_list.sort(has_reverse) - return space.w_None +def descr_new(space, w_listtype, __args__): + w_obj = space.allocate_instance(W_ListObject, w_listtype) + w_obj.clear(space) + return w_obj - sorter = sorterclass(w_list.getitems(), w_list.length()) - sorter.space = space - sorter.w_cmp = w_cmp +# ____________________________________________________________ - try: - # The list is temporarily made empty, so that mutations performed - # by comparison functions can't affect the slice of memory we're - # sorting (allowing mutations during sorting is an IndexError or - # core-dump factory, since the storage may change). - w_list.__init__(space, []) +# ____________________________________________________________ - # wrap each item in a KeyContainer if needed - if has_key: - for i in range(sorter.listlength): - w_item = sorter.list[i] - w_key = space.call_function(w_keyfunc, w_item) - sorter.list[i] = KeyContainer(w_key, w_item) +def get_list_index(space, w_index): + return space.getindex_w(w_index, space.w_IndexError, "list index") - # Reverse sort stability achieved by initially reversing the list, - # applying a stable forward sort, then reversing the final result. - if has_reverse: - sorter.list.reverse() +list_append = SMM('append', 2, + doc='L.append(object) -- append object to end') +list_insert = SMM('insert', 3, + doc='L.insert(index, object) -- insert object before index') +list_extend = SMM('extend', 2, + doc='L.extend(iterable) -- extend list by appending' + ' elements from the iterable') +list_pop = SMM('pop', 2, defaults=(None,), + doc='L.pop([index]) -> item -- remove and return item at' + ' index (default last)') +list_remove = SMM('remove', 2, + doc='L.remove(value) -- remove first occurrence of value') +list_index = SMM('index', 4, defaults=(0,maxint), + doc='L.index(value, [start, [stop]]) -> integer -- return' + ' first index of value') +list_count = SMM('count', 2, + doc='L.count(value) -> integer -- return number of' + ' occurrences of value') +list_reverse = SMM('reverse',1, + doc='L.reverse() -- reverse *IN PLACE*') +list_reversed = SMM('__reversed__', 1, + doc='L.__reversed__() -- return a reverse iterator over' + ' the list') - # perform the sort - sorter.sort() +register_all(vars(), globals()) - # reverse again - if has_reverse: - sorter.list.reverse() +W_ListObject.typedef = StdTypeDef("list", + __doc__ = """list() -> new list +list(sequence) -> new list initialized from sequence's items""", + __new__ = gateway.interp2app(descr_new), + __hash__ = None, + sort = gateway.interp2app(W_ListObject.descr_sort), + ) +W_ListObject.typedef.registermethods(globals()) - finally: - # unwrap each item if needed - if has_key: - for i in range(sorter.listlength): - w_obj = sorter.list[i] - if isinstance(w_obj, KeyContainer): - sorter.list[i] = w_obj.w_item - - # check if the user mucked with the list during the sort - mucked = w_list.length() > 0 - - # put the items back into the list - w_list.__init__(space, sorter.list) - - if mucked: - raise OperationError(space.w_ValueError, - space.wrap("list modified during sort")) - - return space.w_None - - -from pypy.objspace.std import listtype -register_all(vars(), listtype) +list_typedef = W_ListObject.typedef diff --git a/pypy/objspace/std/listtype.py b/pypy/objspace/std/listtype.py deleted file mode 100644 --- a/pypy/objspace/std/listtype.py +++ /dev/null @@ -1,62 +0,0 @@ -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError -from pypy.objspace.std.stdtypedef import StdTypeDef, SMM -from pypy.objspace.std.register_all import register_all -from sys import maxint - -list_append = SMM('append', 2, - doc='L.append(object) -- append object to end') -list_insert = SMM('insert', 3, - doc='L.insert(index, object) -- insert object before index') -list_extend = SMM('extend', 2, - doc='L.extend(iterable) -- extend list by appending' - ' elements from the iterable') -list_pop = SMM('pop', 2, defaults=(None,), - doc='L.pop([index]) -> item -- remove and return item at' - ' index (default last)') -list_remove = SMM('remove', 2, - doc='L.remove(value) -- remove first occurrence of value') -list_index = SMM('index', 4, defaults=(0,maxint), - doc='L.index(value, [start, [stop]]) -> integer -- return' - ' first index of value') -list_count = SMM('count', 2, - doc='L.count(value) -> integer -- return number of' - ' occurrences of value') -list_reverse = SMM('reverse',1, - doc='L.reverse() -- reverse *IN PLACE*') -list_sort = SMM('sort', 4, defaults=(None, None, False), - argnames=['cmp', 'key', 'reverse'], - doc='L.sort(cmp=None, key=None, reverse=False) -- stable' - ' sort *IN PLACE*;\ncmp(x, y) -> -1, 0, 1') -list_reversed = SMM('__reversed__', 1, - doc='L.__reversed__() -- return a reverse iterator over' - ' the list') - -def list_reversed__ANY(space, w_list): - from pypy.objspace.std.iterobject import W_ReverseSeqIterObject - return W_ReverseSeqIterObject(space, w_list, -1) - -register_all(vars(), globals()) - -# ____________________________________________________________ - -def descr__new__(space, w_listtype, __args__): - from pypy.objspace.std.listobject import W_ListObject - w_obj = space.allocate_instance(W_ListObject, w_listtype) - w_obj.clear(space) - return w_obj - -# ____________________________________________________________ - -list_typedef = StdTypeDef("list", - __doc__ = '''list() -> new list -list(sequence) -> new list initialized from sequence's items''', - __new__ = gateway.interp2app(descr__new__), - __hash__ = None, - ) -list_typedef.registermethods(globals()) - -# ____________________________________________________________ - -def get_list_index(space, w_index): - return space.getindex_w(w_index, space.w_IndexError, "list index") 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 @@ -20,8 +20,6 @@ "withsmallint" : ["smallintobject.W_SmallIntObject"], "withsmalllong" : ["smalllongobject.W_SmallLongObject"], "withstrbuf" : ["strbufobject.W_StringBufferObject"], - "withtproxy" : ["proxyobject.W_TransparentList", - "proxyobject.W_TransparentDict"], } IDTAG_INT = 1 @@ -44,7 +42,7 @@ from pypy.objspace.std.settype import set_typedef from pypy.objspace.std.frozensettype import frozenset_typedef from pypy.objspace.std.tupletype import tuple_typedef - from pypy.objspace.std.listtype import list_typedef + from pypy.objspace.std.listobject import list_typedef from pypy.objspace.std.dicttype import dict_typedef from pypy.objspace.std.basestringtype import basestring_typedef from pypy.objspace.std.stringtype import str_typedef diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py --- a/pypy/objspace/std/proxyobject.py +++ b/pypy/objspace/std/proxyobject.py @@ -97,17 +97,3 @@ class W_TransparentGenerator(W_Transparent): typedef = GeneratorIterator.typedef - -class W_TransparentList(W_TransparentObject): - from pypy.objspace.std.listobject import W_ListObject as original - from pypy.objspace.std.listtype import list_typedef as typedef - -class W_TransparentDict(W_TransparentObject): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject as original - from pypy.objspace.std.dicttype import dict_typedef as typedef - -registerimplementation(W_TransparentList) -registerimplementation(W_TransparentDict) - -register_type(W_TransparentList) -register_type(W_TransparentDict) diff --git a/pypy/objspace/std/transparent.py b/pypy/objspace/std/transparent.py --- a/pypy/objspace/std/transparent.py +++ b/pypy/objspace/std/transparent.py @@ -39,10 +39,6 @@ raise OperationError(space.w_TypeError, space.wrap("controller should be function")) if isinstance(w_type, W_TypeObject): - if space.is_true(space.issubtype(w_type, space.w_list)): - return W_TransparentList(space, w_type, w_controller) - if space.is_true(space.issubtype(w_type, space.w_dict)): - return W_TransparentDict(space, w_type, w_controller) if space.is_true(space.issubtype(w_type, space.gettypeobject(Function.typedef))): return W_TransparentFunction(space, w_type, w_controller) if space.is_true(space.issubtype(w_type, space.gettypeobject(PyTraceback.typedef))): From noreply at buildbot.pypy.org Wed Mar 20 00:55:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Mar 2013 00:55:57 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: Add a test Message-ID: <20130319235557.715181C1016@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: remove-list-smm Changeset: r62516:d937f127b2e5 Date: 2013-03-19 16:55 -0700 http://bitbucket.org/pypy/pypy/changeset/d937f127b2e5/ Log: Add a test diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py --- a/pypy/module/__builtin__/test/test_builtin.py +++ b/pypy/module/__builtin__/test/test_builtin.py @@ -347,6 +347,7 @@ sorted_l = sorted(l, reverse = True, key = lambda x: x.lower()) assert sorted_l is not l assert sorted_l == ['C', 'b', 'a'] + raises(TypeError, sorted, [], reverse=None) def test_reversed_simple_sequences(self): l = range(5) From noreply at buildbot.pypy.org Wed Mar 20 01:02:03 2013 From: noreply at buildbot.pypy.org (Jason Chu) Date: Wed, 20 Mar 2013 01:02:03 +0100 (CET) Subject: [pypy-commit] pypy py3k-struct: Pass byte strings into struct.{pack, unpack} instead of str strings when testing Message-ID: <20130320000203.7AF401C04AB@cobra.cs.uni-duesseldorf.de> Author: Jason Chu Branch: py3k-struct Changeset: r62517:4a1f0569d60f Date: 2013-03-19 13:21 -0700 http://bitbucket.org/pypy/pypy/changeset/4a1f0569d60f/ Log: Pass byte strings into struct.{pack,unpack} instead of str strings when testing diff --git a/lib-python/3/test/test_struct.py b/lib-python/3/test/test_struct.py --- a/lib-python/3/test/test_struct.py +++ b/lib-python/3/test/test_struct.py @@ -529,24 +529,24 @@ # format lists containing only count spec should result in an error self.assertRaises(struct.error, struct.pack, '12345') - self.assertRaises(struct.error, struct.unpack, '12345', '') + self.assertRaises(struct.error, struct.unpack, '12345', b'') self.assertRaises(struct.error, struct.pack_into, '12345', store, 0) self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0) # Format lists with trailing count spec should result in an error - self.assertRaises(struct.error, struct.pack, 'c12345', 'x') - self.assertRaises(struct.error, struct.unpack, 'c12345', 'x') + self.assertRaises(struct.error, struct.pack, 'c12345', b'x') + self.assertRaises(struct.error, struct.unpack, 'c12345', b'x') self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0, - 'x') + b'x') self.assertRaises(struct.error, struct.unpack_from, 'c12345', store, 0) # Mixed format tests - self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs') + self.assertRaises(struct.error, struct.pack, '14s42', b'spam and eggs') self.assertRaises(struct.error, struct.unpack, '14s42', - 'spam and eggs') + b'spam and eggs') self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0, - 'spam and eggs') + b'spam and eggs') self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0) def test_Struct_reinitialization(self): 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 @@ -7,7 +7,7 @@ class AppTestStruct(object): - spaceconfig = dict(usemodules=['struct']) + spaceconfig = dict(usemodules=['struct', 'array']) def setup_class(cls): """ @@ -386,6 +386,33 @@ assert self.struct.unpack("ii", b) == (62, 12) raises(self.struct.error, self.struct.unpack, "i", b) + def test_trailing_counter(self): + import array + store = array.array('b', b' '*100) + + # format lists containing only count spec should result in an error + raises(self.struct.error, self.struct.pack, '12345') + raises(self.struct.error, self.struct.unpack, '12345', b'') + raises(self.struct.error, self.struct.pack_into, '12345', store, 0) + raises(self.struct.error, self.struct.unpack_from, '12345', store, 0) + + # Format lists with trailing count spec should result in an error + raises(self.struct.error, self.struct.pack, 'c12345', b'x') + raises(self.struct.error, self.struct.unpack, 'c12345', b'x') + raises(self.struct.error, self.struct.pack_into, 'c12345', store, 0, + b'x') + raises(self.struct.error, self.struct.unpack_from, 'c12345', store, + 0) + + # Mixed format tests + raises(self.struct.error, self.struct.pack, '14s42', b'spam and eggs') + raises(self.struct.error, self.struct.unpack, '14s42', + b'spam and eggs') + raises(self.struct.error, self.struct.pack_into, '14s42', store, 0, + b'spam and eggs') + raises(self.struct.error, self.struct.unpack_from, '14s42', store, 0) + + class AppTestStructBuffer(object): spaceconfig = dict(usemodules=['struct', '__pypy__']) From noreply at buildbot.pypy.org Wed Mar 20 01:02:04 2013 From: noreply at buildbot.pypy.org (Jason Chu) Date: Wed, 20 Mar 2013 01:02:04 +0100 (CET) Subject: [pypy-commit] pypy py3k-struct: Don't accept floats in struct pack/unpack as per py3k test Message-ID: <20130320000204.C0AE81C04AB@cobra.cs.uni-duesseldorf.de> Author: Jason Chu Branch: py3k-struct Changeset: r62518:70bd50f9f372 Date: 2013-03-19 15:38 -0700 http://bitbucket.org/pypy/pypy/changeset/70bd50f9f372/ Log: Don't accept floats in struct pack/unpack as per py3k test Python 2 used to accept things like floats as arguments to struct.pack/unpack. This was done away with in Python 3, for good reason. 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 @@ -3,7 +3,6 @@ from rpython.rlib.rstring import StringBuilder from rpython.rlib.rstruct.error import StructError from rpython.rlib.rstruct.formatiterator import FormatIterator -from rpython.rlib.rstruct.standardfmttable import PACK_ACCEPTS_BROKEN_INPUT from pypy.interpreter.error import OperationError @@ -45,68 +44,39 @@ self.args_index += 1 return w_obj - if PACK_ACCEPTS_BROKEN_INPUT: - # permissive version - accepts float arguments too + # accepts objects with __index__es - def accept_int_arg(self): - return self._accept_integral("int_w") + def accept_int_arg(self): + return self._accept_integral("int_w") - def accept_uint_arg(self): - return self._accept_integral("uint_w") + def accept_uint_arg(self): + return self._accept_integral("uint_w") - def accept_longlong_arg(self): - return self._accept_integral("r_longlong_w") + def accept_longlong_arg(self): + return self._accept_integral("r_longlong_w") - def accept_ulonglong_arg(self): - return self._accept_integral("r_ulonglong_w") + def accept_ulonglong_arg(self): + return self._accept_integral("r_ulonglong_w") - @specialize.arg(1) - def _accept_integral(self, meth): - space = self.space - w_obj = self.accept_obj_arg() - if space.isinstance_w(w_obj, space.w_int): - w_index = w_obj - else: - w_index = None - w_index_method = space.lookup(w_obj, "__index__") - if w_index_method is not None: - try: - w_index = space.index(w_obj) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - pass - if w_index is None: - w_index = self._maybe_float(w_obj) - return getattr(space, meth)(w_index) - - def _maybe_float(self, w_obj): - space = self.space - if space.is_true(space.isinstance(w_obj, space.w_float)): - msg = "struct: integer argument expected, got float" - else: - msg = "integer argument expected, got non-integer" - space.warn(space.wrap(msg), space.w_DeprecationWarning) - return space.int(w_obj) # wrapped float -> wrapped int or long - - else: - # strict version - - def accept_int_arg(self): - w_obj = self.accept_obj_arg() - return self.space.int_w(w_obj) - - def accept_uint_arg(self): - w_obj = self.accept_obj_arg() - return self.space.uint_w(w_obj) - - def accept_longlong_arg(self): - w_obj = self.accept_obj_arg() - return self.space.r_longlong_w(w_obj) - - def accept_ulonglong_arg(self): - w_obj = self.accept_obj_arg() - return self.space.r_ulonglong_w(w_obj) + @specialize.arg(1) + def _accept_integral(self, meth): + space = self.space + w_obj = self.accept_obj_arg() + if space.isinstance_w(w_obj, space.w_int): + w_index = w_obj + else: + w_index = None + w_index_method = space.lookup(w_obj, "__index__") + if w_index_method is not None: + try: + w_index = space.index(w_obj) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + pass + if w_index is None: + raise StructError("required argument is not an integer") + return getattr(space, meth)(w_index) 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 @@ -61,17 +61,6 @@ assert self.struct.unpack("i", self.struct.pack("i", X()))[0] == 3 - def test_deprecation_warning(self): - import warnings - for code in 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q': - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - raises(TypeError, self.struct.pack, code, 3j) - assert len(w) == 1 - assert str(w[0].message) == "integer argument expected, got non-integer" - assert w[0].category is DeprecationWarning - - def test_pack_standard_little(self): """ Check packing with the '<' format specifier. @@ -412,7 +401,26 @@ b'spam and eggs') raises(self.struct.error, self.struct.unpack_from, '14s42', store, 0) - + def test_1530559(self): + # Native 'q' packing isn't available on systems that don't have the C + # long long type. + try: + self.struct.pack('q', 5) + except self.struct.error: + HAVE_LONG_LONG = False + else: + HAVE_LONG_LONG = True + integer_codes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q') + for byteorder in '', '@', '=', '<', '>', '!': + for code in integer_codes: + if (byteorder in ('', '@') and code in ('q', 'Q') and + not HAVE_LONG_LONG): + continue + format = byteorder + code + raises(self.struct.error, self.struct.pack, format, 1.0) + raises(self.struct.error, self.struct.pack, format, 1.5) + raises(self.struct.error, self.struct.pack, 'P', 1.0) + raises(self.struct.error, self.struct.pack, 'P', 1.5) class AppTestStructBuffer(object): spaceconfig = dict(usemodules=['struct', '__pypy__']) diff --git a/rpython/rlib/rstruct/standardfmttable.py b/rpython/rlib/rstruct/standardfmttable.py --- a/rpython/rlib/rstruct/standardfmttable.py +++ b/rpython/rlib/rstruct/standardfmttable.py @@ -13,12 +13,6 @@ from rpython.rlib.rstruct.error import StructError, StructOverflowError from rpython.rlib.unroll import unrolling_iterable -# In the CPython struct module, pack() unconsistently accepts inputs -# that are out-of-range or floats instead of ints. Should we emulate -# this? Let's use a flag for now: - -PACK_ACCEPTS_BROKEN_INPUT = True - # ____________________________________________________________ def pack_pad(fmtiter, count): @@ -100,10 +94,7 @@ return min, max, accept_method def make_int_packer(size, signed, cpython_checks_range, _memo={}): - if cpython_checks_range: - check_range = True - else: - check_range = not PACK_ACCEPTS_BROKEN_INPUT + check_range = True key = (size, signed, check_range) try: return _memo[key] From noreply at buildbot.pypy.org Wed Mar 20 01:02:06 2013 From: noreply at buildbot.pypy.org (Jason Chu) Date: Wed, 20 Mar 2013 01:02:06 +0100 (CET) Subject: [pypy-commit] pypy py3k-struct: Add a small struct test that was also failing from the buildbot for python 3 Message-ID: <20130320000206.0DEF51C04AB@cobra.cs.uni-duesseldorf.de> Author: Jason Chu Branch: py3k-struct Changeset: r62519:ee2033fb01d1 Date: 2013-03-19 15:57 -0700 http://bitbucket.org/pypy/pypy/changeset/ee2033fb01d1/ Log: Add a small struct test that was also failing from the buildbot for python 3 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 @@ -422,6 +422,35 @@ raises(self.struct.error, self.struct.pack, 'P', 1.0) raises(self.struct.error, self.struct.pack, 'P', 1.5) + def test_integers(self): + # Native 'q' packing isn't available on systems that don't have the C + # long long type. + try: + self.struct.pack('q', 5) + except self.struct.error: + HAVE_LONG_LONG = False + else: + HAVE_LONG_LONG = True + + integer_codes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q') + byteorders = '', '@', '=', '<', '>', '!' + + def run_not_int_test(format): + class NotAnInt: + def __int__(self): + return 42 + raises((TypeError, self.struct.error), + self.struct.pack, format, + NotAnInt()) + + for code in integer_codes: + for byteorder in byteorders: + if (byteorder in ('', '@') and code in ('q', 'Q') and + not HAVE_LONG_LONG): + continue + format = byteorder+code + t = run_not_int_test(format) + class AppTestStructBuffer(object): spaceconfig = dict(usemodules=['struct', '__pypy__']) From noreply at buildbot.pypy.org Wed Mar 20 01:02:07 2013 From: noreply at buildbot.pypy.org (Jason Chu) Date: Wed, 20 Mar 2013 01:02:07 +0100 (CET) Subject: [pypy-commit] pypy py3k-struct: Also check for a TypeError in test_crasher for struct tests Message-ID: <20130320000207.4FC911C04AB@cobra.cs.uni-duesseldorf.de> Author: Jason Chu Branch: py3k-struct Changeset: r62520:bc0dd18d6b57 Date: 2013-03-19 16:24 -0700 http://bitbucket.org/pypy/pypy/changeset/bc0dd18d6b57/ Log: Also check for a TypeError in test_crasher for struct tests diff --git a/lib-python/3/test/test_struct.py b/lib-python/3/test/test_struct.py --- a/lib-python/3/test/test_struct.py +++ b/lib-python/3/test/test_struct.py @@ -522,7 +522,8 @@ if IS32BIT: def test_crasher(self): - self.assertRaises(MemoryError, struct.pack, "357913941b", "a") + # Pypy catches the string error instead of calculating the entire size + self.assertRaises((MemoryError, TypeError), struct.pack, "357913941b", "a") def test_trailing_counter(self): store = array.array('b', b' '*100) From noreply at buildbot.pypy.org Wed Mar 20 01:02:08 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Mar 2013 01:02:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: Merged in xentac/pypy/py3k-struct (pull request #141) Message-ID: <20130320000208.8254C1C04AB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62521:5de0aa2e8003 Date: 2013-03-19 17:01 -0700 http://bitbucket.org/pypy/pypy/changeset/5de0aa2e8003/ Log: Merged in xentac/pypy/py3k-struct (pull request #141) Fix struct tests with for py3k diff --git a/lib-python/3/test/test_struct.py b/lib-python/3/test/test_struct.py --- a/lib-python/3/test/test_struct.py +++ b/lib-python/3/test/test_struct.py @@ -522,31 +522,32 @@ if IS32BIT: def test_crasher(self): - self.assertRaises(MemoryError, struct.pack, "357913941b", "a") + # Pypy catches the string error instead of calculating the entire size + self.assertRaises((MemoryError, TypeError), struct.pack, "357913941b", "a") def test_trailing_counter(self): store = array.array('b', b' '*100) # format lists containing only count spec should result in an error self.assertRaises(struct.error, struct.pack, '12345') - self.assertRaises(struct.error, struct.unpack, '12345', '') + self.assertRaises(struct.error, struct.unpack, '12345', b'') self.assertRaises(struct.error, struct.pack_into, '12345', store, 0) self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0) # Format lists with trailing count spec should result in an error - self.assertRaises(struct.error, struct.pack, 'c12345', 'x') - self.assertRaises(struct.error, struct.unpack, 'c12345', 'x') + self.assertRaises(struct.error, struct.pack, 'c12345', b'x') + self.assertRaises(struct.error, struct.unpack, 'c12345', b'x') self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0, - 'x') + b'x') self.assertRaises(struct.error, struct.unpack_from, 'c12345', store, 0) # Mixed format tests - self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs') + self.assertRaises(struct.error, struct.pack, '14s42', b'spam and eggs') self.assertRaises(struct.error, struct.unpack, '14s42', - 'spam and eggs') + b'spam and eggs') self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0, - 'spam and eggs') + b'spam and eggs') self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0) def test_Struct_reinitialization(self): 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 @@ -3,7 +3,6 @@ from rpython.rlib.rstring import StringBuilder from rpython.rlib.rstruct.error import StructError from rpython.rlib.rstruct.formatiterator import FormatIterator -from rpython.rlib.rstruct.standardfmttable import PACK_ACCEPTS_BROKEN_INPUT from pypy.interpreter.error import OperationError @@ -45,68 +44,39 @@ self.args_index += 1 return w_obj - if PACK_ACCEPTS_BROKEN_INPUT: - # permissive version - accepts float arguments too + # accepts objects with __index__es - def accept_int_arg(self): - return self._accept_integral("int_w") + def accept_int_arg(self): + return self._accept_integral("int_w") - def accept_uint_arg(self): - return self._accept_integral("uint_w") + def accept_uint_arg(self): + return self._accept_integral("uint_w") - def accept_longlong_arg(self): - return self._accept_integral("r_longlong_w") + def accept_longlong_arg(self): + return self._accept_integral("r_longlong_w") - def accept_ulonglong_arg(self): - return self._accept_integral("r_ulonglong_w") + def accept_ulonglong_arg(self): + return self._accept_integral("r_ulonglong_w") - @specialize.arg(1) - def _accept_integral(self, meth): - space = self.space - w_obj = self.accept_obj_arg() - if space.isinstance_w(w_obj, space.w_int): - w_index = w_obj - else: - w_index = None - w_index_method = space.lookup(w_obj, "__index__") - if w_index_method is not None: - try: - w_index = space.index(w_obj) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - pass - if w_index is None: - w_index = self._maybe_float(w_obj) - return getattr(space, meth)(w_index) - - def _maybe_float(self, w_obj): - space = self.space - if space.is_true(space.isinstance(w_obj, space.w_float)): - msg = "struct: integer argument expected, got float" - else: - msg = "integer argument expected, got non-integer" - space.warn(space.wrap(msg), space.w_DeprecationWarning) - return space.int(w_obj) # wrapped float -> wrapped int or long - - else: - # strict version - - def accept_int_arg(self): - w_obj = self.accept_obj_arg() - return self.space.int_w(w_obj) - - def accept_uint_arg(self): - w_obj = self.accept_obj_arg() - return self.space.uint_w(w_obj) - - def accept_longlong_arg(self): - w_obj = self.accept_obj_arg() - return self.space.r_longlong_w(w_obj) - - def accept_ulonglong_arg(self): - w_obj = self.accept_obj_arg() - return self.space.r_ulonglong_w(w_obj) + @specialize.arg(1) + def _accept_integral(self, meth): + space = self.space + w_obj = self.accept_obj_arg() + if space.isinstance_w(w_obj, space.w_int): + w_index = w_obj + else: + w_index = None + w_index_method = space.lookup(w_obj, "__index__") + if w_index_method is not None: + try: + w_index = space.index(w_obj) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + pass + if w_index is None: + raise StructError("required argument is not an integer") + return getattr(space, meth)(w_index) 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 @@ -7,7 +7,7 @@ class AppTestStruct(object): - spaceconfig = dict(usemodules=['struct']) + spaceconfig = dict(usemodules=['struct', 'array']) def setup_class(cls): """ @@ -61,17 +61,6 @@ assert self.struct.unpack("i", self.struct.pack("i", X()))[0] == 3 - def test_deprecation_warning(self): - import warnings - for code in 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q': - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - raises(TypeError, self.struct.pack, code, 3j) - assert len(w) == 1 - assert str(w[0].message) == "integer argument expected, got non-integer" - assert w[0].category is DeprecationWarning - - def test_pack_standard_little(self): """ Check packing with the '<' format specifier. @@ -386,6 +375,81 @@ assert self.struct.unpack("ii", b) == (62, 12) raises(self.struct.error, self.struct.unpack, "i", b) + def test_trailing_counter(self): + import array + store = array.array('b', b' '*100) + + # format lists containing only count spec should result in an error + raises(self.struct.error, self.struct.pack, '12345') + raises(self.struct.error, self.struct.unpack, '12345', b'') + raises(self.struct.error, self.struct.pack_into, '12345', store, 0) + raises(self.struct.error, self.struct.unpack_from, '12345', store, 0) + + # Format lists with trailing count spec should result in an error + raises(self.struct.error, self.struct.pack, 'c12345', b'x') + raises(self.struct.error, self.struct.unpack, 'c12345', b'x') + raises(self.struct.error, self.struct.pack_into, 'c12345', store, 0, + b'x') + raises(self.struct.error, self.struct.unpack_from, 'c12345', store, + 0) + + # Mixed format tests + raises(self.struct.error, self.struct.pack, '14s42', b'spam and eggs') + raises(self.struct.error, self.struct.unpack, '14s42', + b'spam and eggs') + raises(self.struct.error, self.struct.pack_into, '14s42', store, 0, + b'spam and eggs') + raises(self.struct.error, self.struct.unpack_from, '14s42', store, 0) + + def test_1530559(self): + # Native 'q' packing isn't available on systems that don't have the C + # long long type. + try: + self.struct.pack('q', 5) + except self.struct.error: + HAVE_LONG_LONG = False + else: + HAVE_LONG_LONG = True + integer_codes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q') + for byteorder in '', '@', '=', '<', '>', '!': + for code in integer_codes: + if (byteorder in ('', '@') and code in ('q', 'Q') and + not HAVE_LONG_LONG): + continue + format = byteorder + code + raises(self.struct.error, self.struct.pack, format, 1.0) + raises(self.struct.error, self.struct.pack, format, 1.5) + raises(self.struct.error, self.struct.pack, 'P', 1.0) + raises(self.struct.error, self.struct.pack, 'P', 1.5) + + def test_integers(self): + # Native 'q' packing isn't available on systems that don't have the C + # long long type. + try: + self.struct.pack('q', 5) + except self.struct.error: + HAVE_LONG_LONG = False + else: + HAVE_LONG_LONG = True + + integer_codes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q') + byteorders = '', '@', '=', '<', '>', '!' + + def run_not_int_test(format): + class NotAnInt: + def __int__(self): + return 42 + raises((TypeError, self.struct.error), + self.struct.pack, format, + NotAnInt()) + + for code in integer_codes: + for byteorder in byteorders: + if (byteorder in ('', '@') and code in ('q', 'Q') and + not HAVE_LONG_LONG): + continue + format = byteorder+code + t = run_not_int_test(format) class AppTestStructBuffer(object): spaceconfig = dict(usemodules=['struct', '__pypy__']) diff --git a/rpython/rlib/rstruct/standardfmttable.py b/rpython/rlib/rstruct/standardfmttable.py --- a/rpython/rlib/rstruct/standardfmttable.py +++ b/rpython/rlib/rstruct/standardfmttable.py @@ -13,12 +13,6 @@ from rpython.rlib.rstruct.error import StructError, StructOverflowError from rpython.rlib.unroll import unrolling_iterable -# In the CPython struct module, pack() unconsistently accepts inputs -# that are out-of-range or floats instead of ints. Should we emulate -# this? Let's use a flag for now: - -PACK_ACCEPTS_BROKEN_INPUT = True - # ____________________________________________________________ def pack_pad(fmtiter, count): @@ -100,10 +94,7 @@ return min, max, accept_method def make_int_packer(size, signed, cpython_checks_range, _memo={}): - if cpython_checks_range: - check_range = True - else: - check_range = not PACK_ACCEPTS_BROKEN_INPUT + check_range = True key = (size, signed, check_range) try: return _memo[key] From noreply at buildbot.pypy.org Wed Mar 20 01:06:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:06:38 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: kill another ANY_ANY_ANY Message-ID: <20130320000638.90F7F1C1016@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62522:0a87595e068a Date: 2013-03-19 17:05 -0700 http://bitbucket.org/pypy/pypy/changeset/0a87595e068a/ Log: kill another ANY_ANY_ANY 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 @@ -6,7 +6,9 @@ from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype -from pypy.interpreter import gateway, baseobjspace +from pypy.interpreter.gateway import WrappedDefault, unwrap_spec, applevel,\ + interp2app +from pypy.interpreter import baseobjspace from pypy.interpreter.signature import Signature from rpython.rlib.objectmodel import (instantiate, newlist_hint, specialize, resizelist_hint) @@ -323,7 +325,23 @@ argument reverse. Argument must be unwrapped.""" self.strategy.sort(self, reverse) - @gateway.unwrap_spec(reverse=bool) + @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(maxint)) + def descr_index(self, space, w_value, w_start, w_stop): + '''L.index(value, [start, [stop]]) -> integer -- return + first index of value''' + # needs to be safe against eq_w() mutating the w_list behind our back + size = self.length() + i, stop = slicetype.unwrap_start_stop( + space, size, w_start, w_stop, True) + while i < stop and i < self.length(): + if space.eq_w(self.getitem(i), w_value): + return space.wrap(i) + i += 1 + raise OperationError(space.w_ValueError, + space.wrap("list.index(x): x not in list")) + + + @unwrap_spec(reverse=bool) def descr_sort(self, space, w_cmp=None, w_key=None, reverse=False): """ L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*; @@ -1452,7 +1470,7 @@ w_other = W_ListObject(space, sequence_w) w_list.setslice(start, step, slicelength, w_other) -app = gateway.applevel(""" +app = applevel(""" def listrepr(currently_in_repr, l): 'The app-level part of repr().' list_id = id(l) @@ -1538,18 +1556,6 @@ raise OperationError(space.w_ValueError, space.wrap("list.remove(x): x not in list")) -def list_index__List_ANY_ANY_ANY(space, w_list, w_any, w_start, w_stop): - # needs to be safe against eq_w() mutating the w_list behind our back - size = w_list.length() - i, stop = slicetype.unwrap_start_stop( - space, size, w_start, w_stop, True) - while i < stop and i < w_list.length(): - if space.eq_w(w_list.getitem(i), w_any): - return space.wrap(i) - i += 1 - raise OperationError(space.w_ValueError, - space.wrap("list.index(x): x not in list")) - def list_count__List_ANY(space, w_list, w_any): # needs to be safe against eq_w() mutating the w_list behind our back count = 0 @@ -1663,9 +1669,6 @@ ' index (default last)') list_remove = SMM('remove', 2, doc='L.remove(value) -- remove first occurrence of value') -list_index = SMM('index', 4, defaults=(0,maxint), - doc='L.index(value, [start, [stop]]) -> integer -- return' - ' first index of value') list_count = SMM('count', 2, doc='L.count(value) -> integer -- return number of' ' occurrences of value') @@ -1680,9 +1683,10 @@ W_ListObject.typedef = StdTypeDef("list", __doc__ = """list() -> new list list(sequence) -> new list initialized from sequence's items""", - __new__ = gateway.interp2app(descr_new), + __new__ = interp2app(descr_new), __hash__ = None, - sort = gateway.interp2app(W_ListObject.descr_sort), + sort = interp2app(W_ListObject.descr_sort), + index = interp2app(W_ListObject.descr_index), ) W_ListObject.typedef.registermethods(globals()) diff --git a/pypy/objspace/std/slicetype.py b/pypy/objspace/std/slicetype.py --- a/pypy/objspace/std/slicetype.py +++ b/pypy/objspace/std/slicetype.py @@ -45,14 +45,14 @@ @specialize.arg(4) def unwrap_start_stop(space, size, w_start, w_end, upper_bound=False): - if space.is_w(w_start, space.w_None): + if space.is_none(w_start): start = 0 elif upper_bound: start = adapt_bound(space, size, w_start) else: start = adapt_lower_bound(space, size, w_start) - if space.is_w(w_end, space.w_None): + if space.is_none(w_end): end = size elif upper_bound: end = adapt_bound(space, size, w_end) From noreply at buildbot.pypy.org Wed Mar 20 01:06:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:06:39 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: merge Message-ID: <20130320000639.D89531C1016@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62523:161c96abab58 Date: 2013-03-19 17:06 -0700 http://bitbucket.org/pypy/pypy/changeset/161c96abab58/ Log: merge diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py --- a/pypy/module/__builtin__/test/test_builtin.py +++ b/pypy/module/__builtin__/test/test_builtin.py @@ -347,6 +347,7 @@ sorted_l = sorted(l, reverse = True, key = lambda x: x.lower()) assert sorted_l is not l assert sorted_l == ['C', 'b', 'a'] + raises(TypeError, sorted, [], reverse=None) def test_reversed_simple_sequences(self): l = range(5) From noreply at buildbot.pypy.org Wed Mar 20 01:34:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:34:34 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: remove more crap Message-ID: <20130320003434.394F51C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62524:2be78ef9f669 Date: 2013-03-19 17:34 -0700 http://bitbucket.org/pypy/pypy/changeset/2be78ef9f669/ Log: remove more crap diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -560,14 +560,14 @@ # __________________________________________________________ # Mutability methods -def list_append__Bytearray_ANY(space, w_bytearray, w_item): +def bytearray_append__Bytearray_ANY(space, w_bytearray, w_item): from pypy.objspace.std.bytearraytype import getbytevalue w_bytearray.data.append(getbytevalue(space, w_item)) -def list_extend__Bytearray_Bytearray(space, w_bytearray, w_other): +def bytearray_extend__Bytearray_Bytearray(space, w_bytearray, w_other): w_bytearray.data += w_other.data -def list_extend__Bytearray_ANY(space, w_bytearray, w_other): +def bytearray_extend__Bytearray_ANY(space, w_bytearray, w_other): w_bytearray.data += makebytearraydata_w(space, w_other) def inplace_add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2): diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -13,11 +13,11 @@ str_expandtabs, str_ljust, str_rjust, str_center, str_zfill, str_join, str_split, str_rsplit, str_partition, str_rpartition, str_splitlines, str_translate) -from pypy.objspace.std.listobject import list_append, list_extend from rpython.rlib.objectmodel import newlist_hint, resizelist_hint - +bytearray_append = SMM('append', 2) +bytearray_extend = SMM('extend', 2) bytearray_insert = SMM('insert', 3, doc="B.insert(index, int) -> None\n\n" "Insert a single item into the bytearray before " 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 @@ -214,9 +214,9 @@ in the list.""" return self.strategy.contains(self, w_obj) - def append(w_list, w_item): - """Appends the wrapped item to the end of the list.""" - w_list.strategy.append(w_list, w_item) + def append(self, w_item): + 'L.append(object) -- append object to end' + self.strategy.append(self, w_item) def length(self): return self.strategy.length(self) @@ -312,9 +312,10 @@ index not.""" self.strategy.insert(self, index, w_item) - def extend(self, w_any): - """Appends the given list of wrapped items.""" - self.strategy.extend(self, w_any) + def extend(self, w_iterable): + '''L.extend(iterable) -- extend list by appending + elements from the iterable''' + self.strategy.extend(self, w_iterable) def reverse(self): """Reverses the list.""" @@ -325,6 +326,68 @@ argument reverse. Argument must be unwrapped.""" self.strategy.sort(self, reverse) + def descr_reversed(self, space): + 'L.__reversed__() -- return a reverse iterator over the list' + from pypy.objspace.std.iterobject import W_ReverseSeqIterObject + return W_ReverseSeqIterObject(space, self, -1) + + def descr_reverse(self, space): + 'L.reverse() -- reverse *IN PLACE*' + self.reverse() + return space.w_None + + def descr_count(self, space, w_value): + '''L.count(value) -> integer -- return number of + occurrences of value''' + # needs to be safe against eq_w() mutating the w_list behind our back + count = 0 + i = 0 + while i < self.length(): + if space.eq_w(self.getitem(i), w_value): + count += 1 + i += 1 + return space.wrap(count) + + @unwrap_spec(index=int) + def descr_insert(self, space, index, w_value): + 'L.insert(index, object) -- insert object before index' + length = self.length() + index = get_positive_index(index, length) + self.insert(index, w_value) + return space.w_None + + @unwrap_spec(index=int) + def descr_pop(self, space, index=-1): + '''L.pop([index]) -> item -- remove and return item at + index (default last)''' + length = self.length() + if length == 0: + raise OperationError(space.w_IndexError, + space.wrap("pop from empty list")) + # clearly differentiate between list.pop() and list.pop(index) + if index == -1: + return self.pop_end() # cannot raise because list is not empty + if index < 0: + index += length + try: + return self.pop(index) + except IndexError: + raise OperationError(space.w_IndexError, + space.wrap("pop index out of range")) + + def descr_remove(self, space, w_value): + 'L.remove(value) -- remove first occurrence of value' + # needs to be safe against eq_w() mutating the w_list behind our back + i = 0 + while i < self.length(): + if space.eq_w(self.getitem(i), w_value): + if i < self.length(): # if this is wrong the list was changed + self.pop(i) + return space.w_None + i += 1 + raise OperationError(space.w_ValueError, + space.wrap("list.remove(x): x not in list")) + @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(maxint)) def descr_index(self, space, w_value, w_start, w_stop): '''L.index(value, [start, [stop]]) -> integer -- return @@ -340,7 +403,6 @@ raise OperationError(space.w_ValueError, space.wrap("list.index(x): x not in list")) - @unwrap_spec(reverse=bool) def descr_sort(self, space, w_cmp=None, w_key=None, reverse=False): """ L.sort(cmp=None, key=None, reverse=False) -- stable @@ -1359,7 +1421,7 @@ def inplace_add__List_ANY(space, w_list1, w_iterable2): try: - list_extend__List_ANY(space, w_list1, w_iterable2) + w_list1.extend(w_iterable2) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -1367,7 +1429,7 @@ return w_list1 def inplace_add__List_List(space, w_list1, w_list2): - list_extend__List_ANY(space, w_list1, w_list2) + w_list1.extend(w_list2) return w_list1 def mul_list_times(space, w_list, w_times): @@ -1497,13 +1559,6 @@ w_currently_in_repr = ec._py_repr = space.newdict() return listrepr(space, w_currently_in_repr, w_list) -def list_insert__List_ANY_ANY(space, w_list, w_where, w_any): - where = space.int_w(w_where) - length = w_list.length() - index = get_positive_index(where, length) - w_list.insert(index, w_any) - return space.w_None - def get_positive_index(where, length): if where < 0: where += length @@ -1514,62 +1569,6 @@ assert where >= 0 return where -def list_append__List_ANY(space, w_list, w_any): - w_list.append(w_any) - return space.w_None - -def list_extend__List_ANY(space, w_list, w_any): - w_list.extend(w_any) - return space.w_None - -# default of w_idx is space.w_None (see listtype.py) -def list_pop__List_ANY(space, w_list, w_idx): - length = w_list.length() - if length == 0: - raise OperationError(space.w_IndexError, - space.wrap("pop from empty list")) - # clearly differentiate between list.pop() and list.pop(index) - if space.is_w(w_idx, space.w_None): - return w_list.pop_end() # cannot raise because list is not empty - if space.isinstance_w(w_idx, space.w_float): - raise OperationError(space.w_TypeError, - space.wrap("integer argument expected, got float") - ) - idx = space.int_w(space.int(w_idx)) - if idx < 0: - idx += length - try: - return w_list.pop(idx) - except IndexError: - raise OperationError(space.w_IndexError, - space.wrap("pop index out of range")) - -def list_remove__List_ANY(space, w_list, w_any): - # needs to be safe against eq_w() mutating the w_list behind our back - i = 0 - while i < w_list.length(): - if space.eq_w(w_list.getitem(i), w_any): - if i < w_list.length(): # if this is wrong the list was changed - w_list.pop(i) - return space.w_None - i += 1 - raise OperationError(space.w_ValueError, - space.wrap("list.remove(x): x not in list")) - -def list_count__List_ANY(space, w_list, w_any): - # needs to be safe against eq_w() mutating the w_list behind our back - count = 0 - i = 0 - while i < w_list.length(): - if space.eq_w(w_list.getitem(i), w_any): - count += 1 - i += 1 - return space.wrap(count) - -def list_reverse__List(space, w_list): - w_list.reverse() - return space.w_None - # ____________________________________________________________ # Sorting @@ -1639,10 +1638,6 @@ assert isinstance(b, KeyContainer) return CustomCompareSort.lt(self, a.w_key, b.w_key) -def list_reversed__ANY(space, w_list): - from pypy.objspace.std.iterobject import W_ReverseSeqIterObject - return W_ReverseSeqIterObject(space, w_list, -1) - # ____________________________________________________________ def descr_new(space, w_listtype, __args__): @@ -1657,27 +1652,6 @@ def get_list_index(space, w_index): return space.getindex_w(w_index, space.w_IndexError, "list index") -list_append = SMM('append', 2, - doc='L.append(object) -- append object to end') -list_insert = SMM('insert', 3, - doc='L.insert(index, object) -- insert object before index') -list_extend = SMM('extend', 2, - doc='L.extend(iterable) -- extend list by appending' - ' elements from the iterable') -list_pop = SMM('pop', 2, defaults=(None,), - doc='L.pop([index]) -> item -- remove and return item at' - ' index (default last)') -list_remove = SMM('remove', 2, - doc='L.remove(value) -- remove first occurrence of value') -list_count = SMM('count', 2, - doc='L.count(value) -> integer -- return number of' - ' occurrences of value') -list_reverse = SMM('reverse',1, - doc='L.reverse() -- reverse *IN PLACE*') -list_reversed = SMM('__reversed__', 1, - doc='L.__reversed__() -- return a reverse iterator over' - ' the list') - register_all(vars(), globals()) W_ListObject.typedef = StdTypeDef("list", @@ -1687,6 +1661,14 @@ __hash__ = None, sort = interp2app(W_ListObject.descr_sort), index = interp2app(W_ListObject.descr_index), + append = interp2app(W_ListObject.append), + reverse = interp2app(W_ListObject.descr_reverse), + __reversed__ = interp2app(W_ListObject.descr_reversed), + count = interp2app(W_ListObject.descr_count), + pop = interp2app(W_ListObject.descr_pop), + extend = interp2app(W_ListObject.extend), + insert = interp2app(W_ListObject.descr_insert), + remove = interp2app(W_ListObject.descr_remove), ) W_ListObject.typedef.registermethods(globals()) From noreply at buildbot.pypy.org Wed Mar 20 01:49:40 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Mar 2013 01:49:40 +0100 (CET) Subject: [pypy-commit] pypy default: support the 6.0.0 db: add its cjk_interval and handle east asian width ranges Message-ID: <20130320004940.541201C1016@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62525:5606e1cd236f Date: 2013-03-19 16:30 -0700 http://bitbucket.org/pypy/pypy/changeset/5606e1cd236f/ Log: support the 6.0.0 db: add its cjk_interval and handle east asian width ranges overlapping the general UnicodeData-x.x.x.txt ranges diff --git a/rpython/rlib/unicodedata/generate_unicodedb.py b/rpython/rlib/unicodedata/generate_unicodedb.py --- a/rpython/rlib/unicodedata/generate_unicodedb.py +++ b/rpython/rlib/unicodedata/generate_unicodedb.py @@ -152,6 +152,12 @@ for char in range(first, last+1): table[char].linebreak = True + # Expand ranges + for (first, last), char in ranges.iteritems(): + for code in range(first, last + 1): + assert table[code] is None, 'Multiply defined character %04X' % code + table[code] = char + # Read east asian width for line in east_asian_width_file: line = line.split('#', 1)[0].strip() @@ -160,22 +166,15 @@ code, width = line.split(';') if '..' in code: first, last = map(lambda x:int(x,16), code.split('..')) - try: - ranges[(first, last)].east_asian_width = width - except KeyError: - ch = Unicodechar(['0000', None, 'Cn'] + [''] * 12) - ch.east_asian_width = width - ranges[(first, last)] = ch + for code in range(first, last + 1): + uc = table[code] + if uc is None: + uc = table[code] = Unicodechar(['0000', None, + 'Cn'] + [''] * 12) + uc.east_asian_width = width else: table[int(code, 16)].east_asian_width = width - # Expand ranges - for (first, last), char in ranges.iteritems(): - for code in range(first, last + 1): - assert table[code] is None, 'Multiply defined character %04X' % code - - table[code] = char - # Read Derived Core Properties: for line in derived_core_properties_file: line = line.split('#', 1)[0].strip() @@ -446,11 +445,17 @@ cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FBB or" " 0x20000 <= code <= 0x2A6D6)") + elif version < "6": + cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" + " 0x4E00 <= code <= 0x9FCB or" + " 0x20000 <= code <= 0x2A6D6 or" + " 0x2A700 <= code <= 0x2B734)") else: cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FCB or" " 0x20000 <= code <= 0x2A6D6 or" - " 0x2A700 <= code <= 0x2B734)") + " 0x2A700 <= code <= 0x2B734 or" + " 0x2B740 <= code <= 0x2B81D)") write_character_names(outfile, table, base_mod) From noreply at buildbot.pypy.org Wed Mar 20 01:49:43 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Mar 2013 01:49:43 +0100 (CET) Subject: [pypy-commit] pypy default: add the unicode 6.0.0 db Message-ID: <20130320004943.061051C1016@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62526:e4933b60d29e Date: 2013-03-19 16:39 -0700 http://bitbucket.org/pypy/pypy/changeset/e4933b60d29e/ Log: add the unicode 6.0.0 db diff too long, truncating to 2000 out of 87914 lines diff --git a/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt b/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt @@ -0,0 +1,206 @@ +# CompositionExclusions-6.0.0.txt +# Date: 2010-06-25, 14:34:00 PDT [KW] +# +# This file lists the characters for the Composition Exclusion Table +# defined in UAX #15, Unicode Normalization Forms. +# +# This file is a normative contributory data file in the +# Unicode Character Database. +# +# Copyright (c) 1991-2010 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# For more information, see +# http://www.unicode.org/unicode/reports/tr15/#Primary_Exclusion_List_Table +# +# For a full derivation of composition exclusions, see the derived property +# Full_Composition_Exclusion in DerivedNormalizationProps.txt +# + +# ================================================ +# (1) Script Specifics +# +# This list of characters cannot be derived from the UnicodeData.txt file. +# ================================================ + +0958 # DEVANAGARI LETTER QA +0959 # DEVANAGARI LETTER KHHA +095A # DEVANAGARI LETTER GHHA +095B # DEVANAGARI LETTER ZA +095C # DEVANAGARI LETTER DDDHA +095D # DEVANAGARI LETTER RHA +095E # DEVANAGARI LETTER FA +095F # DEVANAGARI LETTER YYA +09DC # BENGALI LETTER RRA +09DD # BENGALI LETTER RHA +09DF # BENGALI LETTER YYA +0A33 # GURMUKHI LETTER LLA +0A36 # GURMUKHI LETTER SHA +0A59 # GURMUKHI LETTER KHHA +0A5A # GURMUKHI LETTER GHHA +0A5B # GURMUKHI LETTER ZA +0A5E # GURMUKHI LETTER FA +0B5C # ORIYA LETTER RRA +0B5D # ORIYA LETTER RHA +0F43 # TIBETAN LETTER GHA +0F4D # TIBETAN LETTER DDHA +0F52 # TIBETAN LETTER DHA +0F57 # TIBETAN LETTER BHA +0F5C # TIBETAN LETTER DZHA +0F69 # TIBETAN LETTER KSSA +0F76 # TIBETAN VOWEL SIGN VOCALIC R +0F78 # TIBETAN VOWEL SIGN VOCALIC L +0F93 # TIBETAN SUBJOINED LETTER GHA +0F9D # TIBETAN SUBJOINED LETTER DDHA +0FA2 # TIBETAN SUBJOINED LETTER DHA +0FA7 # TIBETAN SUBJOINED LETTER BHA +0FAC # TIBETAN SUBJOINED LETTER DZHA +0FB9 # TIBETAN SUBJOINED LETTER KSSA +FB1D # HEBREW LETTER YOD WITH HIRIQ +FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH +FB2A # HEBREW LETTER SHIN WITH SHIN DOT +FB2B # HEBREW LETTER SHIN WITH SIN DOT +FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT +FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT +FB2E # HEBREW LETTER ALEF WITH PATAH +FB2F # HEBREW LETTER ALEF WITH QAMATS +FB30 # HEBREW LETTER ALEF WITH MAPIQ +FB31 # HEBREW LETTER BET WITH DAGESH +FB32 # HEBREW LETTER GIMEL WITH DAGESH +FB33 # HEBREW LETTER DALET WITH DAGESH +FB34 # HEBREW LETTER HE WITH MAPIQ +FB35 # HEBREW LETTER VAV WITH DAGESH +FB36 # HEBREW LETTER ZAYIN WITH DAGESH +FB38 # HEBREW LETTER TET WITH DAGESH +FB39 # HEBREW LETTER YOD WITH DAGESH +FB3A # HEBREW LETTER FINAL KAF WITH DAGESH +FB3B # HEBREW LETTER KAF WITH DAGESH +FB3C # HEBREW LETTER LAMED WITH DAGESH +FB3E # HEBREW LETTER MEM WITH DAGESH +FB40 # HEBREW LETTER NUN WITH DAGESH +FB41 # HEBREW LETTER SAMEKH WITH DAGESH +FB43 # HEBREW LETTER FINAL PE WITH DAGESH +FB44 # HEBREW LETTER PE WITH DAGESH +FB46 # HEBREW LETTER TSADI WITH DAGESH +FB47 # HEBREW LETTER QOF WITH DAGESH +FB48 # HEBREW LETTER RESH WITH DAGESH +FB49 # HEBREW LETTER SHIN WITH DAGESH +FB4A # HEBREW LETTER TAV WITH DAGESH +FB4B # HEBREW LETTER VAV WITH HOLAM +FB4C # HEBREW LETTER BET WITH RAFE +FB4D # HEBREW LETTER KAF WITH RAFE +FB4E # HEBREW LETTER PE WITH RAFE + +# Total code points: 67 + +# ================================================ +# (2) Post Composition Version precomposed characters +# +# These characters cannot be derived solely from the UnicodeData.txt file +# in this version of Unicode. +# +# Note that characters added to the standard after the +# Composition Version and which have canonical decomposition mappings +# are not automatically added to this list of Post Composition +# Version precomposed characters. +# ================================================ + +2ADC # FORKING +1D15E # MUSICAL SYMBOL HALF NOTE +1D15F # MUSICAL SYMBOL QUARTER NOTE +1D160 # MUSICAL SYMBOL EIGHTH NOTE +1D161 # MUSICAL SYMBOL SIXTEENTH NOTE +1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE +1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE +1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D1BB # MUSICAL SYMBOL MINIMA +1D1BC # MUSICAL SYMBOL MINIMA BLACK +1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE +1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK +1D1BF # MUSICAL SYMBOL FUSA WHITE +1D1C0 # MUSICAL SYMBOL FUSA BLACK + +# Total code points: 14 + +# ================================================ +# (3) Singleton Decompositions +# +# These characters can be derived from the UnicodeData.txt file +# by including all canonically decomposable characters whose +# canonical decomposition consists of a single character. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK +# 0343 COMBINING GREEK KORONIS +# 0374 GREEK NUMERAL SIGN +# 037E GREEK QUESTION MARK +# 0387 GREEK ANO TELEIA +# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA +# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA +# 1F75 GREEK SMALL LETTER ETA WITH OXIA +# 1F77 GREEK SMALL LETTER IOTA WITH OXIA +# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA +# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA +# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA +# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA +# 1FBE GREEK PROSGEGRAMMENI +# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA +# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA +# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA +# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA +# 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA +# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA +# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA +# 1FFD GREEK OXIA +# 2000..2001 [2] EN QUAD..EM QUAD +# 2126 OHM SIGN +# 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN +# 2329 LEFT-POINTING ANGLE BRACKET +# 232A RIGHT-POINTING ANGLE BRACKET +# F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D +# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10 +# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12 +# FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E +# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20 +# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22 +# FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26 +# FA2A..FA2D [4] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA2D +# FA30..FA6D [62] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6D +# FA70..FAD9 [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +# 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 1033 + +# ================================================ +# (4) Non-Starter Decompositions +# +# These characters can be derived from the UnicodeData file +# by including each expanding canonical decomposition +# (i.e., those which canonically decompose to a sequence +# of characters instead of a single character), such that: +# +# A. The character is not a Starter. +# +# OR (inclusive) +# +# B. The character's canonical decomposition begins +# with a character that is not a Starter. +# +# Note that a "Starter" is any character with a zero combining class. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0344 COMBINING GREEK DIALYTIKA TONOS +# 0F73 TIBETAN VOWEL SIGN II +# 0F75 TIBETAN VOWEL SIGN UU +# 0F81 TIBETAN VOWEL SIGN REVERSED II + +# Total code points: 4 + diff --git a/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt b/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt @@ -0,0 +1,9482 @@ +# DerivedCoreProperties-6.0.0.txt +# Date: 2010-08-19, 00:48:05 GMT [MD] +# +# Unicode Character Database +# Copyright (c) 1991-2010 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# For documentation, see http://www.unicode.org/reports/tr44/ + +# ================================================ + +# Derived Property: Math +# Generated from: Sm + Other_Math + +002B ; Math # Sm PLUS SIGN +003C..003E ; Math # Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN +005E ; Math # Sk CIRCUMFLEX ACCENT +007C ; Math # Sm VERTICAL LINE +007E ; Math # Sm TILDE +00AC ; Math # Sm NOT SIGN +00B1 ; Math # Sm PLUS-MINUS SIGN +00D7 ; Math # Sm MULTIPLICATION SIGN +00F7 ; Math # Sm DIVISION SIGN +03D0..03D2 ; Math # L& [3] GREEK BETA SYMBOL..GREEK UPSILON WITH HOOK SYMBOL +03D5 ; Math # L& GREEK PHI SYMBOL +03F0..03F1 ; Math # L& [2] GREEK KAPPA SYMBOL..GREEK RHO SYMBOL +03F4..03F5 ; Math # L& [2] GREEK CAPITAL THETA SYMBOL..GREEK LUNATE EPSILON SYMBOL +03F6 ; Math # Sm GREEK REVERSED LUNATE EPSILON SYMBOL +0606..0608 ; Math # Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY +2016 ; Math # Po DOUBLE VERTICAL LINE +2032..2034 ; Math # Po [3] PRIME..TRIPLE PRIME +2040 ; Math # Pc CHARACTER TIE +2044 ; Math # Sm FRACTION SLASH +2052 ; Math # Sm COMMERCIAL MINUS SIGN +2061..2064 ; Math # Cf [4] FUNCTION APPLICATION..INVISIBLE PLUS +207A..207C ; Math # Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN +207D ; Math # Ps SUPERSCRIPT LEFT PARENTHESIS +207E ; Math # Pe SUPERSCRIPT RIGHT PARENTHESIS +208A..208C ; Math # Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN +208D ; Math # Ps SUBSCRIPT LEFT PARENTHESIS +208E ; Math # Pe SUBSCRIPT RIGHT PARENTHESIS +20D0..20DC ; Math # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE +20E1 ; Math # Mn COMBINING LEFT RIGHT ARROW ABOVE +20E5..20E6 ; Math # Mn [2] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING DOUBLE VERTICAL STROKE OVERLAY +20EB..20EF ; Math # Mn [5] COMBINING LONG DOUBLE SOLIDUS OVERLAY..COMBINING RIGHT ARROW BELOW +2102 ; Math # L& DOUBLE-STRUCK CAPITAL C +2107 ; Math # L& EULER CONSTANT +210A..2113 ; Math # L& [10] SCRIPT SMALL G..SCRIPT SMALL L +2115 ; Math # L& DOUBLE-STRUCK CAPITAL N +2118 ; Math # Sm SCRIPT CAPITAL P +2119..211D ; Math # L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +2124 ; Math # L& DOUBLE-STRUCK CAPITAL Z +2128 ; Math # L& BLACK-LETTER CAPITAL Z +2129 ; Math # So TURNED GREEK SMALL LETTER IOTA +212C..212D ; Math # L& [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C +212F..2131 ; Math # L& [3] SCRIPT SMALL E..SCRIPT CAPITAL F +2133..2134 ; Math # L& [2] SCRIPT CAPITAL M..SCRIPT SMALL O +2135..2138 ; Math # Lo [4] ALEF SYMBOL..DALET SYMBOL +213C..213F ; Math # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI +2140..2144 ; Math # Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y +2145..2149 ; Math # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J +214B ; Math # Sm TURNED AMPERSAND +2190..2194 ; Math # Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW +2195..2199 ; Math # So [5] UP DOWN ARROW..SOUTH WEST ARROW +219A..219B ; Math # Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE +219C..219F ; Math # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW +21A0 ; Math # Sm RIGHTWARDS TWO HEADED ARROW +21A1..21A2 ; Math # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL +21A3 ; Math # Sm RIGHTWARDS ARROW WITH TAIL +21A4..21A5 ; Math # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR +21A6 ; Math # Sm RIGHTWARDS ARROW FROM BAR +21A7 ; Math # So DOWNWARDS ARROW FROM BAR +21A9..21AD ; Math # So [5] LEFTWARDS ARROW WITH HOOK..LEFT RIGHT WAVE ARROW +21AE ; Math # Sm LEFT RIGHT ARROW WITH STROKE +21B0..21B1 ; Math # So [2] UPWARDS ARROW WITH TIP LEFTWARDS..UPWARDS ARROW WITH TIP RIGHTWARDS +21B6..21B7 ; Math # So [2] ANTICLOCKWISE TOP SEMICIRCLE ARROW..CLOCKWISE TOP SEMICIRCLE ARROW +21BC..21CD ; Math # So [18] LEFTWARDS HARPOON WITH BARB UPWARDS..LEFTWARDS DOUBLE ARROW WITH STROKE +21CE..21CF ; Math # Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE +21D0..21D1 ; Math # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW +21D2 ; Math # Sm RIGHTWARDS DOUBLE ARROW +21D3 ; Math # So DOWNWARDS DOUBLE ARROW +21D4 ; Math # Sm LEFT RIGHT DOUBLE ARROW +21D5..21DB ; Math # So [7] UP DOWN DOUBLE ARROW..RIGHTWARDS TRIPLE ARROW +21DD ; Math # So RIGHTWARDS SQUIGGLE ARROW +21E4..21E5 ; Math # So [2] LEFTWARDS ARROW TO BAR..RIGHTWARDS ARROW TO BAR +21F4..22FF ; Math # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP +2308..230B ; Math # Sm [4] LEFT CEILING..RIGHT FLOOR +2320..2321 ; Math # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL +237C ; Math # Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +239B..23B3 ; Math # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM +23B4..23B5 ; Math # So [2] TOP SQUARE BRACKET..BOTTOM SQUARE BRACKET +23B7 ; Math # So RADICAL SYMBOL BOTTOM +23D0 ; Math # So VERTICAL LINE EXTENSION +23DC..23E1 ; Math # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET +23E2 ; Math # So WHITE TRAPEZIUM +25A0..25A1 ; Math # So [2] BLACK SQUARE..WHITE SQUARE +25AE..25B6 ; Math # So [9] BLACK VERTICAL RECTANGLE..BLACK RIGHT-POINTING TRIANGLE +25B7 ; Math # Sm WHITE RIGHT-POINTING TRIANGLE +25BC..25C0 ; Math # So [5] BLACK DOWN-POINTING TRIANGLE..BLACK LEFT-POINTING TRIANGLE +25C1 ; Math # Sm WHITE LEFT-POINTING TRIANGLE +25C6..25C7 ; Math # So [2] BLACK DIAMOND..WHITE DIAMOND +25CA..25CB ; Math # So [2] LOZENGE..WHITE CIRCLE +25CF..25D3 ; Math # So [5] BLACK CIRCLE..CIRCLE WITH UPPER HALF BLACK +25E2 ; Math # So BLACK LOWER RIGHT TRIANGLE +25E4 ; Math # So BLACK UPPER LEFT TRIANGLE +25E7..25EC ; Math # So [6] SQUARE WITH LEFT HALF BLACK..WHITE UP-POINTING TRIANGLE WITH DOT +25F8..25FF ; Math # Sm [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE +2605..2606 ; Math # So [2] BLACK STAR..WHITE STAR +2640 ; Math # So FEMALE SIGN +2642 ; Math # So MALE SIGN +2660..2663 ; Math # So [4] BLACK SPADE SUIT..BLACK CLUB SUIT +266D..266E ; Math # So [2] MUSIC FLAT SIGN..MUSIC NATURAL SIGN +266F ; Math # Sm MUSIC SHARP SIGN +27C0..27C4 ; Math # Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET +27C5 ; Math # Ps LEFT S-SHAPED BAG DELIMITER +27C6 ; Math # Pe RIGHT S-SHAPED BAG DELIMITER +27C7..27CA ; Math # Sm [4] OR WITH DOT INSIDE..VERTICAL BAR WITH HORIZONTAL STROKE +27CC ; Math # Sm LONG DIVISION +27CE..27E5 ; Math # Sm [24] SQUARED LOGICAL AND..WHITE SQUARE WITH RIGHTWARDS TICK +27E6 ; Math # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E7 ; Math # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E8 ; Math # Ps MATHEMATICAL LEFT ANGLE BRACKET +27E9 ; Math # Pe MATHEMATICAL RIGHT ANGLE BRACKET +27EA ; Math # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EB ; Math # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27EC ; Math # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27ED ; Math # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EE ; Math # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS +27EF ; Math # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS +27F0..27FF ; Math # Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW +2900..2982 ; Math # Sm [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON +2983 ; Math # Ps LEFT WHITE CURLY BRACKET +2984 ; Math # Pe RIGHT WHITE CURLY BRACKET +2985 ; Math # Ps LEFT WHITE PARENTHESIS +2986 ; Math # Pe RIGHT WHITE PARENTHESIS +2987 ; Math # Ps Z NOTATION LEFT IMAGE BRACKET +2988 ; Math # Pe Z NOTATION RIGHT IMAGE BRACKET +2989 ; Math # Ps Z NOTATION LEFT BINDING BRACKET +298A ; Math # Pe Z NOTATION RIGHT BINDING BRACKET +298B ; Math # Ps LEFT SQUARE BRACKET WITH UNDERBAR +298C ; Math # Pe RIGHT SQUARE BRACKET WITH UNDERBAR +298D ; Math # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298E ; Math # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +298F ; Math # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990 ; Math # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2991 ; Math # Ps LEFT ANGLE BRACKET WITH DOT +2992 ; Math # Pe RIGHT ANGLE BRACKET WITH DOT +2993 ; Math # Ps LEFT ARC LESS-THAN BRACKET +2994 ; Math # Pe RIGHT ARC GREATER-THAN BRACKET +2995 ; Math # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET +2996 ; Math # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET +2997 ; Math # Ps LEFT BLACK TORTOISE SHELL BRACKET +2998 ; Math # Pe RIGHT BLACK TORTOISE SHELL BRACKET +2999..29D7 ; Math # Sm [63] DOTTED FENCE..BLACK HOURGLASS +29D8 ; Math # Ps LEFT WIGGLY FENCE +29D9 ; Math # Pe RIGHT WIGGLY FENCE +29DA ; Math # Ps LEFT DOUBLE WIGGLY FENCE +29DB ; Math # Pe RIGHT DOUBLE WIGGLY FENCE +29DC..29FB ; Math # Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS +29FC ; Math # Ps LEFT-POINTING CURVED ANGLE BRACKET +29FD ; Math # Pe RIGHT-POINTING CURVED ANGLE BRACKET +29FE..2AFF ; Math # Sm [258] TINY..N-ARY WHITE VERTICAL BAR +2B30..2B44 ; Math # Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET +2B47..2B4C ; Math # Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +FB29 ; Math # Sm HEBREW LETTER ALTERNATIVE PLUS SIGN +FE61 ; Math # Po SMALL ASTERISK +FE62 ; Math # Sm SMALL PLUS SIGN +FE63 ; Math # Pd SMALL HYPHEN-MINUS +FE64..FE66 ; Math # Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN +FE68 ; Math # Po SMALL REVERSE SOLIDUS +FF0B ; Math # Sm FULLWIDTH PLUS SIGN +FF1C..FF1E ; Math # Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN +FF3C ; Math # Po FULLWIDTH REVERSE SOLIDUS +FF3E ; Math # Sk FULLWIDTH CIRCUMFLEX ACCENT +FF5C ; Math # Sm FULLWIDTH VERTICAL LINE +FF5E ; Math # Sm FULLWIDTH TILDE +FFE2 ; Math # Sm FULLWIDTH NOT SIGN +FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW +1D400..1D454 ; Math # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G +1D456..1D49C ; Math # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2 ; Math # L& MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6 ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC ; Math # L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B9 ; Math # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Math # L& MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Math # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D505 ; Math # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A ; Math # L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514 ; Math # L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C ; Math # L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D51E..1D539 ; Math # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E ; Math # L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544 ; Math # L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 ; Math # L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550 ; Math # L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552..1D6A5 ; Math # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6A8..1D6C0 ; Math # L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6C1 ; Math # Sm MATHEMATICAL BOLD NABLA +1D6C2..1D6DA ; Math # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DB ; Math # Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6DC..1D6FA ; Math # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FB ; Math # Sm MATHEMATICAL ITALIC NABLA +1D6FC..1D714 ; Math # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D715 ; Math # Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D716..1D734 ; Math # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D735 ; Math # Sm MATHEMATICAL BOLD ITALIC NABLA +1D736..1D74E ; Math # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D74F ; Math # Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D750..1D76E ; Math # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D76F ; Math # Sm MATHEMATICAL SANS-SERIF BOLD NABLA +1D770..1D788 ; Math # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D789 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D78A..1D7A8 ; Math # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7A9 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7AA..1D7C2 ; Math # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C3 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1D7C4..1D7CB ; Math # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1D7CE..1D7FF ; Math # Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + +# Total code points: 2165 + +# ================================================ + +# Derived Property: Alphabetic +# Generated from: Lu+Ll+Lt+Lm+Lo+Nl + Other_Alphabetic + +0041..005A ; Alphabetic # L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +0061..007A ; Alphabetic # L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00AA ; Alphabetic # L& FEMININE ORDINAL INDICATOR +00B5 ; Alphabetic # L& MICRO SIGN +00BA ; Alphabetic # L& MASCULINE ORDINAL INDICATOR +00C0..00D6 ; Alphabetic # L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS +00D8..00F6 ; Alphabetic # L& [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS +00F8..01BA ; Alphabetic # L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL +01BB ; Alphabetic # Lo LATIN LETTER TWO WITH STROKE +01BC..01BF ; Alphabetic # L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN +01C0..01C3 ; Alphabetic # Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK +01C4..0293 ; Alphabetic # L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL +0294 ; Alphabetic # Lo LATIN LETTER GLOTTAL STOP +0295..02AF ; Alphabetic # L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +02B0..02C1 ; Alphabetic # Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP +02C6..02D1 ; Alphabetic # Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON +02E0..02E4 ; Alphabetic # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +02EC ; Alphabetic # Lm MODIFIER LETTER VOICING +02EE ; Alphabetic # Lm MODIFIER LETTER DOUBLE APOSTROPHE +0345 ; Alphabetic # Mn COMBINING GREEK YPOGEGRAMMENI +0370..0373 ; Alphabetic # L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI +0374 ; Alphabetic # Lm GREEK NUMERAL SIGN +0376..0377 ; Alphabetic # L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037A ; Alphabetic # Lm GREEK YPOGEGRAMMENI +037B..037D ; Alphabetic # L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +0386 ; Alphabetic # L& GREEK CAPITAL LETTER ALPHA WITH TONOS +0388..038A ; Alphabetic # L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS +038C ; Alphabetic # L& GREEK CAPITAL LETTER OMICRON WITH TONOS +038E..03A1 ; Alphabetic # L& [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO +03A3..03F5 ; Alphabetic # L& [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL +03F7..0481 ; Alphabetic # L& [139] GREEK CAPITAL LETTER SHO..CYRILLIC SMALL LETTER KOPPA +048A..0527 ; Alphabetic # L& [158] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER SHHA WITH DESCENDER +0531..0556 ; Alphabetic # L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH +0559 ; Alphabetic # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING +0561..0587 ; Alphabetic # L& [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN +05B0..05BD ; Alphabetic # Mn [14] HEBREW POINT SHEVA..HEBREW POINT METEG +05BF ; Alphabetic # Mn HEBREW POINT RAFE +05C1..05C2 ; Alphabetic # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C4..05C5 ; Alphabetic # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT +05C7 ; Alphabetic # Mn HEBREW POINT QAMATS QATAN +05D0..05EA ; Alphabetic # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV +05F0..05F2 ; Alphabetic # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD +0610..061A ; Alphabetic # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA +0620..063F ; Alphabetic # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE +0640 ; Alphabetic # Lm ARABIC TATWEEL +0641..064A ; Alphabetic # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH +064B..0657 ; Alphabetic # Mn [13] ARABIC FATHATAN..ARABIC INVERTED DAMMA +0659..065F ; Alphabetic # Mn [7] ARABIC ZWARAKAY..ARABIC WAVY HAMZA BELOW +066E..066F ; Alphabetic # Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF +0670 ; Alphabetic # Mn ARABIC LETTER SUPERSCRIPT ALEF +0671..06D3 ; Alphabetic # Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +06D5 ; Alphabetic # Lo ARABIC LETTER AE +06D6..06DC ; Alphabetic # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN +06E1..06E4 ; Alphabetic # Mn [4] ARABIC SMALL HIGH DOTLESS HEAD OF KHAH..ARABIC SMALL HIGH MADDA +06E5..06E6 ; Alphabetic # Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH +06E7..06E8 ; Alphabetic # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +06ED ; Alphabetic # Mn ARABIC SMALL LOW MEEM +06EE..06EF ; Alphabetic # Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V +06FA..06FC ; Alphabetic # Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW +06FF ; Alphabetic # Lo ARABIC LETTER HEH WITH INVERTED V +0710 ; Alphabetic # Lo SYRIAC LETTER ALAPH +0711 ; Alphabetic # Mn SYRIAC LETTER SUPERSCRIPT ALAPH +0712..072F ; Alphabetic # Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH +0730..073F ; Alphabetic # Mn [16] SYRIAC PTHAHA ABOVE..SYRIAC RWAHA +074D..07A5 ; Alphabetic # Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU +07A6..07B0 ; Alphabetic # Mn [11] THAANA ABAFILI..THAANA SUKUN +07B1 ; Alphabetic # Lo THAANA LETTER NAA +07CA..07EA ; Alphabetic # Lo [33] NKO LETTER A..NKO LETTER JONA RA +07F4..07F5 ; Alphabetic # Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE +07FA ; Alphabetic # Lm NKO LAJANYALAN +0800..0815 ; Alphabetic # Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF +0816..0817 ; Alphabetic # Mn [2] SAMARITAN MARK IN..SAMARITAN MARK IN-ALAF +081A ; Alphabetic # Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT +081B..0823 ; Alphabetic # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A +0824 ; Alphabetic # Lm SAMARITAN MODIFIER LETTER SHORT A +0825..0827 ; Alphabetic # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U +0828 ; Alphabetic # Lm SAMARITAN MODIFIER LETTER I +0829..082C ; Alphabetic # Mn [4] SAMARITAN VOWEL SIGN LONG I..SAMARITAN VOWEL SIGN SUKUN +0840..0858 ; Alphabetic # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN +0900..0902 ; Alphabetic # Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA +0903 ; Alphabetic # Mc DEVANAGARI SIGN VISARGA +0904..0939 ; Alphabetic # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA +093A ; Alphabetic # Mn DEVANAGARI VOWEL SIGN OE +093B ; Alphabetic # Mc DEVANAGARI VOWEL SIGN OOE +093D ; Alphabetic # Lo DEVANAGARI SIGN AVAGRAHA +093E..0940 ; Alphabetic # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II +0941..0948 ; Alphabetic # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI +0949..094C ; Alphabetic # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU +094E..094F ; Alphabetic # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW +0950 ; Alphabetic # Lo DEVANAGARI OM +0955..0957 ; Alphabetic # Mn [3] DEVANAGARI VOWEL SIGN CANDRA LONG E..DEVANAGARI VOWEL SIGN UUE +0958..0961 ; Alphabetic # Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL +0962..0963 ; Alphabetic # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0971 ; Alphabetic # Lm DEVANAGARI SIGN HIGH SPACING DOT +0972..0977 ; Alphabetic # Lo [6] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER UUE +0979..097F ; Alphabetic # Lo [7] DEVANAGARI LETTER ZHA..DEVANAGARI LETTER BBA +0981 ; Alphabetic # Mn BENGALI SIGN CANDRABINDU +0982..0983 ; Alphabetic # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA +0985..098C ; Alphabetic # Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L +098F..0990 ; Alphabetic # Lo [2] BENGALI LETTER E..BENGALI LETTER AI +0993..09A8 ; Alphabetic # Lo [22] BENGALI LETTER O..BENGALI LETTER NA +09AA..09B0 ; Alphabetic # Lo [7] BENGALI LETTER PA..BENGALI LETTER RA +09B2 ; Alphabetic # Lo BENGALI LETTER LA +09B6..09B9 ; Alphabetic # Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA +09BD ; Alphabetic # Lo BENGALI SIGN AVAGRAHA +09BE..09C0 ; Alphabetic # Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II +09C1..09C4 ; Alphabetic # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR +09C7..09C8 ; Alphabetic # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CC ; Alphabetic # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU +09CE ; Alphabetic # Lo BENGALI LETTER KHANDA TA +09D7 ; Alphabetic # Mc BENGALI AU LENGTH MARK +09DC..09DD ; Alphabetic # Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA +09DF..09E1 ; Alphabetic # Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL +09E2..09E3 ; Alphabetic # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL +09F0..09F1 ; Alphabetic # Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL +0A01..0A02 ; Alphabetic # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI +0A03 ; Alphabetic # Mc GURMUKHI SIGN VISARGA +0A05..0A0A ; Alphabetic # Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU +0A0F..0A10 ; Alphabetic # Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI +0A13..0A28 ; Alphabetic # Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA +0A2A..0A30 ; Alphabetic # Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA +0A32..0A33 ; Alphabetic # Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA +0A35..0A36 ; Alphabetic # Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA +0A38..0A39 ; Alphabetic # Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA +0A3E..0A40 ; Alphabetic # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II +0A41..0A42 ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4C ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN OO..GURMUKHI VOWEL SIGN AU +0A51 ; Alphabetic # Mn GURMUKHI SIGN UDAAT +0A59..0A5C ; Alphabetic # Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA +0A5E ; Alphabetic # Lo GURMUKHI LETTER FA +0A70..0A71 ; Alphabetic # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK +0A72..0A74 ; Alphabetic # Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR +0A75 ; Alphabetic # Mn GURMUKHI SIGN YAKASH +0A81..0A82 ; Alphabetic # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA +0A83 ; Alphabetic # Mc GUJARATI SIGN VISARGA +0A85..0A8D ; Alphabetic # Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E +0A8F..0A91 ; Alphabetic # Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O +0A93..0AA8 ; Alphabetic # Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA +0AAA..0AB0 ; Alphabetic # Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA +0AB2..0AB3 ; Alphabetic # Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA +0AB5..0AB9 ; Alphabetic # Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA +0ABD ; Alphabetic # Lo GUJARATI SIGN AVAGRAHA +0ABE..0AC0 ; Alphabetic # Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II +0AC1..0AC5 ; Alphabetic # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC8 ; Alphabetic # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI +0AC9 ; Alphabetic # Mc GUJARATI VOWEL SIGN CANDRA O +0ACB..0ACC ; Alphabetic # Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU +0AD0 ; Alphabetic # Lo GUJARATI OM +0AE0..0AE1 ; Alphabetic # Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL +0AE2..0AE3 ; Alphabetic # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL +0B01 ; Alphabetic # Mn ORIYA SIGN CANDRABINDU +0B02..0B03 ; Alphabetic # Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA +0B05..0B0C ; Alphabetic # Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L +0B0F..0B10 ; Alphabetic # Lo [2] ORIYA LETTER E..ORIYA LETTER AI +0B13..0B28 ; Alphabetic # Lo [22] ORIYA LETTER O..ORIYA LETTER NA +0B2A..0B30 ; Alphabetic # Lo [7] ORIYA LETTER PA..ORIYA LETTER RA +0B32..0B33 ; Alphabetic # Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA +0B35..0B39 ; Alphabetic # Lo [5] ORIYA LETTER VA..ORIYA LETTER HA +0B3D ; Alphabetic # Lo ORIYA SIGN AVAGRAHA +0B3E ; Alphabetic # Mc ORIYA VOWEL SIGN AA +0B3F ; Alphabetic # Mn ORIYA VOWEL SIGN I +0B40 ; Alphabetic # Mc ORIYA VOWEL SIGN II +0B41..0B44 ; Alphabetic # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR +0B47..0B48 ; Alphabetic # Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI +0B4B..0B4C ; Alphabetic # Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU +0B56 ; Alphabetic # Mn ORIYA AI LENGTH MARK +0B57 ; Alphabetic # Mc ORIYA AU LENGTH MARK +0B5C..0B5D ; Alphabetic # Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA +0B5F..0B61 ; Alphabetic # Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL +0B62..0B63 ; Alphabetic # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL +0B71 ; Alphabetic # Lo ORIYA LETTER WA +0B82 ; Alphabetic # Mn TAMIL SIGN ANUSVARA +0B83 ; Alphabetic # Lo TAMIL SIGN VISARGA +0B85..0B8A ; Alphabetic # Lo [6] TAMIL LETTER A..TAMIL LETTER UU +0B8E..0B90 ; Alphabetic # Lo [3] TAMIL LETTER E..TAMIL LETTER AI +0B92..0B95 ; Alphabetic # Lo [4] TAMIL LETTER O..TAMIL LETTER KA +0B99..0B9A ; Alphabetic # Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA +0B9C ; Alphabetic # Lo TAMIL LETTER JA +0B9E..0B9F ; Alphabetic # Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA +0BA3..0BA4 ; Alphabetic # Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA +0BA8..0BAA ; Alphabetic # Lo [3] TAMIL LETTER NA..TAMIL LETTER PA +0BAE..0BB9 ; Alphabetic # Lo [12] TAMIL LETTER MA..TAMIL LETTER HA +0BBE..0BBF ; Alphabetic # Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I +0BC0 ; Alphabetic # Mn TAMIL VOWEL SIGN II +0BC1..0BC2 ; Alphabetic # Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU +0BC6..0BC8 ; Alphabetic # Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI +0BCA..0BCC ; Alphabetic # Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU +0BD0 ; Alphabetic # Lo TAMIL OM +0BD7 ; Alphabetic # Mc TAMIL AU LENGTH MARK +0C01..0C03 ; Alphabetic # Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA +0C05..0C0C ; Alphabetic # Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L +0C0E..0C10 ; Alphabetic # Lo [3] TELUGU LETTER E..TELUGU LETTER AI +0C12..0C28 ; Alphabetic # Lo [23] TELUGU LETTER O..TELUGU LETTER NA +0C2A..0C33 ; Alphabetic # Lo [10] TELUGU LETTER PA..TELUGU LETTER LLA +0C35..0C39 ; Alphabetic # Lo [5] TELUGU LETTER VA..TELUGU LETTER HA +0C3D ; Alphabetic # Lo TELUGU SIGN AVAGRAHA +0C3E..0C40 ; Alphabetic # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II +0C41..0C44 ; Alphabetic # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR +0C46..0C48 ; Alphabetic # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4C ; Alphabetic # Mn [3] TELUGU VOWEL SIGN O..TELUGU VOWEL SIGN AU +0C55..0C56 ; Alphabetic # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C58..0C59 ; Alphabetic # Lo [2] TELUGU LETTER TSA..TELUGU LETTER DZA +0C60..0C61 ; Alphabetic # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL +0C62..0C63 ; Alphabetic # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL +0C82..0C83 ; Alphabetic # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA +0C85..0C8C ; Alphabetic # Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L +0C8E..0C90 ; Alphabetic # Lo [3] KANNADA LETTER E..KANNADA LETTER AI +0C92..0CA8 ; Alphabetic # Lo [23] KANNADA LETTER O..KANNADA LETTER NA +0CAA..0CB3 ; Alphabetic # Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA +0CB5..0CB9 ; Alphabetic # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA +0CBD ; Alphabetic # Lo KANNADA SIGN AVAGRAHA +0CBE ; Alphabetic # Mc KANNADA VOWEL SIGN AA +0CBF ; Alphabetic # Mn KANNADA VOWEL SIGN I +0CC0..0CC4 ; Alphabetic # Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR +0CC6 ; Alphabetic # Mn KANNADA VOWEL SIGN E +0CC7..0CC8 ; Alphabetic # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; Alphabetic # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO +0CCC ; Alphabetic # Mn KANNADA VOWEL SIGN AU +0CD5..0CD6 ; Alphabetic # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0CDE ; Alphabetic # Lo KANNADA LETTER FA +0CE0..0CE1 ; Alphabetic # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL +0CE2..0CE3 ; Alphabetic # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL +0CF1..0CF2 ; Alphabetic # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA +0D02..0D03 ; Alphabetic # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA +0D05..0D0C ; Alphabetic # Lo [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L +0D0E..0D10 ; Alphabetic # Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI +0D12..0D3A ; Alphabetic # Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA +0D3D ; Alphabetic # Lo MALAYALAM SIGN AVAGRAHA +0D3E..0D40 ; Alphabetic # Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II +0D41..0D44 ; Alphabetic # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR +0D46..0D48 ; Alphabetic # Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI +0D4A..0D4C ; Alphabetic # Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU +0D4E ; Alphabetic # Lo MALAYALAM LETTER DOT REPH +0D57 ; Alphabetic # Mc MALAYALAM AU LENGTH MARK +0D60..0D61 ; Alphabetic # Lo [2] MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL +0D62..0D63 ; Alphabetic # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL +0D7A..0D7F ; Alphabetic # Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K +0D82..0D83 ; Alphabetic # Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA +0D85..0D96 ; Alphabetic # Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA +0D9A..0DB1 ; Alphabetic # Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA +0DB3..0DBB ; Alphabetic # Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA +0DBD ; Alphabetic # Lo SINHALA LETTER DANTAJA LAYANNA +0DC0..0DC6 ; Alphabetic # Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA +0DCF..0DD1 ; Alphabetic # Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA +0DD2..0DD4 ; Alphabetic # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; Alphabetic # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA +0DD8..0DDF ; Alphabetic # Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA +0DF2..0DF3 ; Alphabetic # Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA +0E01..0E30 ; Alphabetic # Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A +0E31 ; Alphabetic # Mn THAI CHARACTER MAI HAN-AKAT +0E32..0E33 ; Alphabetic # Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM +0E34..0E3A ; Alphabetic # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E40..0E45 ; Alphabetic # Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO +0E46 ; Alphabetic # Lm THAI CHARACTER MAIYAMOK +0E4D ; Alphabetic # Mn THAI CHARACTER NIKHAHIT +0E81..0E82 ; Alphabetic # Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG +0E84 ; Alphabetic # Lo LAO LETTER KHO TAM +0E87..0E88 ; Alphabetic # Lo [2] LAO LETTER NGO..LAO LETTER CO +0E8A ; Alphabetic # Lo LAO LETTER SO TAM +0E8D ; Alphabetic # Lo LAO LETTER NYO +0E94..0E97 ; Alphabetic # Lo [4] LAO LETTER DO..LAO LETTER THO TAM +0E99..0E9F ; Alphabetic # Lo [7] LAO LETTER NO..LAO LETTER FO SUNG +0EA1..0EA3 ; Alphabetic # Lo [3] LAO LETTER MO..LAO LETTER LO LING +0EA5 ; Alphabetic # Lo LAO LETTER LO LOOT +0EA7 ; Alphabetic # Lo LAO LETTER WO +0EAA..0EAB ; Alphabetic # Lo [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG +0EAD..0EB0 ; Alphabetic # Lo [4] LAO LETTER O..LAO VOWEL SIGN A +0EB1 ; Alphabetic # Mn LAO VOWEL SIGN MAI KAN +0EB2..0EB3 ; Alphabetic # Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM +0EB4..0EB9 ; Alphabetic # Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU +0EBB..0EBC ; Alphabetic # Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO +0EBD ; Alphabetic # Lo LAO SEMIVOWEL SIGN NYO +0EC0..0EC4 ; Alphabetic # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI +0EC6 ; Alphabetic # Lm LAO KO LA +0ECD ; Alphabetic # Mn LAO NIGGAHITA +0EDC..0EDD ; Alphabetic # Lo [2] LAO HO NO..LAO HO MO +0F00 ; Alphabetic # Lo TIBETAN SYLLABLE OM +0F40..0F47 ; Alphabetic # Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA +0F49..0F6C ; Alphabetic # Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA +0F71..0F7E ; Alphabetic # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO +0F7F ; Alphabetic # Mc TIBETAN SIGN RNAM BCAD +0F80..0F81 ; Alphabetic # Mn [2] TIBETAN VOWEL SIGN REVERSED I..TIBETAN VOWEL SIGN REVERSED II +0F88..0F8C ; Alphabetic # Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN +0F8D..0F97 ; Alphabetic # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA +0F99..0FBC ; Alphabetic # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA +1000..102A ; Alphabetic # Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU +102B..102C ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA +102D..1030 ; Alphabetic # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU +1031 ; Alphabetic # Mc MYANMAR VOWEL SIGN E +1032..1036 ; Alphabetic # Mn [5] MYANMAR VOWEL SIGN AI..MYANMAR SIGN ANUSVARA +1038 ; Alphabetic # Mc MYANMAR SIGN VISARGA +103B..103C ; Alphabetic # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA +103D..103E ; Alphabetic # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA +103F ; Alphabetic # Lo MYANMAR LETTER GREAT SA +1050..1055 ; Alphabetic # Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL +1056..1057 ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR +1058..1059 ; Alphabetic # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL +105A..105D ; Alphabetic # Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE +105E..1060 ; Alphabetic # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA +1061 ; Alphabetic # Lo MYANMAR LETTER SGAW KAREN SHA +1062 ; Alphabetic # Mc MYANMAR VOWEL SIGN SGAW KAREN EU +1065..1066 ; Alphabetic # Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA +1067..1068 ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR VOWEL SIGN WESTERN PWO KAREN UE +106E..1070 ; Alphabetic # Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA +1071..1074 ; Alphabetic # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE +1075..1081 ; Alphabetic # Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA +1082 ; Alphabetic # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA +1083..1084 ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E +1085..1086 ; Alphabetic # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y +108E ; Alphabetic # Lo MYANMAR LETTER RUMAI PALAUNG FA +109C ; Alphabetic # Mc MYANMAR VOWEL SIGN AITON A +109D ; Alphabetic # Mn MYANMAR VOWEL SIGN AITON AI +10A0..10C5 ; Alphabetic # L& [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE +10D0..10FA ; Alphabetic # Lo [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN +10FC ; Alphabetic # Lm MODIFIER LETTER GEORGIAN NAR +1100..1248 ; Alphabetic # Lo [329] HANGUL CHOSEONG KIYEOK..ETHIOPIC SYLLABLE QWA +124A..124D ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE +1250..1256 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO +1258 ; Alphabetic # Lo ETHIOPIC SYLLABLE QHWA +125A..125D ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE +1260..1288 ; Alphabetic # Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA +128A..128D ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE +1290..12B0 ; Alphabetic # Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA +12B2..12B5 ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE +12B8..12BE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO +12C0 ; Alphabetic # Lo ETHIOPIC SYLLABLE KXWA +12C2..12C5 ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE +12C8..12D6 ; Alphabetic # Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O +12D8..1310 ; Alphabetic # Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA +1312..1315 ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE +1318..135A ; Alphabetic # Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA +135F ; Alphabetic # Mn ETHIOPIC COMBINING GEMINATION MARK +1380..138F ; Alphabetic # Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE +13A0..13F4 ; Alphabetic # Lo [85] CHEROKEE LETTER A..CHEROKEE LETTER YV +1401..166C ; Alphabetic # Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA +166F..167F ; Alphabetic # Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W +1681..169A ; Alphabetic # Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH +16A0..16EA ; Alphabetic # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X +16EE..16F0 ; Alphabetic # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL +1700..170C ; Alphabetic # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA +170E..1711 ; Alphabetic # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1712..1713 ; Alphabetic # Mn [2] TAGALOG VOWEL SIGN I..TAGALOG VOWEL SIGN U +1720..1731 ; Alphabetic # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA +1732..1733 ; Alphabetic # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1740..1751 ; Alphabetic # Lo [18] BUHID LETTER A..BUHID LETTER HA +1752..1753 ; Alphabetic # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U +1760..176C ; Alphabetic # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA +176E..1770 ; Alphabetic # Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA +1772..1773 ; Alphabetic # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U +1780..17B3 ; Alphabetic # Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU +17B6 ; Alphabetic # Mc KHMER VOWEL SIGN AA +17B7..17BD ; Alphabetic # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA +17BE..17C5 ; Alphabetic # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU +17C6 ; Alphabetic # Mn KHMER SIGN NIKAHIT +17C7..17C8 ; Alphabetic # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU +17D7 ; Alphabetic # Lm KHMER SIGN LEK TOO +17DC ; Alphabetic # Lo KHMER SIGN AVAKRAHASANYA +1820..1842 ; Alphabetic # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI +1843 ; Alphabetic # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN +1844..1877 ; Alphabetic # Lo [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA +1880..18A8 ; Alphabetic # Lo [41] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER MANCHU ALI GALI BHA +18A9 ; Alphabetic # Mn MONGOLIAN LETTER ALI GALI DAGALGA +18AA ; Alphabetic # Lo MONGOLIAN LETTER MANCHU ALI GALI LHA +18B0..18F5 ; Alphabetic # Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S +1900..191C ; Alphabetic # Lo [29] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER HA +1920..1922 ; Alphabetic # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U +1923..1926 ; Alphabetic # Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU +1927..1928 ; Alphabetic # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O +1929..192B ; Alphabetic # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA +1930..1931 ; Alphabetic # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA +1932 ; Alphabetic # Mn LIMBU SMALL LETTER ANUSVARA +1933..1938 ; Alphabetic # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA +1950..196D ; Alphabetic # Lo [30] TAI LE LETTER KA..TAI LE LETTER AI +1970..1974 ; Alphabetic # Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 +1980..19AB ; Alphabetic # Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA +19B0..19C0 ; Alphabetic # Mc [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY +19C1..19C7 ; Alphabetic # Lo [7] NEW TAI LUE LETTER FINAL V..NEW TAI LUE LETTER FINAL B +19C8..19C9 ; Alphabetic # Mc [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2 +1A00..1A16 ; Alphabetic # Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA +1A17..1A18 ; Alphabetic # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U +1A19..1A1B ; Alphabetic # Mc [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE +1A20..1A54 ; Alphabetic # Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA +1A55 ; Alphabetic # Mc TAI THAM CONSONANT SIGN MEDIAL RA +1A56 ; Alphabetic # Mn TAI THAM CONSONANT SIGN MEDIAL LA +1A57 ; Alphabetic # Mc TAI THAM CONSONANT SIGN LA TANG LAI +1A58..1A5E ; Alphabetic # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA +1A61 ; Alphabetic # Mc TAI THAM VOWEL SIGN A +1A62 ; Alphabetic # Mn TAI THAM VOWEL SIGN MAI SAT +1A63..1A64 ; Alphabetic # Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA +1A65..1A6C ; Alphabetic # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW +1A6D..1A72 ; Alphabetic # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI +1A73..1A74 ; Alphabetic # Mn [2] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN MAI KANG +1AA7 ; Alphabetic # Lm TAI THAM SIGN MAI YAMOK +1B00..1B03 ; Alphabetic # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG +1B04 ; Alphabetic # Mc BALINESE SIGN BISAH +1B05..1B33 ; Alphabetic # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA +1B35 ; Alphabetic # Mc BALINESE VOWEL SIGN TEDUNG +1B36..1B3A ; Alphabetic # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3B ; Alphabetic # Mc BALINESE VOWEL SIGN RA REPA TEDUNG +1B3C ; Alphabetic # Mn BALINESE VOWEL SIGN LA LENGA +1B3D..1B41 ; Alphabetic # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG +1B42 ; Alphabetic # Mn BALINESE VOWEL SIGN PEPET +1B43 ; Alphabetic # Mc BALINESE VOWEL SIGN PEPET TEDUNG +1B45..1B4B ; Alphabetic # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B80..1B81 ; Alphabetic # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR +1B82 ; Alphabetic # Mc SUNDANESE SIGN PANGWISAD +1B83..1BA0 ; Alphabetic # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA +1BA1 ; Alphabetic # Mc SUNDANESE CONSONANT SIGN PAMINGKAL +1BA2..1BA5 ; Alphabetic # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU +1BA6..1BA7 ; Alphabetic # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG +1BA8..1BA9 ; Alphabetic # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAE..1BAF ; Alphabetic # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA +1BC0..1BE5 ; Alphabetic # Lo [38] BATAK LETTER A..BATAK LETTER U +1BE7 ; Alphabetic # Mc BATAK VOWEL SIGN E +1BE8..1BE9 ; Alphabetic # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE +1BEA..1BEC ; Alphabetic # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O +1BED ; Alphabetic # Mn BATAK VOWEL SIGN KARO O +1BEE ; Alphabetic # Mc BATAK VOWEL SIGN U +1BEF..1BF1 ; Alphabetic # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1C00..1C23 ; Alphabetic # Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A +1C24..1C2B ; Alphabetic # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU +1C2C..1C33 ; Alphabetic # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T +1C34..1C35 ; Alphabetic # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG +1C4D..1C4F ; Alphabetic # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA +1C5A..1C77 ; Alphabetic # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH +1C78..1C7D ; Alphabetic # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD +1CE9..1CEC ; Alphabetic # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL +1CEE..1CF1 ; Alphabetic # Lo [4] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ANUSVARA UBHAYATO MUKHA +1CF2 ; Alphabetic # Mc VEDIC SIGN ARDHAVISARGA +1D00..1D2B ; Alphabetic # L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL +1D2C..1D61 ; Alphabetic # Lm [54] MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL CHI +1D62..1D77 ; Alphabetic # L& [22] LATIN SUBSCRIPT SMALL LETTER I..LATIN SMALL LETTER TURNED G +1D78 ; Alphabetic # Lm MODIFIER LETTER CYRILLIC EN +1D79..1D9A ; Alphabetic # L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK +1D9B..1DBF ; Alphabetic # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA +1E00..1F15 ; Alphabetic # L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F18..1F1D ; Alphabetic # L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F20..1F45 ; Alphabetic # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F48..1F4D ; Alphabetic # L& [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50..1F57 ; Alphabetic # L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F59 ; Alphabetic # L& GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B ; Alphabetic # L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D ; Alphabetic # L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F..1F7D ; Alphabetic # L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA +1F80..1FB4 ; Alphabetic # L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6..1FBC ; Alphabetic # L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBE ; Alphabetic # L& GREEK PROSGEGRAMMENI +1FC2..1FC4 ; Alphabetic # L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6..1FCC ; Alphabetic # L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FD0..1FD3 ; Alphabetic # L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6..1FDB ; Alphabetic # L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA +1FE0..1FEC ; Alphabetic # L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA +1FF2..1FF4 ; Alphabetic # L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6..1FFC ; Alphabetic # L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +2071 ; Alphabetic # Lm SUPERSCRIPT LATIN SMALL LETTER I +207F ; Alphabetic # Lm SUPERSCRIPT LATIN SMALL LETTER N +2090..209C ; Alphabetic # Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T +2102 ; Alphabetic # L& DOUBLE-STRUCK CAPITAL C +2107 ; Alphabetic # L& EULER CONSTANT +210A..2113 ; Alphabetic # L& [10] SCRIPT SMALL G..SCRIPT SMALL L +2115 ; Alphabetic # L& DOUBLE-STRUCK CAPITAL N +2119..211D ; Alphabetic # L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +2124 ; Alphabetic # L& DOUBLE-STRUCK CAPITAL Z +2126 ; Alphabetic # L& OHM SIGN +2128 ; Alphabetic # L& BLACK-LETTER CAPITAL Z +212A..212D ; Alphabetic # L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C +212F..2134 ; Alphabetic # L& [6] SCRIPT SMALL E..SCRIPT SMALL O +2135..2138 ; Alphabetic # Lo [4] ALEF SYMBOL..DALET SYMBOL +2139 ; Alphabetic # L& INFORMATION SOURCE +213C..213F ; Alphabetic # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI +2145..2149 ; Alphabetic # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J +214E ; Alphabetic # L& TURNED SMALL F +2160..2182 ; Alphabetic # Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND +2183..2184 ; Alphabetic # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C +2185..2188 ; Alphabetic # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND +24B6..24E9 ; Alphabetic # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z +2C00..2C2E ; Alphabetic # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C30..2C5E ; Alphabetic # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C60..2C7C ; Alphabetic # L& [29] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN SUBSCRIPT SMALL LETTER J +2C7D ; Alphabetic # Lm MODIFIER LETTER CAPITAL V +2C7E..2CE4 ; Alphabetic # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI +2CEB..2CEE ; Alphabetic # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +2D00..2D25 ; Alphabetic # L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE +2D30..2D65 ; Alphabetic # Lo [54] TIFINAGH LETTER YA..TIFINAGH LETTER YAZZ +2D6F ; Alphabetic # Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK +2D80..2D96 ; Alphabetic # Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE +2DA0..2DA6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO +2DA8..2DAE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO +2DB0..2DB6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO +2DB8..2DBE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO +2DC0..2DC6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO +2DC8..2DCE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO +2DD0..2DD6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO +2DD8..2DDE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO +2DE0..2DFF ; Alphabetic # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS +2E2F ; Alphabetic # Lm VERTICAL TILDE +3005 ; Alphabetic # Lm IDEOGRAPHIC ITERATION MARK +3006 ; Alphabetic # Lo IDEOGRAPHIC CLOSING MARK +3007 ; Alphabetic # Nl IDEOGRAPHIC NUMBER ZERO +3021..3029 ; Alphabetic # Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE +3031..3035 ; Alphabetic # Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF +3038..303A ; Alphabetic # Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY +303B ; Alphabetic # Lm VERTICAL IDEOGRAPHIC ITERATION MARK +303C ; Alphabetic # Lo MASU MARK +3041..3096 ; Alphabetic # Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE +309D..309E ; Alphabetic # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK +309F ; Alphabetic # Lo HIRAGANA DIGRAPH YORI +30A1..30FA ; Alphabetic # Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO +30FC..30FE ; Alphabetic # Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK +30FF ; Alphabetic # Lo KATAKANA DIGRAPH KOTO +3105..312D ; Alphabetic # Lo [41] BOPOMOFO LETTER B..BOPOMOFO LETTER IH +3131..318E ; Alphabetic # Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE +31A0..31BA ; Alphabetic # Lo [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY +31F0..31FF ; Alphabetic # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO +3400..4DB5 ; Alphabetic # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5 +4E00..9FCB ; Alphabetic # Lo [20940] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FCB +A000..A014 ; Alphabetic # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +A015 ; Alphabetic # Lm YI SYLLABLE WU +A016..A48C ; Alphabetic # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR +A4D0..A4F7 ; Alphabetic # Lo [40] LISU LETTER BA..LISU LETTER OE +A4F8..A4FD ; Alphabetic # Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU +A500..A60B ; Alphabetic # Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG +A60C ; Alphabetic # Lm VAI SYLLABLE LENGTHENER +A610..A61F ; Alphabetic # Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG +A62A..A62B ; Alphabetic # Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO +A640..A66D ; Alphabetic # L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +A66E ; Alphabetic # Lo CYRILLIC LETTER MULTIOCULAR O +A67F ; Alphabetic # Lm CYRILLIC PAYEROK +A680..A697 ; Alphabetic # L& [24] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER SHWE +A6A0..A6E5 ; Alphabetic # Lo [70] BAMUM LETTER A..BAMUM LETTER KI +A6E6..A6EF ; Alphabetic # Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM +A717..A71F ; Alphabetic # Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK +A722..A76F ; Alphabetic # L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON +A770 ; Alphabetic # Lm MODIFIER LETTER US +A771..A787 ; Alphabetic # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T +A788 ; Alphabetic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT +A78B..A78E ; Alphabetic # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT +A790..A791 ; Alphabetic # L& [2] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER N WITH DESCENDER +A7A0..A7A9 ; Alphabetic # L& [10] LATIN CAPITAL LETTER G WITH OBLIQUE STROKE..LATIN SMALL LETTER S WITH OBLIQUE STROKE +A7FA ; Alphabetic # L& LATIN LETTER SMALL CAPITAL TURNED M +A7FB..A801 ; Alphabetic # Lo [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I +A803..A805 ; Alphabetic # Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O +A807..A80A ; Alphabetic # Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO +A80C..A822 ; Alphabetic # Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO +A823..A824 ; Alphabetic # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I +A825..A826 ; Alphabetic # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E +A827 ; Alphabetic # Mc SYLOTI NAGRI VOWEL SIGN OO +A840..A873 ; Alphabetic # Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU +A880..A881 ; Alphabetic # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA +A882..A8B3 ; Alphabetic # Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA +A8B4..A8C3 ; Alphabetic # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU +A8F2..A8F7 ; Alphabetic # Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA +A8FB ; Alphabetic # Lo DEVANAGARI HEADSTROKE +A90A..A925 ; Alphabetic # Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO +A926..A92A ; Alphabetic # Mn [5] KAYAH LI VOWEL UE..KAYAH LI VOWEL O +A930..A946 ; Alphabetic # Lo [23] REJANG LETTER KA..REJANG LETTER A +A947..A951 ; Alphabetic # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A952 ; Alphabetic # Mc REJANG CONSONANT SIGN H +A960..A97C ; Alphabetic # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH +A980..A982 ; Alphabetic # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR +A983 ; Alphabetic # Mc JAVANESE SIGN WIGNYAN +A984..A9B2 ; Alphabetic # Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA +A9B4..A9B5 ; Alphabetic # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG +A9B6..A9B9 ; Alphabetic # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT +A9BA..A9BB ; Alphabetic # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE +A9BC ; Alphabetic # Mn JAVANESE VOWEL SIGN PEPET +A9BD..A9BF ; Alphabetic # Mc [3] JAVANESE CONSONANT SIGN KERET..JAVANESE CONSONANT SIGN CAKRA +A9CF ; Alphabetic # Lm JAVANESE PANGRANGKEP +AA00..AA28 ; Alphabetic # Lo [41] CHAM LETTER A..CHAM LETTER HA +AA29..AA2E ; Alphabetic # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE +AA2F..AA30 ; Alphabetic # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI +AA31..AA32 ; Alphabetic # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE +AA33..AA34 ; Alphabetic # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA +AA35..AA36 ; Alphabetic # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA +AA40..AA42 ; Alphabetic # Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG +AA43 ; Alphabetic # Mn CHAM CONSONANT SIGN FINAL NG +AA44..AA4B ; Alphabetic # Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS +AA4C ; Alphabetic # Mn CHAM CONSONANT SIGN FINAL M +AA4D ; Alphabetic # Mc CHAM CONSONANT SIGN FINAL H +AA60..AA6F ; Alphabetic # Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA +AA70 ; Alphabetic # Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION +AA71..AA76 ; Alphabetic # Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM +AA7A ; Alphabetic # Lo MYANMAR LETTER AITON RA +AA80..AAAF ; Alphabetic # Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O +AAB0 ; Alphabetic # Mn TAI VIET MAI KANG +AAB1 ; Alphabetic # Lo TAI VIET VOWEL AA +AAB2..AAB4 ; Alphabetic # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U +AAB5..AAB6 ; Alphabetic # Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O +AAB7..AAB8 ; Alphabetic # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA +AAB9..AABD ; Alphabetic # Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN +AABE ; Alphabetic # Mn TAI VIET VOWEL AM +AAC0 ; Alphabetic # Lo TAI VIET TONE MAI NUENG +AAC2 ; Alphabetic # Lo TAI VIET TONE MAI SONG +AADB..AADC ; Alphabetic # Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG +AADD ; Alphabetic # Lm TAI VIET SYMBOL SAM +AB01..AB06 ; Alphabetic # Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO +AB09..AB0E ; Alphabetic # Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO +AB11..AB16 ; Alphabetic # Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO +AB20..AB26 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO +AB28..AB2E ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO +ABC0..ABE2 ; Alphabetic # Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM +ABE3..ABE4 ; Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP +ABE5 ; Alphabetic # Mn MEETEI MAYEK VOWEL SIGN ANAP +ABE6..ABE7 ; Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP +ABE8 ; Alphabetic # Mn MEETEI MAYEK VOWEL SIGN UNAP +ABE9..ABEA ; Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG +AC00..D7A3 ; Alphabetic # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH +D7B0..D7C6 ; Alphabetic # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E +D7CB..D7FB ; Alphabetic # Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH +F900..FA2D ; Alphabetic # Lo [302] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA2D +FA30..FA6D ; Alphabetic # Lo [62] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6D +FA70..FAD9 ; Alphabetic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +FB00..FB06 ; Alphabetic # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST +FB13..FB17 ; Alphabetic # L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH +FB1D ; Alphabetic # Lo HEBREW LETTER YOD WITH HIRIQ +FB1E ; Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA +FB1F..FB28 ; Alphabetic # Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV +FB2A..FB36 ; Alphabetic # Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH +FB38..FB3C ; Alphabetic # Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH +FB3E ; Alphabetic # Lo HEBREW LETTER MEM WITH DAGESH +FB40..FB41 ; Alphabetic # Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH +FB43..FB44 ; Alphabetic # Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH +FB46..FBB1 ; Alphabetic # Lo [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM +FBD3..FD3D ; Alphabetic # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM +FD50..FD8F ; Alphabetic # Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM +FD92..FDC7 ; Alphabetic # Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM +FDF0..FDFB ; Alphabetic # Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU +FE70..FE74 ; Alphabetic # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM +FE76..FEFC ; Alphabetic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM +FF21..FF3A ; Alphabetic # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z +FF41..FF5A ; Alphabetic # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z +FF66..FF6F ; Alphabetic # Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU +FF70 ; Alphabetic # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK +FF71..FF9D ; Alphabetic # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N +FF9E..FF9F ; Alphabetic # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +FFA0..FFBE ; Alphabetic # Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH +FFC2..FFC7 ; Alphabetic # Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E +FFCA..FFCF ; Alphabetic # Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE +FFD2..FFD7 ; Alphabetic # Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU +FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I +10000..1000B ; Alphabetic # Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE +1000D..10026 ; Alphabetic # Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO +10028..1003A ; Alphabetic # Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO +1003C..1003D ; Alphabetic # Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE +1003F..1004D ; Alphabetic # Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO +10050..1005D ; Alphabetic # Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 +10080..100FA ; Alphabetic # Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 +10140..10174 ; Alphabetic # Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS +10280..1029C ; Alphabetic # Lo [29] LYCIAN LETTER A..LYCIAN LETTER X +102A0..102D0 ; Alphabetic # Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 +10300..1031E ; Alphabetic # Lo [31] OLD ITALIC LETTER A..OLD ITALIC LETTER UU +10330..10340 ; Alphabetic # Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA +10341 ; Alphabetic # Nl GOTHIC LETTER NINETY +10342..10349 ; Alphabetic # Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL +1034A ; Alphabetic # Nl GOTHIC LETTER NINE HUNDRED +10380..1039D ; Alphabetic # Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU +103A0..103C3 ; Alphabetic # Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA +103C8..103CF ; Alphabetic # Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH +103D1..103D5 ; Alphabetic # Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED +10400..1044F ; Alphabetic # L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW +10450..1049D ; Alphabetic # Lo [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO +10800..10805 ; Alphabetic # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA +10808 ; Alphabetic # Lo CYPRIOT SYLLABLE JO +1080A..10835 ; Alphabetic # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO +10837..10838 ; Alphabetic # Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE +1083C ; Alphabetic # Lo CYPRIOT SYLLABLE ZA +1083F..10855 ; Alphabetic # Lo [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW +10900..10915 ; Alphabetic # Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU +10920..10939 ; Alphabetic # Lo [26] LYDIAN LETTER A..LYDIAN LETTER C +10A00 ; Alphabetic # Lo KHAROSHTHI LETTER A +10A01..10A03 ; Alphabetic # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R +10A05..10A06 ; Alphabetic # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O +10A0C..10A0F ; Alphabetic # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA +10A10..10A13 ; Alphabetic # Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA +10A15..10A17 ; Alphabetic # Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA +10A19..10A33 ; Alphabetic # Lo [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA +10A60..10A7C ; Alphabetic # Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH +10B00..10B35 ; Alphabetic # Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE +10B40..10B55 ; Alphabetic # Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW +10B60..10B72 ; Alphabetic # Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW +10C00..10C48 ; Alphabetic # Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH +11000 ; Alphabetic # Mc BRAHMI SIGN CANDRABINDU +11001 ; Alphabetic # Mn BRAHMI SIGN ANUSVARA +11002 ; Alphabetic # Mc BRAHMI SIGN VISARGA +11003..11037 ; Alphabetic # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA +11038..11045 ; Alphabetic # Mn [14] BRAHMI VOWEL SIGN AA..BRAHMI VOWEL SIGN AU +11082 ; Alphabetic # Mc KAITHI SIGN VISARGA +11083..110AF ; Alphabetic # Lo [45] KAITHI LETTER A..KAITHI LETTER HA +110B0..110B2 ; Alphabetic # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II +110B3..110B6 ; Alphabetic # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI +110B7..110B8 ; Alphabetic # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU +12000..1236E ; Alphabetic # Lo [879] CUNEIFORM SIGN A..CUNEIFORM SIGN ZUM +12400..12462 ; Alphabetic # Nl [99] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER +13000..1342E ; Alphabetic # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 +16800..16A38 ; Alphabetic # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ +1B000..1B001 ; Alphabetic # Lo [2] KATAKANA LETTER ARCHAIC E..HIRAGANA LETTER ARCHAIC YE +1D400..1D454 ; Alphabetic # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G +1D456..1D49C ; Alphabetic # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F ; Alphabetic # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2 ; Alphabetic # L& MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6 ; Alphabetic # L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC ; Alphabetic # L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B9 ; Alphabetic # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Alphabetic # L& MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Alphabetic # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D505 ; Alphabetic # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A ; Alphabetic # L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514 ; Alphabetic # L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C ; Alphabetic # L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D51E..1D539 ; Alphabetic # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E ; Alphabetic # L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544 ; Alphabetic # L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 ; Alphabetic # L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550 ; Alphabetic # L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552..1D6A5 ; Alphabetic # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6A8..1D6C0 ; Alphabetic # L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6C2..1D6DA ; Alphabetic # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DC..1D6FA ; Alphabetic # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FC..1D714 ; Alphabetic # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D716..1D734 ; Alphabetic # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D736..1D74E ; Alphabetic # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D750..1D76E ; Alphabetic # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D770..1D788 ; Alphabetic # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D78A..1D7A8 ; Alphabetic # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7AA..1D7C2 ; Alphabetic # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C4..1D7CB ; Alphabetic # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +20000..2A6D6 ; Alphabetic # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6 +2A700..2B734 ; Alphabetic # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +2B740..2B81D ; Alphabetic # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D +2F800..2FA1D ; Alphabetic # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 101539 + +# ================================================ + +# Derived Property: Lowercase +# Generated from: Ll + Other_Lowercase + +0061..007A ; Lowercase # L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00AA ; Lowercase # L& FEMININE ORDINAL INDICATOR +00B5 ; Lowercase # L& MICRO SIGN +00BA ; Lowercase # L& MASCULINE ORDINAL INDICATOR +00DF..00F6 ; Lowercase # L& [24] LATIN SMALL LETTER SHARP S..LATIN SMALL LETTER O WITH DIAERESIS +00F8..00FF ; Lowercase # L& [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS +0101 ; Lowercase # L& LATIN SMALL LETTER A WITH MACRON +0103 ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE +0105 ; Lowercase # L& LATIN SMALL LETTER A WITH OGONEK +0107 ; Lowercase # L& LATIN SMALL LETTER C WITH ACUTE +0109 ; Lowercase # L& LATIN SMALL LETTER C WITH CIRCUMFLEX +010B ; Lowercase # L& LATIN SMALL LETTER C WITH DOT ABOVE +010D ; Lowercase # L& LATIN SMALL LETTER C WITH CARON +010F ; Lowercase # L& LATIN SMALL LETTER D WITH CARON +0111 ; Lowercase # L& LATIN SMALL LETTER D WITH STROKE +0113 ; Lowercase # L& LATIN SMALL LETTER E WITH MACRON +0115 ; Lowercase # L& LATIN SMALL LETTER E WITH BREVE +0117 ; Lowercase # L& LATIN SMALL LETTER E WITH DOT ABOVE +0119 ; Lowercase # L& LATIN SMALL LETTER E WITH OGONEK +011B ; Lowercase # L& LATIN SMALL LETTER E WITH CARON +011D ; Lowercase # L& LATIN SMALL LETTER G WITH CIRCUMFLEX +011F ; Lowercase # L& LATIN SMALL LETTER G WITH BREVE +0121 ; Lowercase # L& LATIN SMALL LETTER G WITH DOT ABOVE +0123 ; Lowercase # L& LATIN SMALL LETTER G WITH CEDILLA +0125 ; Lowercase # L& LATIN SMALL LETTER H WITH CIRCUMFLEX +0127 ; Lowercase # L& LATIN SMALL LETTER H WITH STROKE +0129 ; Lowercase # L& LATIN SMALL LETTER I WITH TILDE +012B ; Lowercase # L& LATIN SMALL LETTER I WITH MACRON +012D ; Lowercase # L& LATIN SMALL LETTER I WITH BREVE +012F ; Lowercase # L& LATIN SMALL LETTER I WITH OGONEK +0131 ; Lowercase # L& LATIN SMALL LETTER DOTLESS I +0133 ; Lowercase # L& LATIN SMALL LIGATURE IJ +0135 ; Lowercase # L& LATIN SMALL LETTER J WITH CIRCUMFLEX +0137..0138 ; Lowercase # L& [2] LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA +013A ; Lowercase # L& LATIN SMALL LETTER L WITH ACUTE +013C ; Lowercase # L& LATIN SMALL LETTER L WITH CEDILLA +013E ; Lowercase # L& LATIN SMALL LETTER L WITH CARON +0140 ; Lowercase # L& LATIN SMALL LETTER L WITH MIDDLE DOT +0142 ; Lowercase # L& LATIN SMALL LETTER L WITH STROKE +0144 ; Lowercase # L& LATIN SMALL LETTER N WITH ACUTE +0146 ; Lowercase # L& LATIN SMALL LETTER N WITH CEDILLA +0148..0149 ; Lowercase # L& [2] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014B ; Lowercase # L& LATIN SMALL LETTER ENG +014D ; Lowercase # L& LATIN SMALL LETTER O WITH MACRON +014F ; Lowercase # L& LATIN SMALL LETTER O WITH BREVE +0151 ; Lowercase # L& LATIN SMALL LETTER O WITH DOUBLE ACUTE +0153 ; Lowercase # L& LATIN SMALL LIGATURE OE +0155 ; Lowercase # L& LATIN SMALL LETTER R WITH ACUTE +0157 ; Lowercase # L& LATIN SMALL LETTER R WITH CEDILLA +0159 ; Lowercase # L& LATIN SMALL LETTER R WITH CARON +015B ; Lowercase # L& LATIN SMALL LETTER S WITH ACUTE +015D ; Lowercase # L& LATIN SMALL LETTER S WITH CIRCUMFLEX +015F ; Lowercase # L& LATIN SMALL LETTER S WITH CEDILLA +0161 ; Lowercase # L& LATIN SMALL LETTER S WITH CARON +0163 ; Lowercase # L& LATIN SMALL LETTER T WITH CEDILLA +0165 ; Lowercase # L& LATIN SMALL LETTER T WITH CARON +0167 ; Lowercase # L& LATIN SMALL LETTER T WITH STROKE +0169 ; Lowercase # L& LATIN SMALL LETTER U WITH TILDE +016B ; Lowercase # L& LATIN SMALL LETTER U WITH MACRON +016D ; Lowercase # L& LATIN SMALL LETTER U WITH BREVE +016F ; Lowercase # L& LATIN SMALL LETTER U WITH RING ABOVE +0171 ; Lowercase # L& LATIN SMALL LETTER U WITH DOUBLE ACUTE +0173 ; Lowercase # L& LATIN SMALL LETTER U WITH OGONEK +0175 ; Lowercase # L& LATIN SMALL LETTER W WITH CIRCUMFLEX +0177 ; Lowercase # L& LATIN SMALL LETTER Y WITH CIRCUMFLEX +017A ; Lowercase # L& LATIN SMALL LETTER Z WITH ACUTE +017C ; Lowercase # L& LATIN SMALL LETTER Z WITH DOT ABOVE +017E..0180 ; Lowercase # L& [3] LATIN SMALL LETTER Z WITH CARON..LATIN SMALL LETTER B WITH STROKE +0183 ; Lowercase # L& LATIN SMALL LETTER B WITH TOPBAR +0185 ; Lowercase # L& LATIN SMALL LETTER TONE SIX +0188 ; Lowercase # L& LATIN SMALL LETTER C WITH HOOK +018C..018D ; Lowercase # L& [2] LATIN SMALL LETTER D WITH TOPBAR..LATIN SMALL LETTER TURNED DELTA +0192 ; Lowercase # L& LATIN SMALL LETTER F WITH HOOK +0195 ; Lowercase # L& LATIN SMALL LETTER HV +0199..019B ; Lowercase # L& [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE +019E ; Lowercase # L& LATIN SMALL LETTER N WITH LONG RIGHT LEG +01A1 ; Lowercase # L& LATIN SMALL LETTER O WITH HORN +01A3 ; Lowercase # L& LATIN SMALL LETTER OI +01A5 ; Lowercase # L& LATIN SMALL LETTER P WITH HOOK +01A8 ; Lowercase # L& LATIN SMALL LETTER TONE TWO +01AA..01AB ; Lowercase # L& [2] LATIN LETTER REVERSED ESH LOOP..LATIN SMALL LETTER T WITH PALATAL HOOK +01AD ; Lowercase # L& LATIN SMALL LETTER T WITH HOOK +01B0 ; Lowercase # L& LATIN SMALL LETTER U WITH HORN +01B4 ; Lowercase # L& LATIN SMALL LETTER Y WITH HOOK +01B6 ; Lowercase # L& LATIN SMALL LETTER Z WITH STROKE +01B9..01BA ; Lowercase # L& [2] LATIN SMALL LETTER EZH REVERSED..LATIN SMALL LETTER EZH WITH TAIL +01BD..01BF ; Lowercase # L& [3] LATIN SMALL LETTER TONE FIVE..LATIN LETTER WYNN +01C6 ; Lowercase # L& LATIN SMALL LETTER DZ WITH CARON +01C9 ; Lowercase # L& LATIN SMALL LETTER LJ +01CC ; Lowercase # L& LATIN SMALL LETTER NJ +01CE ; Lowercase # L& LATIN SMALL LETTER A WITH CARON +01D0 ; Lowercase # L& LATIN SMALL LETTER I WITH CARON +01D2 ; Lowercase # L& LATIN SMALL LETTER O WITH CARON +01D4 ; Lowercase # L& LATIN SMALL LETTER U WITH CARON +01D6 ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +01D8 ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +01DA ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS AND CARON +01DC..01DD ; Lowercase # L& [2] LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E +01DF ; Lowercase # L& LATIN SMALL LETTER A WITH DIAERESIS AND MACRON +01E1 ; Lowercase # L& LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON +01E3 ; Lowercase # L& LATIN SMALL LETTER AE WITH MACRON +01E5 ; Lowercase # L& LATIN SMALL LETTER G WITH STROKE +01E7 ; Lowercase # L& LATIN SMALL LETTER G WITH CARON +01E9 ; Lowercase # L& LATIN SMALL LETTER K WITH CARON +01EB ; Lowercase # L& LATIN SMALL LETTER O WITH OGONEK +01ED ; Lowercase # L& LATIN SMALL LETTER O WITH OGONEK AND MACRON +01EF..01F0 ; Lowercase # L& [2] LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON +01F3 ; Lowercase # L& LATIN SMALL LETTER DZ +01F5 ; Lowercase # L& LATIN SMALL LETTER G WITH ACUTE +01F9 ; Lowercase # L& LATIN SMALL LETTER N WITH GRAVE +01FB ; Lowercase # L& LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +01FD ; Lowercase # L& LATIN SMALL LETTER AE WITH ACUTE +01FF ; Lowercase # L& LATIN SMALL LETTER O WITH STROKE AND ACUTE +0201 ; Lowercase # L& LATIN SMALL LETTER A WITH DOUBLE GRAVE +0203 ; Lowercase # L& LATIN SMALL LETTER A WITH INVERTED BREVE +0205 ; Lowercase # L& LATIN SMALL LETTER E WITH DOUBLE GRAVE +0207 ; Lowercase # L& LATIN SMALL LETTER E WITH INVERTED BREVE +0209 ; Lowercase # L& LATIN SMALL LETTER I WITH DOUBLE GRAVE +020B ; Lowercase # L& LATIN SMALL LETTER I WITH INVERTED BREVE +020D ; Lowercase # L& LATIN SMALL LETTER O WITH DOUBLE GRAVE +020F ; Lowercase # L& LATIN SMALL LETTER O WITH INVERTED BREVE +0211 ; Lowercase # L& LATIN SMALL LETTER R WITH DOUBLE GRAVE +0213 ; Lowercase # L& LATIN SMALL LETTER R WITH INVERTED BREVE +0215 ; Lowercase # L& LATIN SMALL LETTER U WITH DOUBLE GRAVE +0217 ; Lowercase # L& LATIN SMALL LETTER U WITH INVERTED BREVE +0219 ; Lowercase # L& LATIN SMALL LETTER S WITH COMMA BELOW +021B ; Lowercase # L& LATIN SMALL LETTER T WITH COMMA BELOW +021D ; Lowercase # L& LATIN SMALL LETTER YOGH +021F ; Lowercase # L& LATIN SMALL LETTER H WITH CARON +0221 ; Lowercase # L& LATIN SMALL LETTER D WITH CURL +0223 ; Lowercase # L& LATIN SMALL LETTER OU +0225 ; Lowercase # L& LATIN SMALL LETTER Z WITH HOOK +0227 ; Lowercase # L& LATIN SMALL LETTER A WITH DOT ABOVE +0229 ; Lowercase # L& LATIN SMALL LETTER E WITH CEDILLA +022B ; Lowercase # L& LATIN SMALL LETTER O WITH DIAERESIS AND MACRON +022D ; Lowercase # L& LATIN SMALL LETTER O WITH TILDE AND MACRON +022F ; Lowercase # L& LATIN SMALL LETTER O WITH DOT ABOVE +0231 ; Lowercase # L& LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON +0233..0239 ; Lowercase # L& [7] LATIN SMALL LETTER Y WITH MACRON..LATIN SMALL LETTER QP DIGRAPH +023C ; Lowercase # L& LATIN SMALL LETTER C WITH STROKE +023F..0240 ; Lowercase # L& [2] LATIN SMALL LETTER S WITH SWASH TAIL..LATIN SMALL LETTER Z WITH SWASH TAIL +0242 ; Lowercase # L& LATIN SMALL LETTER GLOTTAL STOP +0247 ; Lowercase # L& LATIN SMALL LETTER E WITH STROKE +0249 ; Lowercase # L& LATIN SMALL LETTER J WITH STROKE +024B ; Lowercase # L& LATIN SMALL LETTER Q WITH HOOK TAIL +024D ; Lowercase # L& LATIN SMALL LETTER R WITH STROKE +024F..0293 ; Lowercase # L& [69] LATIN SMALL LETTER Y WITH STROKE..LATIN SMALL LETTER EZH WITH CURL +0295..02AF ; Lowercase # L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +02B0..02B8 ; Lowercase # Lm [9] MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y +02C0..02C1 ; Lowercase # Lm [2] MODIFIER LETTER GLOTTAL STOP..MODIFIER LETTER REVERSED GLOTTAL STOP +02E0..02E4 ; Lowercase # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +0345 ; Lowercase # Mn COMBINING GREEK YPOGEGRAMMENI +0371 ; Lowercase # L& GREEK SMALL LETTER HETA +0373 ; Lowercase # L& GREEK SMALL LETTER ARCHAIC SAMPI +0377 ; Lowercase # L& GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037A ; Lowercase # Lm GREEK YPOGEGRAMMENI +037B..037D ; Lowercase # L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +0390 ; Lowercase # L& GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +03AC..03CE ; Lowercase # L& [35] GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER OMEGA WITH TONOS +03D0..03D1 ; Lowercase # L& [2] GREEK BETA SYMBOL..GREEK THETA SYMBOL +03D5..03D7 ; Lowercase # L& [3] GREEK PHI SYMBOL..GREEK KAI SYMBOL +03D9 ; Lowercase # L& GREEK SMALL LETTER ARCHAIC KOPPA +03DB ; Lowercase # L& GREEK SMALL LETTER STIGMA +03DD ; Lowercase # L& GREEK SMALL LETTER DIGAMMA +03DF ; Lowercase # L& GREEK SMALL LETTER KOPPA +03E1 ; Lowercase # L& GREEK SMALL LETTER SAMPI +03E3 ; Lowercase # L& COPTIC SMALL LETTER SHEI +03E5 ; Lowercase # L& COPTIC SMALL LETTER FEI +03E7 ; Lowercase # L& COPTIC SMALL LETTER KHEI +03E9 ; Lowercase # L& COPTIC SMALL LETTER HORI +03EB ; Lowercase # L& COPTIC SMALL LETTER GANGIA +03ED ; Lowercase # L& COPTIC SMALL LETTER SHIMA +03EF..03F3 ; Lowercase # L& [5] COPTIC SMALL LETTER DEI..GREEK LETTER YOT +03F5 ; Lowercase # L& GREEK LUNATE EPSILON SYMBOL +03F8 ; Lowercase # L& GREEK SMALL LETTER SHO +03FB..03FC ; Lowercase # L& [2] GREEK SMALL LETTER SAN..GREEK RHO WITH STROKE SYMBOL +0430..045F ; Lowercase # L& [48] CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE +0461 ; Lowercase # L& CYRILLIC SMALL LETTER OMEGA +0463 ; Lowercase # L& CYRILLIC SMALL LETTER YAT +0465 ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED E +0467 ; Lowercase # L& CYRILLIC SMALL LETTER LITTLE YUS +0469 ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS +046B ; Lowercase # L& CYRILLIC SMALL LETTER BIG YUS +046D ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED BIG YUS +046F ; Lowercase # L& CYRILLIC SMALL LETTER KSI +0471 ; Lowercase # L& CYRILLIC SMALL LETTER PSI +0473 ; Lowercase # L& CYRILLIC SMALL LETTER FITA +0475 ; Lowercase # L& CYRILLIC SMALL LETTER IZHITSA +0477 ; Lowercase # L& CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0479 ; Lowercase # L& CYRILLIC SMALL LETTER UK +047B ; Lowercase # L& CYRILLIC SMALL LETTER ROUND OMEGA +047D ; Lowercase # L& CYRILLIC SMALL LETTER OMEGA WITH TITLO +047F ; Lowercase # L& CYRILLIC SMALL LETTER OT +0481 ; Lowercase # L& CYRILLIC SMALL LETTER KOPPA +048B ; Lowercase # L& CYRILLIC SMALL LETTER SHORT I WITH TAIL +048D ; Lowercase # L& CYRILLIC SMALL LETTER SEMISOFT SIGN +048F ; Lowercase # L& CYRILLIC SMALL LETTER ER WITH TICK +0491 ; Lowercase # L& CYRILLIC SMALL LETTER GHE WITH UPTURN +0493 ; Lowercase # L& CYRILLIC SMALL LETTER GHE WITH STROKE +0495 ; Lowercase # L& CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK +0497 ; Lowercase # L& CYRILLIC SMALL LETTER ZHE WITH DESCENDER +0499 ; Lowercase # L& CYRILLIC SMALL LETTER ZE WITH DESCENDER +049B ; Lowercase # L& CYRILLIC SMALL LETTER KA WITH DESCENDER +049D ; Lowercase # L& CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE +049F ; Lowercase # L& CYRILLIC SMALL LETTER KA WITH STROKE +04A1 ; Lowercase # L& CYRILLIC SMALL LETTER BASHKIR KA +04A3 ; Lowercase # L& CYRILLIC SMALL LETTER EN WITH DESCENDER +04A5 ; Lowercase # L& CYRILLIC SMALL LIGATURE EN GHE +04A7 ; Lowercase # L& CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK +04A9 ; Lowercase # L& CYRILLIC SMALL LETTER ABKHASIAN HA +04AB ; Lowercase # L& CYRILLIC SMALL LETTER ES WITH DESCENDER +04AD ; Lowercase # L& CYRILLIC SMALL LETTER TE WITH DESCENDER +04AF ; Lowercase # L& CYRILLIC SMALL LETTER STRAIGHT U +04B1 ; Lowercase # L& CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE +04B3 ; Lowercase # L& CYRILLIC SMALL LETTER HA WITH DESCENDER +04B5 ; Lowercase # L& CYRILLIC SMALL LIGATURE TE TSE +04B7 ; Lowercase # L& CYRILLIC SMALL LETTER CHE WITH DESCENDER +04B9 ; Lowercase # L& CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE +04BB ; Lowercase # L& CYRILLIC SMALL LETTER SHHA +04BD ; Lowercase # L& CYRILLIC SMALL LETTER ABKHASIAN CHE +04BF ; Lowercase # L& CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER +04C2 ; Lowercase # L& CYRILLIC SMALL LETTER ZHE WITH BREVE +04C4 ; Lowercase # L& CYRILLIC SMALL LETTER KA WITH HOOK +04C6 ; Lowercase # L& CYRILLIC SMALL LETTER EL WITH TAIL +04C8 ; Lowercase # L& CYRILLIC SMALL LETTER EN WITH HOOK +04CA ; Lowercase # L& CYRILLIC SMALL LETTER EN WITH TAIL +04CC ; Lowercase # L& CYRILLIC SMALL LETTER KHAKASSIAN CHE +04CE..04CF ; Lowercase # L& [2] CYRILLIC SMALL LETTER EM WITH TAIL..CYRILLIC SMALL LETTER PALOCHKA +04D1 ; Lowercase # L& CYRILLIC SMALL LETTER A WITH BREVE +04D3 ; Lowercase # L& CYRILLIC SMALL LETTER A WITH DIAERESIS +04D5 ; Lowercase # L& CYRILLIC SMALL LIGATURE A IE +04D7 ; Lowercase # L& CYRILLIC SMALL LETTER IE WITH BREVE +04D9 ; Lowercase # L& CYRILLIC SMALL LETTER SCHWA +04DB ; Lowercase # L& CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS +04DD ; Lowercase # L& CYRILLIC SMALL LETTER ZHE WITH DIAERESIS +04DF ; Lowercase # L& CYRILLIC SMALL LETTER ZE WITH DIAERESIS +04E1 ; Lowercase # L& CYRILLIC SMALL LETTER ABKHASIAN DZE +04E3 ; Lowercase # L& CYRILLIC SMALL LETTER I WITH MACRON +04E5 ; Lowercase # L& CYRILLIC SMALL LETTER I WITH DIAERESIS +04E7 ; Lowercase # L& CYRILLIC SMALL LETTER O WITH DIAERESIS +04E9 ; Lowercase # L& CYRILLIC SMALL LETTER BARRED O +04EB ; Lowercase # L& CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS +04ED ; Lowercase # L& CYRILLIC SMALL LETTER E WITH DIAERESIS +04EF ; Lowercase # L& CYRILLIC SMALL LETTER U WITH MACRON +04F1 ; Lowercase # L& CYRILLIC SMALL LETTER U WITH DIAERESIS +04F3 ; Lowercase # L& CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE +04F5 ; Lowercase # L& CYRILLIC SMALL LETTER CHE WITH DIAERESIS +04F7 ; Lowercase # L& CYRILLIC SMALL LETTER GHE WITH DESCENDER +04F9 ; Lowercase # L& CYRILLIC SMALL LETTER YERU WITH DIAERESIS +04FB ; Lowercase # L& CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK +04FD ; Lowercase # L& CYRILLIC SMALL LETTER HA WITH HOOK +04FF ; Lowercase # L& CYRILLIC SMALL LETTER HA WITH STROKE +0501 ; Lowercase # L& CYRILLIC SMALL LETTER KOMI DE +0503 ; Lowercase # L& CYRILLIC SMALL LETTER KOMI DJE +0505 ; Lowercase # L& CYRILLIC SMALL LETTER KOMI ZJE +0507 ; Lowercase # L& CYRILLIC SMALL LETTER KOMI DZJE +0509 ; Lowercase # L& CYRILLIC SMALL LETTER KOMI LJE +050B ; Lowercase # L& CYRILLIC SMALL LETTER KOMI NJE +050D ; Lowercase # L& CYRILLIC SMALL LETTER KOMI SJE +050F ; Lowercase # L& CYRILLIC SMALL LETTER KOMI TJE +0511 ; Lowercase # L& CYRILLIC SMALL LETTER REVERSED ZE +0513 ; Lowercase # L& CYRILLIC SMALL LETTER EL WITH HOOK +0515 ; Lowercase # L& CYRILLIC SMALL LETTER LHA +0517 ; Lowercase # L& CYRILLIC SMALL LETTER RHA +0519 ; Lowercase # L& CYRILLIC SMALL LETTER YAE +051B ; Lowercase # L& CYRILLIC SMALL LETTER QA +051D ; Lowercase # L& CYRILLIC SMALL LETTER WE +051F ; Lowercase # L& CYRILLIC SMALL LETTER ALEUT KA +0521 ; Lowercase # L& CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK +0523 ; Lowercase # L& CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK +0525 ; Lowercase # L& CYRILLIC SMALL LETTER PE WITH DESCENDER +0527 ; Lowercase # L& CYRILLIC SMALL LETTER SHHA WITH DESCENDER +0561..0587 ; Lowercase # L& [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN +1D00..1D2B ; Lowercase # L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL +1D2C..1D61 ; Lowercase # Lm [54] MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL CHI +1D62..1D77 ; Lowercase # L& [22] LATIN SUBSCRIPT SMALL LETTER I..LATIN SMALL LETTER TURNED G +1D78 ; Lowercase # Lm MODIFIER LETTER CYRILLIC EN +1D79..1D9A ; Lowercase # L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK +1D9B..1DBF ; Lowercase # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA +1E01 ; Lowercase # L& LATIN SMALL LETTER A WITH RING BELOW +1E03 ; Lowercase # L& LATIN SMALL LETTER B WITH DOT ABOVE +1E05 ; Lowercase # L& LATIN SMALL LETTER B WITH DOT BELOW +1E07 ; Lowercase # L& LATIN SMALL LETTER B WITH LINE BELOW +1E09 ; Lowercase # L& LATIN SMALL LETTER C WITH CEDILLA AND ACUTE +1E0B ; Lowercase # L& LATIN SMALL LETTER D WITH DOT ABOVE +1E0D ; Lowercase # L& LATIN SMALL LETTER D WITH DOT BELOW +1E0F ; Lowercase # L& LATIN SMALL LETTER D WITH LINE BELOW +1E11 ; Lowercase # L& LATIN SMALL LETTER D WITH CEDILLA +1E13 ; Lowercase # L& LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW +1E15 ; Lowercase # L& LATIN SMALL LETTER E WITH MACRON AND GRAVE +1E17 ; Lowercase # L& LATIN SMALL LETTER E WITH MACRON AND ACUTE +1E19 ; Lowercase # L& LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW +1E1B ; Lowercase # L& LATIN SMALL LETTER E WITH TILDE BELOW +1E1D ; Lowercase # L& LATIN SMALL LETTER E WITH CEDILLA AND BREVE +1E1F ; Lowercase # L& LATIN SMALL LETTER F WITH DOT ABOVE +1E21 ; Lowercase # L& LATIN SMALL LETTER G WITH MACRON +1E23 ; Lowercase # L& LATIN SMALL LETTER H WITH DOT ABOVE +1E25 ; Lowercase # L& LATIN SMALL LETTER H WITH DOT BELOW +1E27 ; Lowercase # L& LATIN SMALL LETTER H WITH DIAERESIS +1E29 ; Lowercase # L& LATIN SMALL LETTER H WITH CEDILLA +1E2B ; Lowercase # L& LATIN SMALL LETTER H WITH BREVE BELOW +1E2D ; Lowercase # L& LATIN SMALL LETTER I WITH TILDE BELOW +1E2F ; Lowercase # L& LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE +1E31 ; Lowercase # L& LATIN SMALL LETTER K WITH ACUTE +1E33 ; Lowercase # L& LATIN SMALL LETTER K WITH DOT BELOW +1E35 ; Lowercase # L& LATIN SMALL LETTER K WITH LINE BELOW +1E37 ; Lowercase # L& LATIN SMALL LETTER L WITH DOT BELOW +1E39 ; Lowercase # L& LATIN SMALL LETTER L WITH DOT BELOW AND MACRON +1E3B ; Lowercase # L& LATIN SMALL LETTER L WITH LINE BELOW +1E3D ; Lowercase # L& LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW +1E3F ; Lowercase # L& LATIN SMALL LETTER M WITH ACUTE +1E41 ; Lowercase # L& LATIN SMALL LETTER M WITH DOT ABOVE +1E43 ; Lowercase # L& LATIN SMALL LETTER M WITH DOT BELOW +1E45 ; Lowercase # L& LATIN SMALL LETTER N WITH DOT ABOVE +1E47 ; Lowercase # L& LATIN SMALL LETTER N WITH DOT BELOW +1E49 ; Lowercase # L& LATIN SMALL LETTER N WITH LINE BELOW +1E4B ; Lowercase # L& LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW +1E4D ; Lowercase # L& LATIN SMALL LETTER O WITH TILDE AND ACUTE +1E4F ; Lowercase # L& LATIN SMALL LETTER O WITH TILDE AND DIAERESIS +1E51 ; Lowercase # L& LATIN SMALL LETTER O WITH MACRON AND GRAVE +1E53 ; Lowercase # L& LATIN SMALL LETTER O WITH MACRON AND ACUTE +1E55 ; Lowercase # L& LATIN SMALL LETTER P WITH ACUTE +1E57 ; Lowercase # L& LATIN SMALL LETTER P WITH DOT ABOVE +1E59 ; Lowercase # L& LATIN SMALL LETTER R WITH DOT ABOVE +1E5B ; Lowercase # L& LATIN SMALL LETTER R WITH DOT BELOW +1E5D ; Lowercase # L& LATIN SMALL LETTER R WITH DOT BELOW AND MACRON +1E5F ; Lowercase # L& LATIN SMALL LETTER R WITH LINE BELOW +1E61 ; Lowercase # L& LATIN SMALL LETTER S WITH DOT ABOVE +1E63 ; Lowercase # L& LATIN SMALL LETTER S WITH DOT BELOW +1E65 ; Lowercase # L& LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE +1E67 ; Lowercase # L& LATIN SMALL LETTER S WITH CARON AND DOT ABOVE +1E69 ; Lowercase # L& LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6B ; Lowercase # L& LATIN SMALL LETTER T WITH DOT ABOVE +1E6D ; Lowercase # L& LATIN SMALL LETTER T WITH DOT BELOW +1E6F ; Lowercase # L& LATIN SMALL LETTER T WITH LINE BELOW +1E71 ; Lowercase # L& LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW +1E73 ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS BELOW +1E75 ; Lowercase # L& LATIN SMALL LETTER U WITH TILDE BELOW +1E77 ; Lowercase # L& LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW +1E79 ; Lowercase # L& LATIN SMALL LETTER U WITH TILDE AND ACUTE +1E7B ; Lowercase # L& LATIN SMALL LETTER U WITH MACRON AND DIAERESIS +1E7D ; Lowercase # L& LATIN SMALL LETTER V WITH TILDE +1E7F ; Lowercase # L& LATIN SMALL LETTER V WITH DOT BELOW +1E81 ; Lowercase # L& LATIN SMALL LETTER W WITH GRAVE +1E83 ; Lowercase # L& LATIN SMALL LETTER W WITH ACUTE +1E85 ; Lowercase # L& LATIN SMALL LETTER W WITH DIAERESIS +1E87 ; Lowercase # L& LATIN SMALL LETTER W WITH DOT ABOVE +1E89 ; Lowercase # L& LATIN SMALL LETTER W WITH DOT BELOW +1E8B ; Lowercase # L& LATIN SMALL LETTER X WITH DOT ABOVE +1E8D ; Lowercase # L& LATIN SMALL LETTER X WITH DIAERESIS +1E8F ; Lowercase # L& LATIN SMALL LETTER Y WITH DOT ABOVE +1E91 ; Lowercase # L& LATIN SMALL LETTER Z WITH CIRCUMFLEX +1E93 ; Lowercase # L& LATIN SMALL LETTER Z WITH DOT BELOW +1E95..1E9D ; Lowercase # L& [9] LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER LONG S WITH HIGH STROKE +1E9F ; Lowercase # L& LATIN SMALL LETTER DELTA +1EA1 ; Lowercase # L& LATIN SMALL LETTER A WITH DOT BELOW +1EA3 ; Lowercase # L& LATIN SMALL LETTER A WITH HOOK ABOVE +1EA5 ; Lowercase # L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA7 ; Lowercase # L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA9 ; Lowercase # L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAB ; Lowercase # L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +1EAD ; Lowercase # L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAF ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE AND ACUTE +1EB1 ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE AND GRAVE +1EB3 ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +1EB5 ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE AND TILDE +1EB7 ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +1EB9 ; Lowercase # L& LATIN SMALL LETTER E WITH DOT BELOW +1EBB ; Lowercase # L& LATIN SMALL LETTER E WITH HOOK ABOVE +1EBD ; Lowercase # L& LATIN SMALL LETTER E WITH TILDE +1EBF ; Lowercase # L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC1 ; Lowercase # L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC3 ; Lowercase # L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC5 ; Lowercase # L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +1EC7 ; Lowercase # L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC9 ; Lowercase # L& LATIN SMALL LETTER I WITH HOOK ABOVE +1ECB ; Lowercase # L& LATIN SMALL LETTER I WITH DOT BELOW +1ECD ; Lowercase # L& LATIN SMALL LETTER O WITH DOT BELOW +1ECF ; Lowercase # L& LATIN SMALL LETTER O WITH HOOK ABOVE +1ED1 ; Lowercase # L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED3 ; Lowercase # L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED5 ; Lowercase # L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED7 ; Lowercase # L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +1ED9 ; Lowercase # L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDB ; Lowercase # L& LATIN SMALL LETTER O WITH HORN AND ACUTE +1EDD ; Lowercase # L& LATIN SMALL LETTER O WITH HORN AND GRAVE +1EDF ; Lowercase # L& LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +1EE1 ; Lowercase # L& LATIN SMALL LETTER O WITH HORN AND TILDE +1EE3 ; Lowercase # L& LATIN SMALL LETTER O WITH HORN AND DOT BELOW +1EE5 ; Lowercase # L& LATIN SMALL LETTER U WITH DOT BELOW +1EE7 ; Lowercase # L& LATIN SMALL LETTER U WITH HOOK ABOVE +1EE9 ; Lowercase # L& LATIN SMALL LETTER U WITH HORN AND ACUTE +1EEB ; Lowercase # L& LATIN SMALL LETTER U WITH HORN AND GRAVE +1EED ; Lowercase # L& LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +1EEF ; Lowercase # L& LATIN SMALL LETTER U WITH HORN AND TILDE +1EF1 ; Lowercase # L& LATIN SMALL LETTER U WITH HORN AND DOT BELOW +1EF3 ; Lowercase # L& LATIN SMALL LETTER Y WITH GRAVE +1EF5 ; Lowercase # L& LATIN SMALL LETTER Y WITH DOT BELOW +1EF7 ; Lowercase # L& LATIN SMALL LETTER Y WITH HOOK ABOVE +1EF9 ; Lowercase # L& LATIN SMALL LETTER Y WITH TILDE +1EFB ; Lowercase # L& LATIN SMALL LETTER MIDDLE-WELSH LL +1EFD ; Lowercase # L& LATIN SMALL LETTER MIDDLE-WELSH V +1EFF..1F07 ; Lowercase # L& [9] LATIN SMALL LETTER Y WITH LOOP..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F10..1F15 ; Lowercase # L& [6] GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F20..1F27 ; Lowercase # L& [8] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI +1F30..1F37 ; Lowercase # L& [8] GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI +1F40..1F45 ; Lowercase # L& [6] GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F50..1F57 ; Lowercase # L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F60..1F67 ; Lowercase # L& [8] GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F70..1F7D ; Lowercase # L& [14] GREEK SMALL LETTER ALPHA WITH VARIA..GREEK SMALL LETTER OMEGA WITH OXIA +1F80..1F87 ; Lowercase # L& [8] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F90..1F97 ; Lowercase # L& [8] GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FA0..1FA7 ; Lowercase # L& [8] GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FB0..1FB4 ; Lowercase # L& [5] GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6..1FB7 ; Lowercase # L& [2] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FBE ; Lowercase # L& GREEK PROSGEGRAMMENI +1FC2..1FC4 ; Lowercase # L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6..1FC7 ; Lowercase # L& [2] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FD0..1FD3 ; Lowercase # L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6..1FD7 ; Lowercase # L& [2] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FE0..1FE7 ; Lowercase # L& [8] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FF2..1FF4 ; Lowercase # L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6..1FF7 ; Lowercase # L& [2] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +2090..2094 ; Lowercase # Lm [5] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER SCHWA +210A ; Lowercase # L& SCRIPT SMALL G +210E..210F ; Lowercase # L& [2] PLANCK CONSTANT..PLANCK CONSTANT OVER TWO PI +2113 ; Lowercase # L& SCRIPT SMALL L +212F ; Lowercase # L& SCRIPT SMALL E +2134 ; Lowercase # L& SCRIPT SMALL O +2139 ; Lowercase # L& INFORMATION SOURCE +213C..213D ; Lowercase # L& [2] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK SMALL GAMMA +2146..2149 ; Lowercase # L& [4] DOUBLE-STRUCK ITALIC SMALL D..DOUBLE-STRUCK ITALIC SMALL J +214E ; Lowercase # L& TURNED SMALL F +2170..217F ; Lowercase # Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND +2184 ; Lowercase # L& LATIN SMALL LETTER REVERSED C +24D0..24E9 ; Lowercase # So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z +2C30..2C5E ; Lowercase # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C61 ; Lowercase # L& LATIN SMALL LETTER L WITH DOUBLE BAR +2C65..2C66 ; Lowercase # L& [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE +2C68 ; Lowercase # L& LATIN SMALL LETTER H WITH DESCENDER +2C6A ; Lowercase # L& LATIN SMALL LETTER K WITH DESCENDER +2C6C ; Lowercase # L& LATIN SMALL LETTER Z WITH DESCENDER +2C71 ; Lowercase # L& LATIN SMALL LETTER V WITH RIGHT HOOK +2C73..2C74 ; Lowercase # L& [2] LATIN SMALL LETTER W WITH HOOK..LATIN SMALL LETTER V WITH CURL +2C76..2C7C ; Lowercase # L& [7] LATIN SMALL LETTER HALF H..LATIN SUBSCRIPT SMALL LETTER J +2C7D ; Lowercase # Lm MODIFIER LETTER CAPITAL V +2C81 ; Lowercase # L& COPTIC SMALL LETTER ALFA +2C83 ; Lowercase # L& COPTIC SMALL LETTER VIDA +2C85 ; Lowercase # L& COPTIC SMALL LETTER GAMMA +2C87 ; Lowercase # L& COPTIC SMALL LETTER DALDA +2C89 ; Lowercase # L& COPTIC SMALL LETTER EIE +2C8B ; Lowercase # L& COPTIC SMALL LETTER SOU +2C8D ; Lowercase # L& COPTIC SMALL LETTER ZATA +2C8F ; Lowercase # L& COPTIC SMALL LETTER HATE +2C91 ; Lowercase # L& COPTIC SMALL LETTER THETHE +2C93 ; Lowercase # L& COPTIC SMALL LETTER IAUDA +2C95 ; Lowercase # L& COPTIC SMALL LETTER KAPA +2C97 ; Lowercase # L& COPTIC SMALL LETTER LAULA +2C99 ; Lowercase # L& COPTIC SMALL LETTER MI +2C9B ; Lowercase # L& COPTIC SMALL LETTER NI +2C9D ; Lowercase # L& COPTIC SMALL LETTER KSI +2C9F ; Lowercase # L& COPTIC SMALL LETTER O +2CA1 ; Lowercase # L& COPTIC SMALL LETTER PI +2CA3 ; Lowercase # L& COPTIC SMALL LETTER RO +2CA5 ; Lowercase # L& COPTIC SMALL LETTER SIMA +2CA7 ; Lowercase # L& COPTIC SMALL LETTER TAU +2CA9 ; Lowercase # L& COPTIC SMALL LETTER UA +2CAB ; Lowercase # L& COPTIC SMALL LETTER FI +2CAD ; Lowercase # L& COPTIC SMALL LETTER KHI +2CAF ; Lowercase # L& COPTIC SMALL LETTER PSI +2CB1 ; Lowercase # L& COPTIC SMALL LETTER OOU +2CB3 ; Lowercase # L& COPTIC SMALL LETTER DIALECT-P ALEF +2CB5 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC AIN +2CB7 ; Lowercase # L& COPTIC SMALL LETTER CRYPTOGRAMMIC EIE +2CB9 ; Lowercase # L& COPTIC SMALL LETTER DIALECT-P KAPA +2CBB ; Lowercase # L& COPTIC SMALL LETTER DIALECT-P NI +2CBD ; Lowercase # L& COPTIC SMALL LETTER CRYPTOGRAMMIC NI +2CBF ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC OOU +2CC1 ; Lowercase # L& COPTIC SMALL LETTER SAMPI +2CC3 ; Lowercase # L& COPTIC SMALL LETTER CROSSED SHEI +2CC5 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC SHEI +2CC7 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC ESH +2CC9 ; Lowercase # L& COPTIC SMALL LETTER AKHMIMIC KHEI +2CCB ; Lowercase # L& COPTIC SMALL LETTER DIALECT-P HORI +2CCD ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC HORI +2CCF ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC HA +2CD1 ; Lowercase # L& COPTIC SMALL LETTER L-SHAPED HA +2CD3 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC HEI +2CD5 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC HAT +2CD7 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC GANGIA +2CD9 ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC DJA +2CDB ; Lowercase # L& COPTIC SMALL LETTER OLD COPTIC SHIMA +2CDD ; Lowercase # L& COPTIC SMALL LETTER OLD NUBIAN SHIMA +2CDF ; Lowercase # L& COPTIC SMALL LETTER OLD NUBIAN NGI +2CE1 ; Lowercase # L& COPTIC SMALL LETTER OLD NUBIAN NYI +2CE3..2CE4 ; Lowercase # L& [2] COPTIC SMALL LETTER OLD NUBIAN WAU..COPTIC SYMBOL KAI +2CEC ; Lowercase # L& COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI +2CEE ; Lowercase # L& COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +2D00..2D25 ; Lowercase # L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE +A641 ; Lowercase # L& CYRILLIC SMALL LETTER ZEMLYA +A643 ; Lowercase # L& CYRILLIC SMALL LETTER DZELO +A645 ; Lowercase # L& CYRILLIC SMALL LETTER REVERSED DZE +A647 ; Lowercase # L& CYRILLIC SMALL LETTER IOTA +A649 ; Lowercase # L& CYRILLIC SMALL LETTER DJERV +A64B ; Lowercase # L& CYRILLIC SMALL LETTER MONOGRAPH UK +A64D ; Lowercase # L& CYRILLIC SMALL LETTER BROAD OMEGA +A64F ; Lowercase # L& CYRILLIC SMALL LETTER NEUTRAL YER +A651 ; Lowercase # L& CYRILLIC SMALL LETTER YERU WITH BACK YER +A653 ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED YAT +A655 ; Lowercase # L& CYRILLIC SMALL LETTER REVERSED YU +A657 ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED A +A659 ; Lowercase # L& CYRILLIC SMALL LETTER CLOSED LITTLE YUS +A65B ; Lowercase # L& CYRILLIC SMALL LETTER BLENDED YUS +A65D ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS +A65F ; Lowercase # L& CYRILLIC SMALL LETTER YN +A661 ; Lowercase # L& CYRILLIC SMALL LETTER REVERSED TSE +A663 ; Lowercase # L& CYRILLIC SMALL LETTER SOFT DE +A665 ; Lowercase # L& CYRILLIC SMALL LETTER SOFT EL +A667 ; Lowercase # L& CYRILLIC SMALL LETTER SOFT EM +A669 ; Lowercase # L& CYRILLIC SMALL LETTER MONOCULAR O +A66B ; Lowercase # L& CYRILLIC SMALL LETTER BINOCULAR O +A66D ; Lowercase # L& CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +A681 ; Lowercase # L& CYRILLIC SMALL LETTER DWE +A683 ; Lowercase # L& CYRILLIC SMALL LETTER DZWE +A685 ; Lowercase # L& CYRILLIC SMALL LETTER ZHWE +A687 ; Lowercase # L& CYRILLIC SMALL LETTER CCHE +A689 ; Lowercase # L& CYRILLIC SMALL LETTER DZZE +A68B ; Lowercase # L& CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK +A68D ; Lowercase # L& CYRILLIC SMALL LETTER TWE +A68F ; Lowercase # L& CYRILLIC SMALL LETTER TSWE +A691 ; Lowercase # L& CYRILLIC SMALL LETTER TSSE +A693 ; Lowercase # L& CYRILLIC SMALL LETTER TCHE +A695 ; Lowercase # L& CYRILLIC SMALL LETTER HWE +A697 ; Lowercase # L& CYRILLIC SMALL LETTER SHWE +A723 ; Lowercase # L& LATIN SMALL LETTER EGYPTOLOGICAL ALEF +A725 ; Lowercase # L& LATIN SMALL LETTER EGYPTOLOGICAL AIN +A727 ; Lowercase # L& LATIN SMALL LETTER HENG +A729 ; Lowercase # L& LATIN SMALL LETTER TZ +A72B ; Lowercase # L& LATIN SMALL LETTER TRESILLO +A72D ; Lowercase # L& LATIN SMALL LETTER CUATRILLO +A72F..A731 ; Lowercase # L& [3] LATIN SMALL LETTER CUATRILLO WITH COMMA..LATIN LETTER SMALL CAPITAL S +A733 ; Lowercase # L& LATIN SMALL LETTER AA +A735 ; Lowercase # L& LATIN SMALL LETTER AO +A737 ; Lowercase # L& LATIN SMALL LETTER AU +A739 ; Lowercase # L& LATIN SMALL LETTER AV +A73B ; Lowercase # L& LATIN SMALL LETTER AV WITH HORIZONTAL BAR +A73D ; Lowercase # L& LATIN SMALL LETTER AY +A73F ; Lowercase # L& LATIN SMALL LETTER REVERSED C WITH DOT +A741 ; Lowercase # L& LATIN SMALL LETTER K WITH STROKE +A743 ; Lowercase # L& LATIN SMALL LETTER K WITH DIAGONAL STROKE +A745 ; Lowercase # L& LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE +A747 ; Lowercase # L& LATIN SMALL LETTER BROKEN L +A749 ; Lowercase # L& LATIN SMALL LETTER L WITH HIGH STROKE +A74B ; Lowercase # L& LATIN SMALL LETTER O WITH LONG STROKE OVERLAY +A74D ; Lowercase # L& LATIN SMALL LETTER O WITH LOOP +A74F ; Lowercase # L& LATIN SMALL LETTER OO +A751 ; Lowercase # L& LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER +A753 ; Lowercase # L& LATIN SMALL LETTER P WITH FLOURISH +A755 ; Lowercase # L& LATIN SMALL LETTER P WITH SQUIRREL TAIL +A757 ; Lowercase # L& LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER +A759 ; Lowercase # L& LATIN SMALL LETTER Q WITH DIAGONAL STROKE +A75B ; Lowercase # L& LATIN SMALL LETTER R ROTUNDA +A75D ; Lowercase # L& LATIN SMALL LETTER RUM ROTUNDA +A75F ; Lowercase # L& LATIN SMALL LETTER V WITH DIAGONAL STROKE +A761 ; Lowercase # L& LATIN SMALL LETTER VY +A763 ; Lowercase # L& LATIN SMALL LETTER VISIGOTHIC Z +A765 ; Lowercase # L& LATIN SMALL LETTER THORN WITH STROKE +A767 ; Lowercase # L& LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER +A769 ; Lowercase # L& LATIN SMALL LETTER VEND +A76B ; Lowercase # L& LATIN SMALL LETTER ET +A76D ; Lowercase # L& LATIN SMALL LETTER IS +A76F ; Lowercase # L& LATIN SMALL LETTER CON +A770 ; Lowercase # Lm MODIFIER LETTER US +A771..A778 ; Lowercase # L& [8] LATIN SMALL LETTER DUM..LATIN SMALL LETTER UM +A77A ; Lowercase # L& LATIN SMALL LETTER INSULAR D +A77C ; Lowercase # L& LATIN SMALL LETTER INSULAR F +A77F ; Lowercase # L& LATIN SMALL LETTER TURNED INSULAR G +A781 ; Lowercase # L& LATIN SMALL LETTER TURNED L +A783 ; Lowercase # L& LATIN SMALL LETTER INSULAR R +A785 ; Lowercase # L& LATIN SMALL LETTER INSULAR S +A787 ; Lowercase # L& LATIN SMALL LETTER INSULAR T +A78C ; Lowercase # L& LATIN SMALL LETTER SALTILLO +A78E ; Lowercase # L& LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT +A791 ; Lowercase # L& LATIN SMALL LETTER N WITH DESCENDER +A7A1 ; Lowercase # L& LATIN SMALL LETTER G WITH OBLIQUE STROKE +A7A3 ; Lowercase # L& LATIN SMALL LETTER K WITH OBLIQUE STROKE +A7A5 ; Lowercase # L& LATIN SMALL LETTER N WITH OBLIQUE STROKE +A7A7 ; Lowercase # L& LATIN SMALL LETTER R WITH OBLIQUE STROKE +A7A9 ; Lowercase # L& LATIN SMALL LETTER S WITH OBLIQUE STROKE +A7FA ; Lowercase # L& LATIN LETTER SMALL CAPITAL TURNED M +FB00..FB06 ; Lowercase # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST +FB13..FB17 ; Lowercase # L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH +FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z +10428..1044F ; Lowercase # L& [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW +1D41A..1D433 ; Lowercase # L& [26] MATHEMATICAL BOLD SMALL A..MATHEMATICAL BOLD SMALL Z +1D44E..1D454 ; Lowercase # L& [7] MATHEMATICAL ITALIC SMALL A..MATHEMATICAL ITALIC SMALL G +1D456..1D467 ; Lowercase # L& [18] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL ITALIC SMALL Z +1D482..1D49B ; Lowercase # L& [26] MATHEMATICAL BOLD ITALIC SMALL A..MATHEMATICAL BOLD ITALIC SMALL Z +1D4B6..1D4B9 ; Lowercase # L& [4] MATHEMATICAL SCRIPT SMALL A..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Lowercase # L& MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Lowercase # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D4CF ; Lowercase # L& [11] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL SCRIPT SMALL Z +1D4EA..1D503 ; Lowercase # L& [26] MATHEMATICAL BOLD SCRIPT SMALL A..MATHEMATICAL BOLD SCRIPT SMALL Z +1D51E..1D537 ; Lowercase # L& [26] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL FRAKTUR SMALL Z +1D552..1D56B ; Lowercase # L& [26] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL DOUBLE-STRUCK SMALL Z +1D586..1D59F ; Lowercase # L& [26] MATHEMATICAL BOLD FRAKTUR SMALL A..MATHEMATICAL BOLD FRAKTUR SMALL Z +1D5BA..1D5D3 ; Lowercase # L& [26] MATHEMATICAL SANS-SERIF SMALL A..MATHEMATICAL SANS-SERIF SMALL Z +1D5EE..1D607 ; Lowercase # L& [26] MATHEMATICAL SANS-SERIF BOLD SMALL A..MATHEMATICAL SANS-SERIF BOLD SMALL Z +1D622..1D63B ; Lowercase # L& [26] MATHEMATICAL SANS-SERIF ITALIC SMALL A..MATHEMATICAL SANS-SERIF ITALIC SMALL Z +1D656..1D66F ; Lowercase # L& [26] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z +1D68A..1D6A5 ; Lowercase # L& [28] MATHEMATICAL MONOSPACE SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6C2..1D6DA ; Lowercase # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DC..1D6E1 ; Lowercase # L& [6] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL BOLD PI SYMBOL +1D6FC..1D714 ; Lowercase # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D716..1D71B ; Lowercase # L& [6] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL ITALIC PI SYMBOL +1D736..1D74E ; Lowercase # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D750..1D755 ; Lowercase # L& [6] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC PI SYMBOL +1D770..1D788 ; Lowercase # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D78A..1D78F ; Lowercase # L& [6] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD PI SYMBOL +1D7AA..1D7C2 ; Lowercase # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C4..1D7C9 ; Lowercase # L& [6] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL +1D7CB ; Lowercase # L& MATHEMATICAL BOLD SMALL DIGAMMA + +# Total code points: 1918 + +# ================================================ + +# Derived Property: Uppercase +# Generated from: Lu + Other_Uppercase + +0041..005A ; Uppercase # L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +00C0..00D6 ; Uppercase # L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS +00D8..00DE ; Uppercase # L& [7] LATIN CAPITAL LETTER O WITH STROKE..LATIN CAPITAL LETTER THORN +0100 ; Uppercase # L& LATIN CAPITAL LETTER A WITH MACRON +0102 ; Uppercase # L& LATIN CAPITAL LETTER A WITH BREVE +0104 ; Uppercase # L& LATIN CAPITAL LETTER A WITH OGONEK +0106 ; Uppercase # L& LATIN CAPITAL LETTER C WITH ACUTE +0108 ; Uppercase # L& LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A ; Uppercase # L& LATIN CAPITAL LETTER C WITH DOT ABOVE +010C ; Uppercase # L& LATIN CAPITAL LETTER C WITH CARON +010E ; Uppercase # L& LATIN CAPITAL LETTER D WITH CARON +0110 ; Uppercase # L& LATIN CAPITAL LETTER D WITH STROKE +0112 ; Uppercase # L& LATIN CAPITAL LETTER E WITH MACRON +0114 ; Uppercase # L& LATIN CAPITAL LETTER E WITH BREVE +0116 ; Uppercase # L& LATIN CAPITAL LETTER E WITH DOT ABOVE +0118 ; Uppercase # L& LATIN CAPITAL LETTER E WITH OGONEK +011A ; Uppercase # L& LATIN CAPITAL LETTER E WITH CARON +011C ; Uppercase # L& LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E ; Uppercase # L& LATIN CAPITAL LETTER G WITH BREVE +0120 ; Uppercase # L& LATIN CAPITAL LETTER G WITH DOT ABOVE +0122 ; Uppercase # L& LATIN CAPITAL LETTER G WITH CEDILLA +0124 ; Uppercase # L& LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126 ; Uppercase # L& LATIN CAPITAL LETTER H WITH STROKE +0128 ; Uppercase # L& LATIN CAPITAL LETTER I WITH TILDE +012A ; Uppercase # L& LATIN CAPITAL LETTER I WITH MACRON +012C ; Uppercase # L& LATIN CAPITAL LETTER I WITH BREVE +012E ; Uppercase # L& LATIN CAPITAL LETTER I WITH OGONEK +0130 ; Uppercase # L& LATIN CAPITAL LETTER I WITH DOT ABOVE +0132 ; Uppercase # L& LATIN CAPITAL LIGATURE IJ +0134 ; Uppercase # L& LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136 ; Uppercase # L& LATIN CAPITAL LETTER K WITH CEDILLA +0139 ; Uppercase # L& LATIN CAPITAL LETTER L WITH ACUTE +013B ; Uppercase # L& LATIN CAPITAL LETTER L WITH CEDILLA +013D ; Uppercase # L& LATIN CAPITAL LETTER L WITH CARON +013F ; Uppercase # L& LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141 ; Uppercase # L& LATIN CAPITAL LETTER L WITH STROKE +0143 ; Uppercase # L& LATIN CAPITAL LETTER N WITH ACUTE +0145 ; Uppercase # L& LATIN CAPITAL LETTER N WITH CEDILLA +0147 ; Uppercase # L& LATIN CAPITAL LETTER N WITH CARON +014A ; Uppercase # L& LATIN CAPITAL LETTER ENG +014C ; Uppercase # L& LATIN CAPITAL LETTER O WITH MACRON +014E ; Uppercase # L& LATIN CAPITAL LETTER O WITH BREVE +0150 ; Uppercase # L& LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152 ; Uppercase # L& LATIN CAPITAL LIGATURE OE +0154 ; Uppercase # L& LATIN CAPITAL LETTER R WITH ACUTE +0156 ; Uppercase # L& LATIN CAPITAL LETTER R WITH CEDILLA +0158 ; Uppercase # L& LATIN CAPITAL LETTER R WITH CARON +015A ; Uppercase # L& LATIN CAPITAL LETTER S WITH ACUTE +015C ; Uppercase # L& LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E ; Uppercase # L& LATIN CAPITAL LETTER S WITH CEDILLA +0160 ; Uppercase # L& LATIN CAPITAL LETTER S WITH CARON +0162 ; Uppercase # L& LATIN CAPITAL LETTER T WITH CEDILLA +0164 ; Uppercase # L& LATIN CAPITAL LETTER T WITH CARON +0166 ; Uppercase # L& LATIN CAPITAL LETTER T WITH STROKE +0168 ; Uppercase # L& LATIN CAPITAL LETTER U WITH TILDE +016A ; Uppercase # L& LATIN CAPITAL LETTER U WITH MACRON +016C ; Uppercase # L& LATIN CAPITAL LETTER U WITH BREVE +016E ; Uppercase # L& LATIN CAPITAL LETTER U WITH RING ABOVE +0170 ; Uppercase # L& LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172 ; Uppercase # L& LATIN CAPITAL LETTER U WITH OGONEK +0174 ; Uppercase # L& LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176 ; Uppercase # L& LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178..0179 ; Uppercase # L& [2] LATIN CAPITAL LETTER Y WITH DIAERESIS..LATIN CAPITAL LETTER Z WITH ACUTE +017B ; Uppercase # L& LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D ; Uppercase # L& LATIN CAPITAL LETTER Z WITH CARON +0181..0182 ; Uppercase # L& [2] LATIN CAPITAL LETTER B WITH HOOK..LATIN CAPITAL LETTER B WITH TOPBAR +0184 ; Uppercase # L& LATIN CAPITAL LETTER TONE SIX +0186..0187 ; Uppercase # L& [2] LATIN CAPITAL LETTER OPEN O..LATIN CAPITAL LETTER C WITH HOOK +0189..018B ; Uppercase # L& [3] LATIN CAPITAL LETTER AFRICAN D..LATIN CAPITAL LETTER D WITH TOPBAR +018E..0191 ; Uppercase # L& [4] LATIN CAPITAL LETTER REVERSED E..LATIN CAPITAL LETTER F WITH HOOK +0193..0194 ; Uppercase # L& [2] LATIN CAPITAL LETTER G WITH HOOK..LATIN CAPITAL LETTER GAMMA +0196..0198 ; Uppercase # L& [3] LATIN CAPITAL LETTER IOTA..LATIN CAPITAL LETTER K WITH HOOK +019C..019D ; Uppercase # L& [2] LATIN CAPITAL LETTER TURNED M..LATIN CAPITAL LETTER N WITH LEFT HOOK +019F..01A0 ; Uppercase # L& [2] LATIN CAPITAL LETTER O WITH MIDDLE TILDE..LATIN CAPITAL LETTER O WITH HORN +01A2 ; Uppercase # L& LATIN CAPITAL LETTER OI +01A4 ; Uppercase # L& LATIN CAPITAL LETTER P WITH HOOK +01A6..01A7 ; Uppercase # L& [2] LATIN LETTER YR..LATIN CAPITAL LETTER TONE TWO +01A9 ; Uppercase # L& LATIN CAPITAL LETTER ESH +01AC ; Uppercase # L& LATIN CAPITAL LETTER T WITH HOOK +01AE..01AF ; Uppercase # L& [2] LATIN CAPITAL LETTER T WITH RETROFLEX HOOK..LATIN CAPITAL LETTER U WITH HORN +01B1..01B3 ; Uppercase # L& [3] LATIN CAPITAL LETTER UPSILON..LATIN CAPITAL LETTER Y WITH HOOK +01B5 ; Uppercase # L& LATIN CAPITAL LETTER Z WITH STROKE +01B7..01B8 ; Uppercase # L& [2] LATIN CAPITAL LETTER EZH..LATIN CAPITAL LETTER EZH REVERSED +01BC ; Uppercase # L& LATIN CAPITAL LETTER TONE FIVE +01C4 ; Uppercase # L& LATIN CAPITAL LETTER DZ WITH CARON +01C7 ; Uppercase # L& LATIN CAPITAL LETTER LJ +01CA ; Uppercase # L& LATIN CAPITAL LETTER NJ +01CD ; Uppercase # L& LATIN CAPITAL LETTER A WITH CARON +01CF ; Uppercase # L& LATIN CAPITAL LETTER I WITH CARON +01D1 ; Uppercase # L& LATIN CAPITAL LETTER O WITH CARON +01D3 ; Uppercase # L& LATIN CAPITAL LETTER U WITH CARON +01D5 ; Uppercase # L& LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7 ; Uppercase # L& LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9 ; Uppercase # L& LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB ; Uppercase # L& LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE ; Uppercase # L& LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0 ; Uppercase # L& LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2 ; Uppercase # L& LATIN CAPITAL LETTER AE WITH MACRON +01E4 ; Uppercase # L& LATIN CAPITAL LETTER G WITH STROKE +01E6 ; Uppercase # L& LATIN CAPITAL LETTER G WITH CARON +01E8 ; Uppercase # L& LATIN CAPITAL LETTER K WITH CARON +01EA ; Uppercase # L& LATIN CAPITAL LETTER O WITH OGONEK +01EC ; Uppercase # L& LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE ; Uppercase # L& LATIN CAPITAL LETTER EZH WITH CARON +01F1 ; Uppercase # L& LATIN CAPITAL LETTER DZ +01F4 ; Uppercase # L& LATIN CAPITAL LETTER G WITH ACUTE +01F6..01F8 ; Uppercase # L& [3] LATIN CAPITAL LETTER HWAIR..LATIN CAPITAL LETTER N WITH GRAVE +01FA ; Uppercase # L& LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC ; Uppercase # L& LATIN CAPITAL LETTER AE WITH ACUTE +01FE ; Uppercase # L& LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200 ; Uppercase # L& LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202 ; Uppercase # L& LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204 ; Uppercase # L& LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206 ; Uppercase # L& LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208 ; Uppercase # L& LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A ; Uppercase # L& LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C ; Uppercase # L& LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E ; Uppercase # L& LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210 ; Uppercase # L& LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212 ; Uppercase # L& LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214 ; Uppercase # L& LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216 ; Uppercase # L& LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218 ; Uppercase # L& LATIN CAPITAL LETTER S WITH COMMA BELOW +021A ; Uppercase # L& LATIN CAPITAL LETTER T WITH COMMA BELOW +021C ; Uppercase # L& LATIN CAPITAL LETTER YOGH +021E ; Uppercase # L& LATIN CAPITAL LETTER H WITH CARON +0220 ; Uppercase # L& LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222 ; Uppercase # L& LATIN CAPITAL LETTER OU +0224 ; Uppercase # L& LATIN CAPITAL LETTER Z WITH HOOK +0226 ; Uppercase # L& LATIN CAPITAL LETTER A WITH DOT ABOVE +0228 ; Uppercase # L& LATIN CAPITAL LETTER E WITH CEDILLA +022A ; Uppercase # L& LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C ; Uppercase # L& LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E ; Uppercase # L& LATIN CAPITAL LETTER O WITH DOT ABOVE +0230 ; Uppercase # L& LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232 ; Uppercase # L& LATIN CAPITAL LETTER Y WITH MACRON +023A..023B ; Uppercase # L& [2] LATIN CAPITAL LETTER A WITH STROKE..LATIN CAPITAL LETTER C WITH STROKE +023D..023E ; Uppercase # L& [2] LATIN CAPITAL LETTER L WITH BAR..LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241 ; Uppercase # L& LATIN CAPITAL LETTER GLOTTAL STOP +0243..0246 ; Uppercase # L& [4] LATIN CAPITAL LETTER B WITH STROKE..LATIN CAPITAL LETTER E WITH STROKE +0248 ; Uppercase # L& LATIN CAPITAL LETTER J WITH STROKE +024A ; Uppercase # L& LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C ; Uppercase # L& LATIN CAPITAL LETTER R WITH STROKE +024E ; Uppercase # L& LATIN CAPITAL LETTER Y WITH STROKE +0370 ; Uppercase # L& GREEK CAPITAL LETTER HETA +0372 ; Uppercase # L& GREEK CAPITAL LETTER ARCHAIC SAMPI +0376 ; Uppercase # L& GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +0386 ; Uppercase # L& GREEK CAPITAL LETTER ALPHA WITH TONOS +0388..038A ; Uppercase # L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS +038C ; Uppercase # L& GREEK CAPITAL LETTER OMICRON WITH TONOS +038E..038F ; Uppercase # L& [2] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER OMEGA WITH TONOS +0391..03A1 ; Uppercase # L& [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO +03A3..03AB ; Uppercase # L& [9] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03CF ; Uppercase # L& GREEK CAPITAL KAI SYMBOL +03D2..03D4 ; Uppercase # L& [3] GREEK UPSILON WITH HOOK SYMBOL..GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL +03D8 ; Uppercase # L& GREEK LETTER ARCHAIC KOPPA +03DA ; Uppercase # L& GREEK LETTER STIGMA +03DC ; Uppercase # L& GREEK LETTER DIGAMMA +03DE ; Uppercase # L& GREEK LETTER KOPPA +03E0 ; Uppercase # L& GREEK LETTER SAMPI +03E2 ; Uppercase # L& COPTIC CAPITAL LETTER SHEI +03E4 ; Uppercase # L& COPTIC CAPITAL LETTER FEI +03E6 ; Uppercase # L& COPTIC CAPITAL LETTER KHEI +03E8 ; Uppercase # L& COPTIC CAPITAL LETTER HORI +03EA ; Uppercase # L& COPTIC CAPITAL LETTER GANGIA +03EC ; Uppercase # L& COPTIC CAPITAL LETTER SHIMA +03EE ; Uppercase # L& COPTIC CAPITAL LETTER DEI +03F4 ; Uppercase # L& GREEK CAPITAL THETA SYMBOL +03F7 ; Uppercase # L& GREEK CAPITAL LETTER SHO +03F9..03FA ; Uppercase # L& [2] GREEK CAPITAL LUNATE SIGMA SYMBOL..GREEK CAPITAL LETTER SAN +03FD..042F ; Uppercase # L& [51] GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL..CYRILLIC CAPITAL LETTER YA +0460 ; Uppercase # L& CYRILLIC CAPITAL LETTER OMEGA +0462 ; Uppercase # L& CYRILLIC CAPITAL LETTER YAT +0464 ; Uppercase # L& CYRILLIC CAPITAL LETTER IOTIFIED E +0466 ; Uppercase # L& CYRILLIC CAPITAL LETTER LITTLE YUS +0468 ; Uppercase # L& CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +046A ; Uppercase # L& CYRILLIC CAPITAL LETTER BIG YUS +046C ; Uppercase # L& CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046E ; Uppercase # L& CYRILLIC CAPITAL LETTER KSI +0470 ; Uppercase # L& CYRILLIC CAPITAL LETTER PSI +0472 ; Uppercase # L& CYRILLIC CAPITAL LETTER FITA +0474 ; Uppercase # L& CYRILLIC CAPITAL LETTER IZHITSA +0476 ; Uppercase # L& CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0478 ; Uppercase # L& CYRILLIC CAPITAL LETTER UK +047A ; Uppercase # L& CYRILLIC CAPITAL LETTER ROUND OMEGA +047C ; Uppercase # L& CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047E ; Uppercase # L& CYRILLIC CAPITAL LETTER OT +0480 ; Uppercase # L& CYRILLIC CAPITAL LETTER KOPPA +048A ; Uppercase # L& CYRILLIC CAPITAL LETTER SHORT I WITH TAIL From noreply at buildbot.pypy.org Wed Mar 20 01:50:11 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:50:11 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: update Message-ID: <20130320005011.B251E1C1016@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62527:6f2c4610695c Date: 2013-03-19 17:49 -0700 http://bitbucket.org/pypy/pypy/changeset/6f2c4610695c/ Log: update diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -1,121 +1,121 @@ -[3304d0bb187] {jit-backend-dump +[1cffd8feb691] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0ca602] jit-backend-dump} -[3304d0cfdf4] {jit-backend-dump +CODE_DUMP @7f5514b31000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd8ffaba6] jit-backend-dump} +[1cffd90012ee] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0d2b27] jit-backend-dump} -[3304d0d73d6] {jit-backend-dump +CODE_DUMP @7f5514b31085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd9003b76] jit-backend-dump} +[1cffd900719f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d512e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[3304d0d9073] jit-backend-dump} -[3304d0db1d8] {jit-backend-dump +CODE_DUMP @7f5514b3112e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1cffd9008c81] jit-backend-dump} +[1cffd900b384] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[3304d0dce9e] jit-backend-dump} -[3304d0dfc06] {jit-backend-dump +CODE_DUMP @7f5514b31191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1cffd900cf18] jit-backend-dump} +[1cffd9010345] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d51fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C25C80219034C8B2425C002190348C70425C00219030000000048C70425C80219030000000041BBC069120141FFD3F20F10442418488B44240848891C25C80219034C892425C0021903488B5C24284C8B642430488D642438C3 -[3304d0e1a04] jit-backend-dump} -[3304d0e4ae5] {jit-backend-dump +CODE_DUMP @7f5514b311fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 +[1cffd9011f0b] jit-backend-dump} +[1cffd9015bd8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C25C802190348894D38488B1C25C002190348C70425C00219030000000048C70425C80219030000000041BB90E3E80041FFD34889C5488B4D3848C745380000000048890C25C802190348891C25C00219034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[3304d0e9130] jit-backend-dump} -[3304d0ea4a1] {jit-backend-dump +CODE_DUMP @7f5514b31275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[1cffd901a191] jit-backend-dump} +[1cffd901b3a6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0ecf16] jit-backend-dump} -[3304d0ee1ff] {jit-backend-dump +CODE_DUMP @7f5514b31491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd901dc46] jit-backend-dump} +[1cffd901ef79] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0fca06] jit-backend-dump} -[3304d0fe4ac] {jit-backend-dump +CODE_DUMP @7f5514b31595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd902ce01] jit-backend-dump} +[1cffd902e819] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d56bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[3304d1018ac] jit-backend-dump} -[3304d103089] {jit-backend-dump +CODE_DUMP @7f5514b316bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1cffd9031b79] jit-backend-dump} +[1cffd90331b0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d581e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[3304d1062c0] jit-backend-dump} -[3304d1072c1] {jit-backend-dump +CODE_DUMP @7f5514b3181e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1cffd903629a] jit-backend-dump} +[1cffd903736b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5988 +0 488B0425C802190348C70425C00219030000000048C70425C8021903000000004889453848C745108064B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d1089ec] jit-backend-dump} -[3304d11572c] {jit-backend-dump +CODE_DUMP @7f5514b31988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd9038a70] jit-backend-dump} +[1cffd903e2cd] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d59e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBF0ACE80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD517D6A477F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25C8EEB50148C7452000000000C34883C40849BB88597D6A477F000041FFE3 -[3304d120245] jit-backend-dump} -[3304d122916] {jit-backend-dump +CODE_DUMP @7f5514b319e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD11B314557F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB8819B314557F000041FFE3 +[1cffd904265b] jit-backend-dump} +[1cffd90448f2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5bd6 +0 4889E74883EC0841BB9018210141FFD34883C408488B0425C00219034885C07501C34883C40849BB88597D6A477F000041FFE3 -[3304d1240c0] jit-backend-dump} -[3304d1246a0] {jit-backend-counts -[3304d124ab0] jit-backend-counts} -[3304d690a50] {jit-backend -[3304db64ec0] {jit-backend-dump +CODE_DUMP @7f5514b31bd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB8819B314557F000041FFE3 +[1cffd9045d15] jit-backend-dump} +[1cffd904647a] {jit-backend-counts +[1cffd9046851] jit-backend-counts} +[1cffd9636773] {jit-backend +[1cffd9afbdde] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBF0905D6D477F00004D8B3B4D8D770149BBF0905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08915D6D477F0000498B0B488D410149BB08915D6D477F00004989034983F8020F85000000004883FB017206813B680B00000F85000000004983FA000F850000000049BB20C0FC6A477F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425409519034983FC000F8C0000000049BB20915D6D477F00004D8B234D8D54240149BB20915D6D477F00004D89134883FB0A0F8D000000004C8D5301488B1C25409519034883FB000F8C000000004C89D3E9B9FFFFFF49BB2020FD6A477F0000415349BB405C7D6A477F0000415349BB00507D6A477F000041FFE349BB3806036B477F0000415349BB505C7D6A477F0000415349BB00507D6A477F000041FFE349BBC005036B477F0000415349BB605C7D6A477F0000415349BB00507D6A477F000041FFE349BB4805036B477F0000415349BB705C7D6A477F0000415349BB00507D6A477F000041FFE349BBD004036B477F0000415349BB805C7D6A477F0000415349BB00507D6A477F000041FFE349BB5804036B477F0000415349BB905C7D6A477F0000415349BB00507D6A477F000041FFE349BBE003036B477F0000415349BBA05C7D6A477F0000415349BB00507D6A477F000041FFE349BB6803036B477F0000415349BBB05C7D6A477F0000415349BB00507D6A477F000041FFE349BBF002036B477F0000415349BBC05C7D6A477F0000415349BB00507D6A477F000041FFE349BB7802036B477F0000415349BBD05C7D6A477F0000415349BB00507D6A477F000041FFE3 -[3304db7d5e4] jit-backend-dump} -[3304db7df74] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 0x7f476a7d5d30 to 0x7f476a7d5e80 (bootstrap 0x7f476a7d5ce0) -[3304db7f906] jit-backend-addr} -[3304db8036d] {jit-backend-dump +CODE_DUMP @7f5514b31ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD61BB314557F000041FFD349BBF0509317557F00004D8B3B4D8D770149BBF0509317557F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08519317557F0000498B0B488D410149BB08519317557F00004989034983F8020F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB20803215557F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425807816034983FC000F8C0000000049BB20519317557F00004D8B234D8D54240149BB20519317557F00004D89134883FB0A0F8D000000004C8D5301488B1C25807816034883FB000F8C000000004C89D3E9B9FFFFFF49BB20E03215557F0000415349BB401CB314557F0000415349BB0010B314557F000041FFE349BB38C63815557F0000415349BB501CB314557F0000415349BB0010B314557F000041FFE349BBC0C53815557F0000415349BB601CB314557F0000415349BB0010B314557F000041FFE349BB48C53815557F0000415349BB701CB314557F0000415349BB0010B314557F000041FFE349BBD0C43815557F0000415349BB801CB314557F0000415349BB0010B314557F000041FFE349BB58C43815557F0000415349BB901CB314557F0000415349BB0010B314557F000041FFE349BBE0C33815557F0000415349BBA01CB314557F0000415349BB0010B314557F000041FFE349BB68C33815557F0000415349BBB01CB314557F0000415349BB0010B314557F000041FFE349BBF0C23815557F0000415349BBC01CB314557F0000415349BB0010B314557F000041FFE349BB78C23815557F0000415349BBD01CB314557F0000415349BB0010B314557F000041FFE3 +[1cffd9b146d6] jit-backend-dump} +[1cffd9b14ff3] {jit-backend-addr +Loop 0 ( #9 LOAD_FAST) has address 0x7f5514b31d30 to 0x7f5514b31e80 (bootstrap 0x7f5514b31ce0) +[1cffd9b16753] jit-backend-addr} +[1cffd9b17245] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5de1 +0 9B000000 -[3304db81160] jit-backend-dump} -[3304db81772] {jit-backend-dump +CODE_DUMP @7f5514b31de1 +0 9B000000 +[1cffd9b18103] jit-backend-dump} +[1cffd9b18762] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5df3 +0 AE000000 -[3304db8217a] jit-backend-dump} -[3304db825e3] {jit-backend-dump +CODE_DUMP @7f5514b31df3 +0 AE000000 +[1cffd9b191ae] jit-backend-dump} +[1cffd9b1960b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5dfd +0 C9000000 -[3304db82ee8] jit-backend-dump} -[3304db83330] {jit-backend-dump +CODE_DUMP @7f5514b31dfd +0 C9000000 +[1cffd9b19f1f] jit-backend-dump} +[1cffd9b1a32f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e10 +0 DB000000 -[3304db83c9d] jit-backend-dump} -[3304db840c2] {jit-backend-dump +CODE_DUMP @7f5514b31e10 +0 DB000000 +[1cffd9b1ac8d] jit-backend-dump} +[1cffd9b1b091] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e1e +0 F2000000 -[3304db849f0] jit-backend-dump} -[3304db84f62] {jit-backend-dump +CODE_DUMP @7f5514b31e1e +0 F2000000 +[1cffd9b1ba54] jit-backend-dump} +[1cffd9b1bfec] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e35 +0 25010000 -[3304db8586f] jit-backend-dump} -[3304db85c9d] {jit-backend-dump +CODE_DUMP @7f5514b31e35 +0 25010000 +[1cffd9b1c8d3] jit-backend-dump} +[1cffd9b1ccfb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e5e +0 21010000 -[3304db86572] jit-backend-dump} -[3304db869e7] {jit-backend-dump +CODE_DUMP @7f5514b31e5e +0 21010000 +[1cffd9b1d5d6] jit-backend-dump} +[1cffd9b1da25] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e74 +0 55010000 -[3304db872e3] jit-backend-dump} -[3304db88112] jit-backend} -[3304db8ae6c] {jit-log-opt-loop +CODE_DUMP @7f5514b31e74 +0 55010000 +[1cffd9b1e3b8] jit-backend-dump} +[1cffd9b1f0b2] jit-backend} +[1cffd9b20d9f] {jit-log-opt-loop # Loop 0 ( #9 LOAD_FAST) : loop with 59 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -131,17 +131,17 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944714371104)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140003404595232)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] -+279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] ++251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] ++279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] ++289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] debug_merge_point(0, 0, ' #15 COMPARE_OP') +308: i23 = getfield_gc_pure(p11, descr=) +312: i25 = int_lt(i23, 10) -guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] +guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_CONST') debug_merge_point(0, 0, ' #24 STORE_FAST') @@ -151,17 +151,17 @@ +322: i27 = int_add(i23, 1) debug_merge_point(0, 0, ' #34 STORE_FAST') debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') -+327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] -+327: i29 = getfield_raw(52008256, descr=) ++327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] ++327: i29 = getfield_raw(51804288, descr=) +335: i31 = int_lt(i29, 0) -guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] +guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(139944714371192)) ++345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(140003404595320)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +376: i32 = int_lt(i27, 10) -guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] +guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_CONST') debug_merge_point(0, 0, ' #24 STORE_FAST') @@ -171,95 +171,95 @@ +386: i33 = int_add(i27, 1) debug_merge_point(0, 0, ' #34 STORE_FAST') debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') -+390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] -+390: i35 = getfield_raw(52008256, descr=) ++390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] ++390: i35 = getfield_raw(51804288, descr=) +398: i36 = int_lt(i35, 0) -guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] +guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(139944714371192)) ++408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(140003404595320)) +416: --end of the loop-- -[3304dc0f6eb] jit-log-opt-loop} -[3304ddc81da] {jit-backend -[3304dec8bed] {jit-backend-dump +[1cffd9ba83b9] jit-log-opt-loop} +[1cffd9d7af1e] {jit-backend +[1cffd9ea4873] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBD8905D6D477F00004D8B3B4D8D770149BBD8905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38915D6D477F0000498B0B488D590149BB38915D6D477F000049891B4983F8030F85000000008138704500000F85000000004C8B40104D85C00F8400000000488B5808498B48108139005305000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A909403000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB88607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C745200000000048833C25C0021903000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425409519034883F8000F8C00000000488B856801000049BB588C026B477F00004C39D80F850000000049BB50915D6D477F00004D8B13498D420149BB50915D6D477F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE8607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C74520000000004C8B958001000049895A0848833C25C0021903000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25409519034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0D6496D477F0000415349BB08607D6A477F0000415349BB00507D6A477F000041FFE349BB708A4D6D477F0000415349BB18607D6A477F0000415349BB00507D6A477F000041FFE349BBF8894D6D477F0000415349BB28607D6A477F0000415349BB00507D6A477F000041FFE349BB80894D6D477F0000415349BB38607D6A477F0000415349BB00507D6A477F000041FFE349BB08894D6D477F0000415349BB48607D6A477F0000415349BB00507D6A477F000041FFE349BB90884D6D477F0000415349BB58607D6A477F0000415349BB00507D6A477F000041FFE349BB18884D6D477F0000415349BB68607D6A477F0000415349BB00507D6A477F000041FFE349BBA0874D6D477F0000415349BB78607D6A477F0000415349BB00507D6A477F000041FFE349BB28874D6D477F0000415349BB98607D6A477F0000415349BB85507D6A477F000041FFE349BBB0864D6D477F0000415349BBA8607D6A477F0000415349BB00507D6A477F000041FFE349BB38864D6D477F0000415349BBB8607D6A477F0000415349BB00507D6A477F000041FFE349BBC0854D6D477F0000415349BBC8607D6A477F0000415349BB00507D6A477F000041FFE349BB48854D6D477F0000415349BBD8607D6A477F0000415349BB00507D6A477F000041FFE349BBD0844D6D477F0000415349BBF8607D6A477F0000415349BB85507D6A477F000041FFE349BB58844D6D477F0000415349BB08617D6A477F0000415349BB00507D6A477F000041FFE349BBE0834D6D477F0000415349BB18617D6A477F0000415349BB00507D6A477F000041FFE3 -[3304dedb0c9] jit-backend-dump} -[3304dedb9eb] {jit-backend-addr -Loop 1 ( #13 FOR_ITER) has address 0x7f476a7d6178 to 0x7f476a7d6470 (bootstrap 0x7f476a7d6128) -[3304dedcbfe] jit-backend-addr} -[3304dedd31e] {jit-backend-dump +CODE_DUMP @7f5514b32128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD61BB314557F000041FFD349BBD8509317557F00004D8B3B4D8D770149BBD8509317557F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38519317557F0000498B0B488D590149BB38519317557F000049891B4983F8030F85000000008138E82200000F85000000004C8B40104D85C00F8400000000488B5808498B48108139685505000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A089203000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB8820B314557F00004C895D2041BBE060730041FFD3F6450401740D49BBFD11B314557F000041FFD348C745200000000048833C2500E61503000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425807816034883F8000F8C00000000488B856801000049BB584C3815557F00004C39D80F850000000049BB50519317557F00004D8B13498D420149BB50519317557F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE820B314557F00004C895D2041BBE060730041FFD3F6450401740D49BBFD11B314557F000041FFD348C74520000000004C8B958001000049895A0848833C2500E61503000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25807816034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0967F17557F0000415349BB0820B314557F0000415349BB0010B314557F000041FFE349BB704A8317557F0000415349BB1820B314557F0000415349BB0010B314557F000041FFE349BBF8498317557F0000415349BB2820B314557F0000415349BB0010B314557F000041FFE349BB80498317557F0000415349BB3820B314557F0000415349BB0010B314557F000041FFE349BB08498317557F0000415349BB4820B314557F0000415349BB0010B314557F000041FFE349BB90488317557F0000415349BB5820B314557F0000415349BB0010B314557F000041FFE349BB18488317557F0000415349BB6820B314557F0000415349BB0010B314557F000041FFE349BBA0478317557F0000415349BB7820B314557F0000415349BB0010B314557F000041FFE349BB28478317557F0000415349BB9820B314557F0000415349BB8510B314557F000041FFE349BBB0468317557F0000415349BBA820B314557F0000415349BB0010B314557F000041FFE349BB38468317557F0000415349BBB820B314557F0000415349BB0010B314557F000041FFE349BBC0458317557F0000415349BBC820B314557F0000415349BB0010B314557F000041FFE349BB48458317557F0000415349BBD820B314557F0000415349BB0010B314557F000041FFE349BBD0448317557F0000415349BBF820B314557F0000415349BB8510B314557F000041FFE349BB58448317557F0000415349BB0821B314557F0000415349BB0010B314557F000041FFE349BBE0438317557F0000415349BB1821B314557F0000415349BB0010B314557F000041FFE3 +[1cffd9ebc29f] jit-backend-dump} +[1cffd9ebcab0] {jit-backend-addr +Loop 1 ( #13 FOR_ITER) has address 0x7f5514b32178 to 0x7f5514b32470 (bootstrap 0x7f5514b32128) +[1cffd9ebde77] jit-backend-addr} +[1cffd9ebe969] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6222 +0 4A020000 -[3304dede364] jit-backend-dump} -[3304dede8d3] {jit-backend-dump +CODE_DUMP @7f5514b32222 +0 4A020000 +[1cffd9ebfa23] jit-backend-dump} +[1cffd9ec0059] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d622e +0 63020000 -[3304dedf2ce] jit-backend-dump} -[3304dedf728] {jit-backend-dump +CODE_DUMP @7f5514b3222e +0 63020000 +[1cffd9ec0ae6] jit-backend-dump} +[1cffd9ec0f4f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d623b +0 7B020000 -[3304dedffef] jit-backend-dump} -[3304dee040e] {jit-backend-dump +CODE_DUMP @7f5514b3223b +0 7B020000 +[1cffd9ec18bc] jit-backend-dump} +[1cffd9ec1d28] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d624f +0 8C020000 -[3304dee0d4e] jit-backend-dump} -[3304dee115b] {jit-backend-dump +CODE_DUMP @7f5514b3224f +0 8C020000 +[1cffd9ec2689] jit-backend-dump} +[1cffd9ec2b07] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6269 +0 97020000 -[3304dee1a98] jit-backend-dump} -[3304dee1e9f] {jit-backend-dump +CODE_DUMP @7f5514b32269 +0 97020000 +[1cffd9ec3474] jit-backend-dump} +[1cffd9ec38bc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6272 +0 B3020000 -[3304dee2789] jit-backend-dump} -[3304dee2bb1] {jit-backend-dump +CODE_DUMP @7f5514b32272 +0 B3020000 +[1cffd9ec4220] jit-backend-dump} +[1cffd9ec4677] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6291 +0 B9020000 -[3304dee34bf] jit-backend-dump} -[3304dee38cc] {jit-backend-dump +CODE_DUMP @7f5514b32291 +0 B9020000 +[1cffd9ec5011] jit-backend-dump} +[1cffd9ec5459] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d62a2 +0 CD020000 -[3304dee41c5] jit-backend-dump} -[3304dee45e1] {jit-backend-dump +CODE_DUMP @7f5514b322a2 +0 CD020000 +[1cffd9ec5e1c] jit-backend-dump} +[1cffd9ec6279] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d632d +0 67020000 -[3304dee4ec5] jit-backend-dump} -[3304dee543c] {jit-backend-dump +CODE_DUMP @7f5514b3232d +0 67020000 +[1cffd9ec6bd7] jit-backend-dump} +[1cffd9ec77c9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d635d +0 81020000 -[3304dee5d03] jit-backend-dump} -[3304dee6139] {jit-backend-dump +CODE_DUMP @7f5514b3235d +0 81020000 +[1cffd9ec8142] jit-backend-dump} +[1cffd9ec85c0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6377 +0 8C020000 -[3304dee69fa] jit-backend-dump} -[3304dee6e10] {jit-backend-dump +CODE_DUMP @7f5514b32377 +0 8C020000 +[1cffd9ecbf8d] jit-backend-dump} +[1cffd9ecc51d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d63a2 +0 86020000 -[3304dee9db8] jit-backend-dump} -[3304deea2e6] {jit-backend-dump +CODE_DUMP @7f5514b323a2 +0 86020000 +[1cffd9eccee0] jit-backend-dump} +[1cffd9ecd33a] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6426 +0 27020000 -[3304deeac17] jit-backend-dump} -[3304deeb092] {jit-backend-dump +CODE_DUMP @7f5514b32426 +0 27020000 +[1cffd9ecdc8f] jit-backend-dump} +[1cffd9ece160] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d644f +0 48020000 -[3304deeb97f] jit-backend-dump} -[3304deec304] jit-backend} -[3304deed1f1] {jit-log-opt-loop +CODE_DUMP @7f5514b3244f +0 48020000 +[1cffd9eceab8] jit-backend-dump} +[1cffd9ecf545] jit-backend} +[1cffd9ed0c35] {jit-log-opt-loop # Loop 1 ( #13 FOR_ITER) : loop with 82 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -275,53 +275,53 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944753096184)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140003443320224)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+254: guard_class(p15, 25719440, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] ++244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++254: guard_class(p15, 26177128, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] +266: p21 = getfield_gc(p15, descr=) -+270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] +279: i22 = getfield_gc(p15, descr=) +283: p23 = getfield_gc(p21, descr=) -+287: guard_class(p23, 26050592, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++287: guard_class(p23, 26517736, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] +299: p25 = getfield_gc(p21, descr=) +303: i26 = getfield_gc_pure(p25, descr=) +307: i27 = getfield_gc_pure(p25, descr=) +311: i28 = getfield_gc_pure(p25, descr=) +315: i30 = int_lt(i22, 0) -guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +325: i31 = int_ge(i22, i28) -guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +334: i32 = int_mul(i22, i27) +341: i33 = int_add(i26, i32) +347: i35 = int_add(i22, 1) +351: setfield_gc(p15, i35, descr=) -+355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] ++355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_FAST') debug_merge_point(0, 0, ' #22 LIST_APPEND') +365: p37 = getfield_gc(p13, descr=) -+369: guard_class(p37, 25936304, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] ++369: guard_class(p37, 26402184, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] +382: p39 = getfield_gc(p13, descr=) +386: i40 = getfield_gc(p39, descr=) +390: i42 = int_add(i40, 1) +394: p43 = getfield_gc(p39, descr=) +394: i44 = arraylen_gc(p43, descr=) -+394: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i42, descr=) -+506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] ++394: call(ConstClass(_ll_list_resize_ge_trampoline__v672___simple_call__function__), p39, i42, descr=) ++506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] +521: p47 = getfield_gc(p39, descr=) +532: setarrayitem_gc(p47, i40, i33, descr=) debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') -+551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] -+551: i49 = getfield_raw(52008256, descr=) ++551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++551: i49 = getfield_raw(51804288, descr=) +559: i51 = int_lt(i49, 0) -guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] -+569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] +guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] debug_merge_point(0, 0, ' #13 FOR_ITER') -+595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(140003443320312)) debug_merge_point(0, 0, ' #13 FOR_ITER') +625: i53 = int_ge(i35, i28) -guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] +guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] +638: i54 = int_mul(i35, i27) +649: i55 = int_add(i26, i54) +655: i56 = int_add(i35, 1) @@ -332,25 +332,25 @@ +663: i58 = int_add(i57, 1) +667: p59 = getfield_gc(p39, descr=) +667: i60 = arraylen_gc(p59, descr=) -+667: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i58, descr=) ++667: call(ConstClass(_ll_list_resize_ge_trampoline__v672___simple_call__function__), p39, i58, descr=) +744: setfield_gc(p15, i56, descr=) -+755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] ++755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] +770: p61 = getfield_gc(p39, descr=) +781: setarrayitem_gc(p61, i57, i55, descr=) debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') -+793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] -+793: i62 = getfield_raw(52008256, descr=) ++793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] ++793: i62 = getfield_raw(51804288, descr=) +801: i63 = int_lt(i62, 0) -guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] +guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] debug_merge_point(0, 0, ' #13 FOR_ITER') -+811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(140003443320312)) +840: --end of the loop-- -[3304df359fe] jit-log-opt-loop} -[3304df6aed1] {jit-backend-counts +[1cffd9f27224] jit-log-opt-loop} +[1cffd9f6f244] {jit-backend-counts entry 0:1 -TargetToken(139944714371104):1 -TargetToken(139944714371192):4 +TargetToken(140003404595232):1 +TargetToken(140003404595320):4 entry 1:1 -TargetToken(139944753096184):1 -TargetToken(139944753096272):4 -[3304df6da3a] jit-backend-counts} +TargetToken(140003443320224):1 +TargetToken(140003443320312):4 +[1cffd9f72430] jit-backend-counts} From noreply at buildbot.pypy.org Wed Mar 20 01:52:33 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Mar 2013 01:52:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130320005233.BC11C1C04AB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62528:8688a5451f54 Date: 2013-03-19 17:52 -0700 http://bitbucket.org/pypy/pypy/changeset/8688a5451f54/ Log: merge default diff too long, truncating to 2000 out of 89406 lines 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 @@ -11,6 +11,8 @@ .. branch: callback-jit Callbacks from C are now better JITted +.. branch: fix-jit-logs + .. branch: remove-globals-in-jit .. branch: length-hint 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 @@ -17,9 +17,9 @@ return not dtype.itemtype.bool(val) class W_Ufunc(Wrappable): - _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", + _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex", "complex_to_float"] - _immutable_fields_ = ["promote_to_float", "promote_bools", "name", + _immutable_fields_ = ["promote_to_float", "promote_bools", "name", "allow_complex", "complex_to_float"] def __init__(self, name, promote_to_float, promote_bools, identity, @@ -151,13 +151,13 @@ assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) if obj.get_dtype().is_flexible_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() shapelen = len(obj_shape) - axis = unwrap_axis_arg(space, shapelen, w_axis) + axis = unwrap_axis_arg(space, shapelen, w_axis) assert axis >= 0 size = obj.get_size() dtype = interp_dtype.decode_w_dtype(space, dtype) @@ -256,7 +256,7 @@ out = None w_obj = convert_to_array(space, w_obj) if w_obj.get_dtype().is_flexible_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('Not implemented for this type')) if self.int_only and not w_obj.get_dtype().is_int_type(): raise OperationError(space.w_TypeError, space.wrap( @@ -281,7 +281,7 @@ if self.complex_to_float and calc_dtype.is_complex_type(): if calc_dtype.name == 'complex64': res_dtype = interp_dtype.get_dtype_cache(space).w_float32dtype - else: + else: res_dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if w_obj.is_scalar(): w_val = self.func(calc_dtype, @@ -304,7 +304,7 @@ argcount = 2 def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, comparison_func=False, int_only=False, + identity=None, comparison_func=False, int_only=False, allow_complex=True, complex_to_float=False): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, @@ -507,11 +507,11 @@ return current_guess elif space.isinstance_w(w_obj, space.w_str): if (current_guess is None): - return interp_dtype.variable_dtype(space, + return interp_dtype.variable_dtype(space, 'S%d' % space.len_w(w_obj)) elif current_guess.num ==18: if current_guess.itemtype.get_size() < space.len_w(w_obj): - return interp_dtype.variable_dtype(space, + return interp_dtype.variable_dtype(space, 'S%d' % space.len_w(w_obj)) return current_guess if current_guess is complex_type: @@ -588,7 +588,7 @@ ("negative", "neg", 1), ("absolute", "abs", 1, {"complex_to_float": True}), ("sign", "sign", 1, {"promote_bools": True}), - ("signbit", "signbit", 1, {"bool_result": True, + ("signbit", "signbit", 1, {"bool_result": True, "allow_complex": False}), ("reciprocal", "reciprocal", 1), ("conjugate", "conj", 1), @@ -599,7 +599,7 @@ "allow_complex": False}), ("fmax", "fmax", 2, {"promote_to_float": True}), ("fmin", "fmin", 2, {"promote_to_float": True}), - ("fmod", "fmod", 2, {"promote_to_float": True, + ("fmod", "fmod", 2, {"promote_to_float": True, 'allow_complex': False}), ("floor", "floor", 1, {"promote_to_float": True, "allow_complex": False}), diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -496,7 +496,7 @@ i10 = getfield_raw(..., descr=<.* pypysig_long_struct.c_value .*>) i14 = int_lt(i10, 0) guard_false(i14, descr=...) - jump(p0, p1, p2, p3, i8, descr=...) + jump(..., descr=...) """) # assert loop.match(""" @@ -504,7 +504,7 @@ guard_true(i6, descr=...) i8 = int_add(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i8, descr=...) + jump(..., descr=...) """) # py.test.raises(InvalidMatch, loop.match, """ @@ -512,7 +512,7 @@ guard_true(i6) i8 = int_add(i5, 1) # variable mismatch --TICK-- - jump(p0, p1, p2, p3, i8, descr=...) + jump(..., descr=...) """) def test_match_by_id(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_array.py b/pypy/module/pypyjit/test_pypy_c/test_array.py --- a/pypy/module/pypyjit/test_pypy_c/test_array.py +++ b/pypy/module/pypyjit/test_pypy_c/test_array.py @@ -22,7 +22,7 @@ guard_true(i7, descr=...) i9 = int_add(i5, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i9, i6, descr=...) + jump(..., descr=...) """) def test_array_sum(self): @@ -47,7 +47,7 @@ guard_no_overflow(descr=...) i18 = int_add(i7, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i18, i16, p8, i9, i10, descr=...) + jump(..., descr=...) """) def test_array_intimg(self): @@ -85,7 +85,7 @@ setarrayitem_raw(i11, i8, _, descr=) i28 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p5, p6, i28, i15, p9, i10, i11, descr=...) + jump(..., descr=...) """) def test_array_of_doubles(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py --- a/pypy/module/pypyjit/test_pypy_c/test_call.py +++ b/pypy/module/pypyjit/test_pypy_c/test_call.py @@ -101,7 +101,7 @@ i15 = int_add_ovf(i12, 1) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i15, i6, p7, p8, descr=...) + jump(..., descr=...) """) def test_method_call(self): @@ -144,7 +144,7 @@ i19 = int_add_ovf(i10, i17) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i19, p7, i17, i9, i10, p11, p12, p13, descr=...) + jump(..., descr=...) """) def test_static_classmethod_call(self): @@ -369,12 +369,12 @@ assert loop.match_by_id('call', opcode='CALL_FUNCTION', expected_src=""" # make sure that the "block" is not allocated ... - i20 = force_token() + p20 = force_token() p22 = new_with_vtable(...) p24 = new_array(1, descr=) p26 = new_with_vtable(ConstClass(W_ListObject)) {{{ - setfield_gc(p0, i20, descr=) + setfield_gc(p0, p20, descr=) setfield_gc(p22, 1, descr=) setfield_gc(p26, ConstPtr(ptr22), descr=) setarrayitem_gc(p24, 0, p26, descr=) @@ -467,7 +467,7 @@ p22 = new_with_vtable(ConstClass(W_IntObject)) setfield_gc(p22, i13, descr=) setfield_gc(p4, p22, descr=) - jump(p0, p1, p2, p3, p4, p7, p22, p7, descr=...) + jump(..., descr=...) """) def test_kwargs_virtual(self): 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 @@ -115,7 +115,7 @@ i35 = int_add_ovf(i5, i34) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i35, p13, i7, descr=...) + jump(..., descr=...) """) def test_floatlist_unpack_without_calls(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py --- a/pypy/module/pypyjit/test_pypy_c/test_instance.py +++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py @@ -27,7 +27,7 @@ i9 = int_add_ovf(i5, 2) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i9, i6, descr=...) + jump(..., descr=...) """) def test_load_attr(self): @@ -52,7 +52,7 @@ i10 = int_add_ovf(i5, i7) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, i10, i6, i7, p8, descr=...) + jump(..., descr=...) """) def test_getattr_with_dynamic_attribute(self): @@ -127,7 +127,7 @@ p20 = new_with_vtable(ConstClass(W_IntObject)) setfield_gc(p20, i11, descr=) setfield_gc(ConstPtr(ptr21), p20, descr=) - jump(p0, p1, p2, p3, p4, p20, p6, i7, p20, descr=...) + jump(..., descr=...) """) def test_oldstyle_newstyle_mix(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_intbound.py b/pypy/module/pypyjit/test_pypy_c/test_intbound.py --- a/pypy/module/pypyjit/test_pypy_c/test_intbound.py +++ b/pypy/module/pypyjit/test_pypy_c/test_intbound.py @@ -97,7 +97,7 @@ guard_no_overflow(descr=...) i17 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i14, i12, i17, p8, i9, descr=...) + jump(..., descr=...) """) def test_intbound_sub_lt(self): @@ -121,7 +121,7 @@ guard_no_overflow(descr=...) i13 = int_add(i5, 1) --TICK-- - jump(p0, p1, p2, p3, i11, i13, descr=...) + jump(..., descr=...) """) def test_intbound_addsub_ge(self): @@ -150,7 +150,7 @@ guard_no_overflow(descr=...) i19 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i16, i14, i19, p8, i9, descr=...) + jump(..., descr=...) """) def test_intbound_addmul_ge(self): @@ -178,7 +178,7 @@ guard_no_overflow(descr=...) i21 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i18, i14, i21, p8, descr=...) + jump(..., descr=...) """) def test_intbound_eq(self): @@ -210,7 +210,7 @@ guard_no_overflow(descr=...) i16 = int_add(i8, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p6, i14, i16, p8, descr=...) + jump(..., descr=...) """) def test_intbound_mul(self): @@ -236,7 +236,7 @@ guard_no_overflow(descr=...) i14 = int_add(i6, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i12, i14, descr=...) + jump(..., descr=...) """) def test_assert(self): @@ -257,7 +257,7 @@ guard_no_overflow(descr=...) i12 = int_add(i6, 1) --TICK-- - jump(p0, p1, p2, p3, p4, i10, i12, descr=...) + jump(..., descr=...) """) def test_xor(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_min_max.py b/pypy/module/pypyjit/test_pypy_c/test_min_max.py --- a/pypy/module/pypyjit/test_pypy_c/test_min_max.py +++ b/pypy/module/pypyjit/test_pypy_c/test_min_max.py @@ -22,7 +22,7 @@ guard_no_overflow(descr=...) i11 = int_add(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i11, i9, descr=...) + jump(..., descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -31,7 +31,7 @@ i13 = int_add_ovf(i6, i12) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i13, i11, i8, descr=...) + jump(..., descr=...) """ assert loop0.match(expected) # XXX: The retracing fails to form a loop since j @@ -56,7 +56,7 @@ guard_no_overflow(descr=...) i10 = int_sub(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i10, i8, descr=...) + jump(..., descr=...) """) # log = self.run(fact, [25], threshold=20) @@ -71,7 +71,7 @@ guard_no_exception(descr=...) i13 = int_sub(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i13, p11, descr=...) + jump(..., descr=...) """) @@ -91,7 +91,7 @@ guard_true(i9, descr=...) f10 = float_add(f8, f5) --TICK-- - jump(p0, p1, p2, p3, p4, f10, p6, f7, f8, descr=...) + jump(..., descr=...) """) @@ -252,7 +252,7 @@ i28 = int_add_ovf(i10, i25) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, p6, i28, i25, p9, p10, p11, p12, i19, descr=...) + jump(..., descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -49,7 +49,7 @@ guard_true(i32, descr=...) i34 = int_add(i6, 1) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i34, p7, p8, i9, i10, p11, i12, p13, descr=...) + jump(..., descr=...) """ % (-sys.maxint-1, SHIFT)) def test_long(self): @@ -115,7 +115,7 @@ i58 = int_add_ovf(i6, i57) guard_no_overflow(descr=...) --TICK-- - jump(p0, p1, p2, p3, p4, p5, i58, i7, descr=...) + jump(..., descr=...) """ % (-sys.maxint-1, SHIFT)) def test_str_mod(self): @@ -164,7 +164,7 @@ guard_no_overflow(descr=...) i40 = int_sub(i4, 1) --TICK-- - jump(p0, p1, p2, p3, i40, i38, descr=...) + jump(..., descr=...) """) def test_getattr_promote(self): diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py b/pypy/module/pypyjit/test_pypy_c/test_thread.py --- a/pypy/module/pypyjit/test_pypy_c/test_thread.py +++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py @@ -46,5 +46,5 @@ guard_no_overflow(descr=...) --TICK-- i58 = arraylen_gc(p43, descr=...) - jump(p0, p1, p3, p5, p10, p12, p14, i54, i27, i47, p45, p43, descr=...) + jump(..., descr=...) """) diff --git a/pypy/module/termios/test/test_termios.py b/pypy/module/termios/test/test_termios.py --- a/pypy/module/termios/test/test_termios.py +++ b/pypy/module/termios/test/test_termios.py @@ -42,7 +42,8 @@ child.expect('attr= (\[.*?\[.*?\]\])') lst = eval(child.match.group(1)) assert len(lst) == 7 - assert len(lst[-1]) == 32 # XXX is this portable??? + # Length of the last element is 32 on Linux, 20 on MacOSX. + assert len(lst[-1]) in (20, 32) def test_tcall(self): """ Again - a test that doesnt really test anything @@ -63,10 +64,16 @@ child.expect('ok!') def test_tcsetattr(self): + # The last element of the third parameter for termios.tcsetattr() + # can't be a constant, because it varies from one OS to another. + # (Its length must be 32 on Linux, 20 on MacOSX, for example.) + # Use termios.tcgetattr() to get a value that will hopefully be + # valid for whatever OS we are running on right now. source = py.code.Source(""" import sys import termios - termios.tcsetattr(sys.stdin, 1, [16640, 4, 191, 2608, 15, 15, [b'\x03', b'\x1c', b'\x7f', b'\x15', b'\x04', 0, 1, b'\x00', b'\x11', b'\x13', b'\x1a', b'\x00', b'\x12', b'\x0f', b'\x17', b'\x16', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00']]) + cc = termios.tcgetattr(sys.stdin)[-1] + termios.tcsetattr(sys.stdin, 1, [16640, 4, 191, 2608, 15, 15, cc]) print('ok!') """) f = udir.join("test_tcsetattr.py") diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -364,16 +364,17 @@ def import_log(logname, ParserCls=SimpleParser): log = parse_log_file(logname) + hex_re = '0x([\da-f]+)' addrs = {} for entry in extract_category(log, 'jit-backend-addr'): - m = re.search('bootstrap ([-\da-f]+)', entry) + m = re.search('bootstrap ' + hex_re, entry) if not m: # a bridge - m = re.search('has address ([-\da-f]+)', entry) + m = re.search('has address ' + hex_re, entry) addr = int(m.group(1), 16) entry = entry.lower() - m = re.search('guard [\da-f]+', entry) - name = m.group(0) + m = re.search('guard ' + hex_re, entry) + name = 'guard ' + m.group(1) else: name = entry[:entry.find('(') - 1].lower() addr = int(m.group(1), 16) @@ -395,8 +396,8 @@ comm = loop.comment comm = comm.lower() if comm.startswith('# bridge'): - m = re.search('guard (\d+)', comm) - name = 'guard ' + hex(int(m.group(1)))[2:] + m = re.search('guard ([\da-f]+)', comm) + name = 'guard ' + m.group(1) elif "(" in comm: name = comm[2:comm.find('(')-1] else: @@ -414,7 +415,8 @@ def split_trace(trace): labels = [0] if trace.comment and 'Guard' in trace.comment: - descrs = ['bridge ' + re.search('Guard ([\da-f]+)', trace.comment).group(1)] + descrs = ['bridge %d' % int( + re.search('Guard 0x([\da-f]+)', trace.comment).group(1), 16)] else: descrs = ['entry ' + re.search('Loop (\d+)', trace.comment).group(1)] for i, op in enumerate(trace.operations): diff --git a/pypy/tool/jitlogparser/storage.py b/pypy/tool/jitlogparser/storage.py --- a/pypy/tool/jitlogparser/storage.py +++ b/pypy/tool/jitlogparser/storage.py @@ -70,7 +70,7 @@ if 'entry bridge' in comment: pass elif comment.startswith('# bridge out of'): - no = int(comment[len('# bridge out of Guard '):].split(' ', 1)[0], 16) + no = int(comment[len('# bridge out of Guard 0x'):].split(' ', 1)[0], 16) op, parent = guard_dict[no] op.bridge = loop op.percentage = ((getattr(loop, 'count', 1) * 100) / diff --git a/pypy/tool/jitlogparser/test/logtest.log b/pypy/tool/jitlogparser/test/logtest.log --- a/pypy/tool/jitlogparser/test/logtest.log +++ b/pypy/tool/jitlogparser/test/logtest.log @@ -5,7 +5,7 @@ CODE_DUMP @7f3b0b2e63d5 +0 554889E5534154415541564157488DA500000000488B042590C5540148C7042590C554010000000048898570FFFFFF488B042598C5540148C7042598C554010000000048898568FFFFFF488B0425A0C5540148C70425A0C554010000000048898560FFFFFF488B0425A8C5540148C70425A8C554010000000048898558FFFFFF4C8B3C2550525B0149BB3050920D3B7F00004D8B334983C60149BB3050920D3B7F00004D89334981FF102700000F8D000000004983C7014C8B342580F76A024983EE014C89342580F76A024983FE000F8C00000000E9AEFFFFFF488B042588F76A024829E0483B042580EC3C01760D49BB05632E0B3B7F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E954FFFFFF49BB00602E0B3B7F000041FFD34440484C3D030300000049BB00602E0B3B7F000041FFD34440484C3D070304000000 [11f210b949b3] jit-backend-dump} [11f210b949b4] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 7f3b0b2e645d to 7f3b0b2e64af (bootstrap 7f3b0b2e63d5) +Loop 0 ( #9 LOAD_FAST) has address 0x7f3b0b2e645d to 0x7f3b0b2e64af (bootstrap 0x7f3b0b2e63d5) [11f210bab188] jit-backend-addr} [11f210bab189] jit-backend} [11f210bacbb7] {jit-log-opt-loop diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -1,301 +1,356 @@ -[1f5e7f69779] {jit-backend-dump +[3304d0bb187] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b000 +0 4157415641554154415341524151415057565554535251504889E349C7C340BC920041FFD34889DF4883E4F049C7C350BC920041FFD3488D65D8415F415E415D415C5B5DC3 -[1f5e7f7fe75] jit-backend-dump} -[1f5e7f84fc4] {jit-backend-dump +CODE_DUMP @7f476a7d5000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[3304d0ca602] jit-backend-dump} +[3304d0cfdf4] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b045 +0 4157415641554154415341524151415057565554535251504889E349C7C3F0BB920041FFD34889DF4883E4F049C7C350BC920041FFD3488D65D8415F415E415D415C5B5DC3 -[1f5e7f87ac1] jit-backend-dump} -[1f5e7f8a0b4] {jit-backend-dump +CODE_DUMP @7f476a7d5085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[3304d0d2b27] jit-backend-dump} +[3304d0d73d6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b08a +0 4157415641554154415341524151415057565554535251504889E34881EC80000000F20F110424F20F114C2408F20F11542410F20F115C2418F20F11642420F20F116C2428F20F11742430F20F117C2438F2440F11442440F2440F114C2448F2440F11542450F2440F115C2458F2440F11642460F2440F116C2468F2440F11742470F2440F117C247849C7C340BC920041FFD34889DF4883E4F049C7C350BC920041FFD3488D65D8415F415E415D415C5B5DC3 -[1f5e7f8da6b] jit-backend-dump} -[1f5e7f8f4f6] {jit-backend-dump +CODE_DUMP @7f476a7d512e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[3304d0d9073] jit-backend-dump} +[3304d0db1d8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b13d +0 4157415641554154415341524151415057565554535251504889E34881EC80000000F20F110424F20F114C2408F20F11542410F20F115C2418F20F11642420F20F116C2428F20F11742430F20F117C2438F2440F11442440F2440F114C2448F2440F11542450F2440F115C2458F2440F11642460F2440F116C2468F2440F11742470F2440F117C247849C7C3F0BB920041FFD34889DF4883E4F049C7C350BC920041FFD3488D65D8415F415E415D415C5B5DC3 -[1f5e7f92b83] jit-backend-dump} -[1f5e7f95b99] {jit-backend-dump +CODE_DUMP @7f476a7d5191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[3304d0dce9e] jit-backend-dump} +[3304d0dfc06] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b210 +0 F20F11442410F20F114C2418F20F11542420F20F115C2428F20F11642430F20F116C2438F20F11742440F20F117C2448F2440F11442450F2440F114C2458F2440F11542460F2440F115C2468F2440F11642470F2440F116C2478F2440F11B42480000000F2440F11BC24880000004829C24889D749C7C350A8920041FFE3 -[1f5e7f988d0] jit-backend-dump} -[1f5e7fa16fb] {jit-backend-dump +CODE_DUMP @7f476a7d51fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C25C80219034C8B2425C002190348C70425C00219030000000048C70425C80219030000000041BBC069120141FFD3F20F10442418488B44240848891C25C80219034C892425C0021903488B5C24284C8B642430488D642438C3 +[3304d0e1a04] jit-backend-dump} +[3304d0e4ae5] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b28e +0 F20F10442410F20F104C2418F20F10542420F20F105C2428F20F10642430F20F106C2438F20F10742440F20F107C2448F2440F10442450F2440F104C2458F2440F10542460F2440F105C2468F2440F10642470F2440F106C2478F2440F10B42480000000F2440F10BC2488000000488B1425704F3D01C3 -[1f5e7fa47ac] jit-backend-dump} -[1f5e7fab3a4] {jit-backend-dump +CODE_DUMP @7f476a7d5275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C25C802190348894D38488B1C25C002190348C70425C00219030000000048C70425C80219030000000041BB90E3E80041FFD34889C5488B4D3848C745380000000048890C25C802190348891C25C00219034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[3304d0e9130] jit-backend-dump} +[3304d0ea4a1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b305 +0 57565251415041514883EC40F20F110424F20F114C2408F20F11542410F20F115C2418F20F11642420F20F116C2428F20F11742430F20F117C2438488D7D1049C7C340BA520041FFD3488B042550546B024885C0753CF20F107C2438F20F10742430F20F106C2428F20F10642420F20F105C2418F20F10542410F20F104C2408F20F1004244883C44041594158595A5E5FC3488B042558546B0248C7042550546B020000000048C7042558546B02000000004889042590C2540149C7C340BC920041FFD348C7C0020000004883C478C3 -[1f5e7faf1ca] jit-backend-dump} -[1f5e7fb0813] {jit-backend-counts -[1f5e7fb0f61] jit-backend-counts} -[1f5fd38be3e] {jit-backend -[1f5fe729336] {jit-backend-dump +CODE_DUMP @7f476a7d5491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[3304d0ecf16] jit-backend-dump} +[3304d0ee1ff] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b3d5 +0 554889E5534154415541564157488DA500000000488B042590C2540148C7042590C254010000000048898570FFFFFF488B042598C2540148C7042598C254010000000048898568FFFFFF488B0425A0C2540148C70425A0C254010000000048898560FFFFFF488B0425A8C2540148C70425A8C254010000000048898558FFFFFF4C8B3C25D04D5B0149BB30B00C0A897F00004D8B334983C60149BB30B00C0A897F00004D89334981FF102700000F8D000000004D89FE4983E7024983FF000F85000000004983C6034C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C000000004D89F7E99AFFFFFF488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E940FFFFFF49BB00B0A007897F000041FFD34440484C3D030300000049BB00B0A007897F000041FFD34440484C3D39030400000049BB00B0A007897F000041FFD34440484C3907070305000000 -[1f5fe73276a] jit-backend-dump} -[1f5fe73438f] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 7f8907a0b45d to 7f8907a0b4c3 (bootstrap 7f8907a0b3d5) -[1f5fe7369af] jit-backend-addr} -[1f5fe737940] {jit-backend-dump +CODE_DUMP @7f476a7d5595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[3304d0fca06] jit-backend-dump} +[3304d0fe4ac] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b3e5 +0 50FFFFFF -[1f5fe74b40e] jit-backend-dump} -[1f5fe74c63d] {jit-backend-dump +CODE_DUMP @7f476a7d56bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[3304d1018ac] jit-backend-dump} +[3304d103089] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b484 +0 95000000 -[1f5fe74da6a] jit-backend-dump} -[1f5fe74e438] {jit-backend-dump +CODE_DUMP @7f476a7d581e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[3304d1062c0] jit-backend-dump} +[3304d1072c1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b495 +0 9B000000 -[1f5fe74f513] jit-backend-dump} -[1f5fe74fd2e] {jit-backend-dump +CODE_DUMP @7f476a7d5988 +0 488B0425C802190348C70425C00219030000000048C70425C8021903000000004889453848C745108064B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[3304d1089ec] jit-backend-dump} +[3304d11572c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b4b7 +0 91000000 -[1f5fe750d8c] jit-backend-dump} -[1f5fe75373f] jit-backend} -[1f5fe755abc] {jit-log-opt-loop -# Loop 0 : loop with 26 ops -[p0, p1, p2, p3, i4] -debug_merge_point(0, ' #9 LOAD_FAST') -debug_merge_point(0, ' #12 LOAD_CONST') -debug_merge_point(0, ' #15 COMPARE_OP') -+166: i6 = int_lt(i4, 10000) -guard_true(i6, descr=) [p1, p0, p2, p3, i4] -debug_merge_point(0, ' #18 POP_JUMP_IF_FALSE') -debug_merge_point(0, ' #21 LOAD_FAST') -debug_merge_point(0, ' #24 LOAD_CONST') -debug_merge_point(0, ' #27 BINARY_AND') -+179: i8 = int_and(i4, 2) -debug_merge_point(0, ' #28 POP_JUMP_IF_FALSE') -+186: i9 = int_is_true(i8) -guard_false(i9, descr=) [p1, p0, p2, p3, i8, i4] -debug_merge_point(0, ' #44 LOAD_FAST') -debug_merge_point(0, ' #47 LOAD_CONST') -debug_merge_point(0, ' #50 INPLACE_ADD') -+196: i11 = int_add(i4, 3) -debug_merge_point(0, ' #51 STORE_FAST') -debug_merge_point(0, ' #54 JUMP_ABSOLUTE') -+200: i13 = getfield_raw(40588192, descr=) -+208: i15 = int_sub(i13, 1) -+212: setfield_raw(40588192, i15, descr=) -+220: i17 = int_lt(i15, 0) -guard_false(i17, descr=) [p1, p0, p2, p3, i11, None, None] -debug_merge_point(0, ' #9 LOAD_FAST') -+230: jump(p0, p1, p2, p3, i11, descr=) -+238: --end of the loop-- -[1f5fe92b8af] jit-log-opt-loop} -[1f5fe944ae5] {jit-backend -[1f5fee20651] {jit-backend-dump +CODE_DUMP @7f476a7d59e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBF0ACE80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD517D6A477F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25C8EEB50148C7452000000000C34883C40849BB88597D6A477F000041FFE3 +[3304d120245] jit-backend-dump} +[3304d122916] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b565 +0 554889E5534154415541564157488DA5000000004C8B3C2590C2540148C7042590C25401000000004C8B342598C2540148C7042598C25401000000004C8B2C25A0C2540148C70425A0C25401000000004C8B2425A8C2540148C70425A8C25401000000004C8B1425D04D5B014C8B0C25B8C2540148C70425B8C25401000000004C8B0425E04D5B01488B3C25E84D5B01488B3425D0C2540148C70425D0C2540100000000488B1C25D8C2540148C70425D8C2540100000000488B1425E0C2540148C70425E0C254010000000049BB38B00C0A897F0000498B0B4883C10149BB38B00C0A897F000049890B4983F8010F85000000004883FE017206813E980700000F85000000004983FA000F850000000049BBA8F0B407897F00004D39DC0F8500000000488B56084881FA102700000F8D000000004989D44883E2024883FA000F85000000004983C403488B1425A0536B024883EA0148891425A0536B024883FA000F8C000000004C89BD70FFFFFF4C89B568FFFFFF4C89AD60FFFFFF4C898D58FFFFFF4D89E749BB5DB4A007897F000041FFE3488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4989FF4989F64989D54989CC4D89C24C8B5D104D89D84C8B5D184C89DF4C8B5D204C89DE4C8B5D284C89DB4C8B5D304C89DAE9CCFEFFFF49BB00B0A007897F000041FFD321383C343029241D180C08030600000049BB00B0A007897F000041FFD3383C18343029240C08030700000049BB00B0A007897F000041FFD329383C3430241808030800000049BB00B0A007897F000041FFD3383C3034241808030900000049BB00B0A007897F000041FFD3383C183424030A00000049BB00B0A007897F000041FFD3383C34241809030B00000049BB00B0A007897F000041FFD3383C34243107030C000000 -[1f5fee2e673] jit-backend-dump} -[1f5fee2f38d] {jit-backend-addr -Loop 1 ( #9 LOAD_FAST) has address 7f8907a0b631 to 7f8907a0b6f8 (bootstrap 7f8907a0b565) -[1f5fee312e3] jit-backend-addr} -[1f5fee320ed] {jit-backend-dump +CODE_DUMP @7f476a7d5bd6 +0 4889E74883EC0841BB9018210141FFD34883C408488B0425C00219034885C07501C34883C40849BB88597D6A477F000041FFE3 +[3304d1240c0] jit-backend-dump} +[3304d1246a0] {jit-backend-counts +[3304d124ab0] jit-backend-counts} +[3304d690a50] {jit-backend +[3304db64ec0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b575 +0 50FFFFFF -[1f5fee3e903] jit-backend-dump} -[1f5fee3fbff] {jit-backend-dump +CODE_DUMP @7f476a7d5ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBF0905D6D477F00004D8B3B4D8D770149BBF0905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08915D6D477F0000498B0B488D410149BB08915D6D477F00004989034983F8020F85000000004883FB017206813B680B00000F85000000004983FA000F850000000049BB20C0FC6A477F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425409519034983FC000F8C0000000049BB20915D6D477F00004D8B234D8D54240149BB20915D6D477F00004D89134883FB0A0F8D000000004C8D5301488B1C25409519034883FB000F8C000000004C89D3E9B9FFFFFF49BB2020FD6A477F0000415349BB405C7D6A477F0000415349BB00507D6A477F000041FFE349BB3806036B477F0000415349BB505C7D6A477F0000415349BB00507D6A477F000041FFE349BBC005036B477F0000415349BB605C7D6A477F0000415349BB00507D6A477F000041FFE349BB4805036B477F0000415349BB705C7D6A477F0000415349BB00507D6A477F000041FFE349BBD004036B477F0000415349BB805C7D6A477F0000415349BB00507D6A477F000041FFE349BB5804036B477F0000415349BB905C7D6A477F0000415349BB00507D6A477F000041FFE349BBE003036B477F0000415349BBA05C7D6A477F0000415349BB00507D6A477F000041FFE349BB6803036B477F0000415349BBB05C7D6A477F0000415349BB00507D6A477F000041FFE349BBF002036B477F0000415349BBC05C7D6A477F0000415349BB00507D6A477F000041FFE349BB7802036B477F0000415349BBD05C7D6A477F0000415349BB00507D6A477F000041FFE3 +[3304db7d5e4] jit-backend-dump} +[3304db7df74] {jit-backend-addr +Loop 0 ( #9 LOAD_FAST) has address 0x7f476a7d5d30 to 0x7f476a7d5e80 (bootstrap 0x7f476a7d5ce0) +[3304db7f906] jit-backend-addr} +[3304db8036d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b655 +0 0C010000 -[1f5fee41579] jit-backend-dump} -[1f5fee421af] {jit-backend-dump +CODE_DUMP @7f476a7d5de1 +0 9B000000 +[3304db81160] jit-backend-dump} +[3304db81772] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b667 +0 17010000 -[1f5fee43835] jit-backend-dump} -[1f5fee44261] {jit-backend-dump +CODE_DUMP @7f476a7d5df3 +0 AE000000 +[3304db8217a] jit-backend-dump} +[3304db825e3] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b671 +0 28010000 -[1f5fee457c1] jit-backend-dump} -[1f5fee461a5] {jit-backend-dump +CODE_DUMP @7f476a7d5dfd +0 C9000000 +[3304db82ee8] jit-backend-dump} +[3304db83330] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b684 +0 2F010000 -[1f5fee475d3] jit-backend-dump} -[1f5fee47f57] {jit-backend-dump +CODE_DUMP @7f476a7d5e10 +0 DB000000 +[3304db83c9d] jit-backend-dump} +[3304db840c2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b695 +0 37010000 -[1f5fee4933d] jit-backend-dump} -[1f5fee49cd9] {jit-backend-dump +CODE_DUMP @7f476a7d5e1e +0 F2000000 +[3304db849f0] jit-backend-dump} +[3304db84f62] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b6a6 +0 3D010000 -[1f5fee4b0ad] jit-backend-dump} -[1f5fee4ba4f] {jit-backend-dump +CODE_DUMP @7f476a7d5e35 +0 25010000 +[3304db8586f] jit-backend-dump} +[3304db85c9d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b6c8 +0 33010000 -[1f5fee4cf61] jit-backend-dump} -[1f5fee4dc45] jit-backend} -[1f5fee4f3a9] {jit-log-opt-loop -# Loop 1 : entry bridge with 31 ops -[p0, p1, p2, p3, i4, p5, i6, i7, p8, p9, p10] -debug_merge_point(0, ' #9 LOAD_FAST') -+234: guard_value(i6, 1, descr=) [i6, p1, p0, p2, p3, i4, p5, i7, p8, p9, p10] -+244: guard_nonnull_class(p8, ConstClass(W_IntObject), descr=) [p1, p0, p8, p2, p3, i4, p5, p9, p10] -+262: guard_value(i4, 0, descr=) [i4, p1, p0, p2, p3, p5, p8, p10] -debug_merge_point(0, ' #12 LOAD_CONST') -+272: guard_value(p3, ConstPtr(ptr14), descr=) [p1, p0, p3, p2, p5, p8, p10] -debug_merge_point(0, ' #15 COMPARE_OP') -+291: i15 = getfield_gc_pure(p8, descr=) -+295: i17 = int_lt(i15, 10000) -guard_true(i17, descr=) [p1, p0, p8, p2, p5] -debug_merge_point(0, ' #18 POP_JUMP_IF_FALSE') -debug_merge_point(0, ' #21 LOAD_FAST') -debug_merge_point(0, ' #24 LOAD_CONST') -debug_merge_point(0, ' #27 BINARY_AND') -+308: i19 = int_and(i15, 2) -debug_merge_point(0, ' #28 POP_JUMP_IF_FALSE') -+315: i20 = int_is_true(i19) -guard_false(i20, descr=) [p1, p0, p2, p5, p8, i19] -debug_merge_point(0, ' #44 LOAD_FAST') -debug_merge_point(0, ' #47 LOAD_CONST') -debug_merge_point(0, ' #50 INPLACE_ADD') -+325: i22 = int_add(i15, 3) -debug_merge_point(0, ' #51 STORE_FAST') -debug_merge_point(0, ' #54 JUMP_ABSOLUTE') -+329: i24 = getfield_raw(40588192, descr=) -+337: i26 = int_sub(i24, 1) -+341: setfield_raw(40588192, i26, descr=) -+349: i28 = int_lt(i26, 0) -guard_false(i28, descr=) [p1, p0, p2, p5, i22, None] -debug_merge_point(0, ' #9 LOAD_FAST') -+359: jump(p0, p1, p2, p5, i22, descr=) -+403: --end of the loop-- -[1f60036d952] jit-log-opt-loop} -[1f600719a74] {jit-backend -[1f600759dac] {jit-backend-dump +CODE_DUMP @7f476a7d5e5e +0 21010000 +[3304db86572] jit-backend-dump} +[3304db869e7] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b817 +0 554889E5534154415541564157488DA500000000488B042590C2540148C7042590C254010000000048898570FFFFFF488B042598C2540148C7042598C254010000000048898568FFFFFF488B0425A0C2540148C70425A0C254010000000048898560FFFFFF488B0425A8C2540148C70425A8C254010000000048898558FFFFFF4C8B3C25D04D5B0149BB40B00C0A897F00004D8B334983C60149BB40B00C0A897F00004D89334981FF102700000F8D000000004D89FE4983E7024983FF000F85000000004983C6034C8B3C25A0536B024983EF024C893C25A0536B024983FF000F8C000000004D89F7E99AFFFFFF488B0425A8536B024829E0483B042580DC3C01760D49BB05B3A007897F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E940FFFFFF49BB00B0A007897F000041FFD34440484C3D030D00000049BB00B0A007897F000041FFD34440484C3D39030E00000049BB00B0A007897F000041FFD34440484C390707030F000000 -[1f60076fd90] jit-backend-dump} -[1f600770f30] {jit-backend-addr -Loop 2 ( #9 LOAD_FAST) has address 7f8907a0b89f to 7f8907a0b905 (bootstrap 7f8907a0b817) -[1f6007730fc] jit-backend-addr} -[1f600773fde] {jit-backend-dump +CODE_DUMP @7f476a7d5e74 +0 55010000 +[3304db872e3] jit-backend-dump} +[3304db88112] jit-backend} +[3304db8ae6c] {jit-log-opt-loop +# Loop 0 ( #9 LOAD_FAST) : loop with 59 ops +[p0, p1] ++110: p2 = getfield_gc(p0, descr=) ++124: p3 = getfield_gc(p0, descr=) ++128: p4 = getfield_gc(p0, descr=) ++132: i5 = getfield_gc(p0, descr=) ++140: p6 = getfield_gc(p0, descr=) ++144: i7 = getfield_gc(p0, descr=) ++148: i8 = getfield_gc(p0, descr=) ++152: p9 = getfield_gc(p0, descr=) ++156: p11 = getarrayitem_gc(p9, 0, descr=) ++160: p13 = getarrayitem_gc(p9, 1, descr=) ++164: p15 = getarrayitem_gc(p9, 2, descr=) ++168: p17 = getarrayitem_gc(p9, 3, descr=) ++172: p18 = getfield_gc(p0, descr=) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944714371104)) +debug_merge_point(0, 0, ' #9 LOAD_FAST') ++251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] ++279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] +debug_merge_point(0, 0, ' #12 LOAD_CONST') ++289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] +debug_merge_point(0, 0, ' #15 COMPARE_OP') ++308: i23 = getfield_gc_pure(p11, descr=) ++312: i25 = int_lt(i23, 10) +guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] +debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') +debug_merge_point(0, 0, ' #21 LOAD_CONST') +debug_merge_point(0, 0, ' #24 STORE_FAST') +debug_merge_point(0, 0, ' #27 LOAD_FAST') +debug_merge_point(0, 0, ' #30 LOAD_CONST') +debug_merge_point(0, 0, ' #33 INPLACE_ADD') ++322: i27 = int_add(i23, 1) +debug_merge_point(0, 0, ' #34 STORE_FAST') +debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') ++327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] ++327: i29 = getfield_raw(52008256, descr=) ++335: i31 = int_lt(i29, 0) +guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] +debug_merge_point(0, 0, ' #9 LOAD_FAST') ++345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(139944714371192)) +debug_merge_point(0, 0, ' #9 LOAD_FAST') +debug_merge_point(0, 0, ' #12 LOAD_CONST') +debug_merge_point(0, 0, ' #15 COMPARE_OP') ++376: i32 = int_lt(i27, 10) +guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] +debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') +debug_merge_point(0, 0, ' #21 LOAD_CONST') +debug_merge_point(0, 0, ' #24 STORE_FAST') +debug_merge_point(0, 0, ' #27 LOAD_FAST') +debug_merge_point(0, 0, ' #30 LOAD_CONST') +debug_merge_point(0, 0, ' #33 INPLACE_ADD') ++386: i33 = int_add(i27, 1) +debug_merge_point(0, 0, ' #34 STORE_FAST') +debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') ++390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] ++390: i35 = getfield_raw(52008256, descr=) ++398: i36 = int_lt(i35, 0) +guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] +debug_merge_point(0, 0, ' #9 LOAD_FAST') ++408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(139944714371192)) ++416: --end of the loop-- +[3304dc0f6eb] jit-log-opt-loop} +[3304ddc81da] {jit-backend +[3304dec8bed] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b827 +0 50FFFFFF -[1f600775c76] jit-backend-dump} -[1f600776a38] {jit-backend-dump +CODE_DUMP @7f476a7d6128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBD8905D6D477F00004D8B3B4D8D770149BBD8905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38915D6D477F0000498B0B488D590149BB38915D6D477F000049891B4983F8030F85000000008138704500000F85000000004C8B40104D85C00F8400000000488B5808498B48108139005305000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A909403000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB88607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C745200000000048833C25C0021903000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425409519034883F8000F8C00000000488B856801000049BB588C026B477F00004C39D80F850000000049BB50915D6D477F00004D8B13498D420149BB50915D6D477F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE8607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C74520000000004C8B958001000049895A0848833C25C0021903000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25409519034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0D6496D477F0000415349BB08607D6A477F0000415349BB00507D6A477F000041FFE349BB708A4D6D477F0000415349BB18607D6A477F0000415349BB00507D6A477F000041FFE349BBF8894D6D477F0000415349BB28607D6A477F0000415349BB00507D6A477F000041FFE349BB80894D6D477F0000415349BB38607D6A477F0000415349BB00507D6A477F000041FFE349BB08894D6D477F0000415349BB48607D6A477F0000415349BB00507D6A477F000041FFE349BB90884D6D477F0000415349BB58607D6A477F0000415349BB00507D6A477F000041FFE349BB18884D6D477F0000415349BB68607D6A477F0000415349BB00507D6A477F000041FFE349BBA0874D6D477F0000415349BB78607D6A477F0000415349BB00507D6A477F000041FFE349BB28874D6D477F0000415349BB98607D6A477F0000415349BB85507D6A477F000041FFE349BBB0864D6D477F0000415349BBA8607D6A477F0000415349BB00507D6A477F000041FFE349BB38864D6D477F0000415349BBB8607D6A477F0000415349BB00507D6A477F000041FFE349BBC0854D6D477F0000415349BBC8607D6A477F0000415349BB00507D6A477F000041FFE349BB48854D6D477F0000415349BBD8607D6A477F0000415349BB00507D6A477F000041FFE349BBD0844D6D477F0000415349BBF8607D6A477F0000415349BB85507D6A477F000041FFE349BB58844D6D477F0000415349BB08617D6A477F0000415349BB00507D6A477F000041FFE349BBE0834D6D477F0000415349BB18617D6A477F0000415349BB00507D6A477F000041FFE3 +[3304dedb0c9] jit-backend-dump} +[3304dedb9eb] {jit-backend-addr +Loop 1 ( #13 FOR_ITER) has address 0x7f476a7d6178 to 0x7f476a7d6470 (bootstrap 0x7f476a7d6128) +[3304dedcbfe] jit-backend-addr} +[3304dedd31e] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b8c6 +0 95000000 -[1f600778112] jit-backend-dump} -[1f600778b8c] {jit-backend-dump +CODE_DUMP @7f476a7d6222 +0 4A020000 +[3304dede364] jit-backend-dump} +[3304dede8d3] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b8d7 +0 9B000000 -[1f60077a04a] jit-backend-dump} -[1f60077aa6a] {jit-backend-dump +CODE_DUMP @7f476a7d622e +0 63020000 +[3304dedf2ce] jit-backend-dump} +[3304dedf728] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b8f9 +0 91000000 -[1f60077bf10] jit-backend-dump} -[1f60077cc24] jit-backend} -[1f60077e094] {jit-log-opt-loop -# Loop 2 : loop with 25 ops -[p0, p1, p2, p3, i4] -debug_merge_point(0, ' #12 LOAD_CONST') -debug_merge_point(0, ' #15 COMPARE_OP') -+166: i6 = int_lt(i4, 10000) -guard_true(i6, descr=) [p1, p0, p2, p3, i4] -debug_merge_point(0, ' #18 POP_JUMP_IF_FALSE') -debug_merge_point(0, ' #21 LOAD_FAST') -debug_merge_point(0, ' #24 LOAD_CONST') -debug_merge_point(0, ' #27 BINARY_AND') -+179: i8 = int_and(i4, 2) -debug_merge_point(0, ' #28 POP_JUMP_IF_FALSE') -+186: i9 = int_is_true(i8) -guard_false(i9, descr=) [p1, p0, p2, p3, i8, i4] -debug_merge_point(0, ' #44 LOAD_FAST') -debug_merge_point(0, ' #47 LOAD_CONST') -debug_merge_point(0, ' #50 INPLACE_ADD') -+196: i11 = int_add(i4, 3) -debug_merge_point(0, ' #51 STORE_FAST') -debug_merge_point(0, ' #54 JUMP_ABSOLUTE') -+200: i13 = getfield_raw(40588192, descr=) -+208: i15 = int_sub(i13, 2) -+212: setfield_raw(40588192, i15, descr=) -+220: i17 = int_lt(i15, 0) -guard_false(i17, descr=) [p1, p0, p2, p3, i11, None, None] -debug_merge_point(0, ' #9 LOAD_FAST') -+230: jump(p0, p1, p2, p3, i11, descr=) -+238: --end of the loop-- -[1f6007a567c] jit-log-opt-loop} -[1f600802cd6] {jit-backend -[1f600862dd8] {jit-backend-dump +CODE_DUMP @7f476a7d623b +0 7B020000 +[3304dedffef] jit-backend-dump} +[3304dee040e] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b9b7 +0 488DA50000000049BB48B00C0A897F00004D8B3B4983C70149BB48B00C0A897F00004D893B4D89F74983C6010F80000000004C8B3C25A0536B024983EF014C893C25A0536B024983FF000F8C00000000488B0425704F3D01488D5010483B1425784F3D01761A49BB10B2A007897F000041FFD349BB8EB2A007897F000041FFD348C7009807000048891425704F3D014C89700848898550FFFFFF4C8BBD70FFFFFF4C8BB568FFFFFF4C8BAD60FFFFFF49BBA8F0B407897F00004D89DC49C7C2000000004C8B8D58FFFFFF49C7C00100000048C7C709000000488BB550FFFFFF48C7C30000000048C7C20000000049BB31B6A007897F000041FFE349BB00B0A007897F000041FFD3444039484C3D031000000049BB00B0A007897F000041FFD34440484C39070311000000 -[1f60086ba5a] jit-backend-dump} -[1f60086d36e] {jit-backend-addr -Bridge out of guard 4 has address 7f8907a0b9b7 to 7f8907a0bab1 -[1f60086ffd2] jit-backend-addr} -[1f600870dca] {jit-backend-dump +CODE_DUMP @7f476a7d624f +0 8C020000 +[3304dee0d4e] jit-backend-dump} +[3304dee115b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b9ba +0 C0FEFFFF -[1f60087281c] jit-backend-dump} -[1f600873506] {jit-backend-dump +CODE_DUMP @7f476a7d6269 +0 97020000 +[3304dee1a98] jit-backend-dump} +[3304dee1e9f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b3d5 +0 C8000000 -[1f600874b44] jit-backend-dump} -[1f6008754d4] {jit-backend-dump +CODE_DUMP @7f476a7d6272 +0 B3020000 +[3304dee2789] jit-backend-dump} +[3304dee2bb1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0ba03 +0 C2000000 -[1f600876956] jit-backend-dump} -[1f600877b1a] {jit-backend-dump +CODE_DUMP @7f476a7d6291 +0 B9020000 +[3304dee34bf] jit-backend-dump} +[3304dee38cc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f8907a0b495 +0 1E050000 -[1f600878f4e] jit-backend-dump} -[1f600884c12] jit-backend} -[1f60088780a] {jit-log-opt-bridge -# bridge out of Guard 4 with 16 ops -[p0, p1, p2, p3, i4, i5] -debug_merge_point(0, ' #31 LOAD_FAST') -debug_merge_point(0, ' #34 LOAD_CONST') -debug_merge_point(0, ' #37 INPLACE_ADD') -+37: i7 = int_add_ovf(i5, 1) -guard_no_overflow(, descr=) [p0, p1, i7, p2, p3, i5] -debug_merge_point(0, ' #38 STORE_FAST') -debug_merge_point(0, ' #41 JUMP_ABSOLUTE') -+50: i9 = getfield_raw(40588192, descr=) -+58: i11 = int_sub(i9, 1) -+62: setfield_raw(40588192, i11, descr=) -+70: i13 = int_lt(i11, 0) -guard_false(i13, descr=) [p0, p1, p2, p3, i7, None] -debug_merge_point(0, ' #9 LOAD_FAST') -+80: p16 = new_with_vtable(ConstClass(W_IntObject)) -+143: setfield_gc(p16, i7, descr=) -+147: jump(p1, p0, p2, ConstPtr(ptr17), 0, p3, 1, 9, p16, ConstPtr(ptr21), ConstPtr(ptr22), descr=) -+250: --end of the loop-- -[1f6008aa976] jit-log-opt-bridge} -[1f600912c98] {jit-backend-counts -0:1982 -1:1985 -2:0 -3:1782 -[1f600916544] jit-backend-counts} +CODE_DUMP @7f476a7d62a2 +0 CD020000 +[3304dee41c5] jit-backend-dump} +[3304dee45e1] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7f476a7d632d +0 67020000 +[3304dee4ec5] jit-backend-dump} +[3304dee543c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7f476a7d635d +0 81020000 +[3304dee5d03] jit-backend-dump} +[3304dee6139] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7f476a7d6377 +0 8C020000 +[3304dee69fa] jit-backend-dump} +[3304dee6e10] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7f476a7d63a2 +0 86020000 +[3304dee9db8] jit-backend-dump} +[3304deea2e6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7f476a7d6426 +0 27020000 +[3304deeac17] jit-backend-dump} +[3304deeb092] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7f476a7d644f +0 48020000 +[3304deeb97f] jit-backend-dump} +[3304deec304] jit-backend} +[3304deed1f1] {jit-log-opt-loop +# Loop 1 ( #13 FOR_ITER) : loop with 82 ops +[p0, p1] ++110: p2 = getfield_gc(p0, descr=) ++124: p3 = getfield_gc(p0, descr=) ++128: p4 = getfield_gc(p0, descr=) ++132: i5 = getfield_gc(p0, descr=) ++140: p6 = getfield_gc(p0, descr=) ++144: i7 = getfield_gc(p0, descr=) ++148: i8 = getfield_gc(p0, descr=) ++152: p9 = getfield_gc(p0, descr=) ++156: p11 = getarrayitem_gc(p9, 0, descr=) ++160: p13 = getarrayitem_gc(p9, 1, descr=) ++164: p15 = getarrayitem_gc(p9, 2, descr=) ++168: p17 = getarrayitem_gc(p9, 3, descr=) ++172: p18 = getfield_gc(p0, descr=) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944753096184)) +debug_merge_point(0, 0, ' #13 FOR_ITER') ++244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++254: guard_class(p15, 25719440, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] ++266: p21 = getfield_gc(p15, descr=) ++270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++279: i22 = getfield_gc(p15, descr=) ++283: p23 = getfield_gc(p21, descr=) ++287: guard_class(p23, 26050592, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++299: p25 = getfield_gc(p21, descr=) ++303: i26 = getfield_gc_pure(p25, descr=) ++307: i27 = getfield_gc_pure(p25, descr=) ++311: i28 = getfield_gc_pure(p25, descr=) ++315: i30 = int_lt(i22, 0) +guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] ++325: i31 = int_ge(i22, i28) +guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] ++334: i32 = int_mul(i22, i27) ++341: i33 = int_add(i26, i32) ++347: i35 = int_add(i22, 1) ++351: setfield_gc(p15, i35, descr=) ++355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] +debug_merge_point(0, 0, ' #16 STORE_FAST') +debug_merge_point(0, 0, ' #19 LOAD_FAST') +debug_merge_point(0, 0, ' #22 LIST_APPEND') ++365: p37 = getfield_gc(p13, descr=) ++369: guard_class(p37, 25936304, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] ++382: p39 = getfield_gc(p13, descr=) ++386: i40 = getfield_gc(p39, descr=) ++390: i42 = int_add(i40, 1) ++394: p43 = getfield_gc(p39, descr=) ++394: i44 = arraylen_gc(p43, descr=) ++394: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i42, descr=) ++506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] ++521: p47 = getfield_gc(p39, descr=) ++532: setarrayitem_gc(p47, i40, i33, descr=) +debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') ++551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++551: i49 = getfield_raw(52008256, descr=) ++559: i51 = int_lt(i49, 0) +guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] +debug_merge_point(0, 0, ' #13 FOR_ITER') ++595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(139944753096272)) +debug_merge_point(0, 0, ' #13 FOR_ITER') ++625: i53 = int_ge(i35, i28) +guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] ++638: i54 = int_mul(i35, i27) ++649: i55 = int_add(i26, i54) ++655: i56 = int_add(i35, 1) +debug_merge_point(0, 0, ' #16 STORE_FAST') +debug_merge_point(0, 0, ' #19 LOAD_FAST') +debug_merge_point(0, 0, ' #22 LIST_APPEND') ++659: i57 = getfield_gc(p39, descr=) ++663: i58 = int_add(i57, 1) ++667: p59 = getfield_gc(p39, descr=) ++667: i60 = arraylen_gc(p59, descr=) ++667: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i58, descr=) ++744: setfield_gc(p15, i56, descr=) ++755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] ++770: p61 = getfield_gc(p39, descr=) ++781: setarrayitem_gc(p61, i57, i55, descr=) +debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') ++793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] ++793: i62 = getfield_raw(52008256, descr=) ++801: i63 = int_lt(i62, 0) +guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] +debug_merge_point(0, 0, ' #13 FOR_ITER') ++811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++840: --end of the loop-- +[3304df359fe] jit-log-opt-loop} +[3304df6aed1] {jit-backend-counts +entry 0:1 +TargetToken(139944714371104):1 +TargetToken(139944714371192):4 +entry 1:1 +TargetToken(139944753096184):1 +TargetToken(139944753096272):4 +[3304df6da3a] jit-backend-counts} diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -106,13 +106,13 @@ fname = str(py.path.local(__file__).join('..', 'x.py')) ops = parse(''' [i0, i1] - debug_merge_point(0, 0, " #0 LOAD_FAST") - debug_merge_point(0, 0, " #3 LOAD_FAST") - debug_merge_point(0, 0, " #6 BINARY_ADD") - debug_merge_point(0, 0, " #7 RETURN_VALUE") + debug_merge_point(0, 0, " #0 LOAD_FAST") + debug_merge_point(0, 0, " #3 LOAD_FAST") + debug_merge_point(0, 0, " #6 BINARY_ADD") + debug_merge_point(0, 0, " #7 RETURN_VALUE") ''' % locals()) res = Function.from_operations(ops.operations, LoopStorage()) - assert res.chunks[1].lineno == 3 + assert res.chunks[1].lineno == 6 def test_linerange(): if sys.version_info > (2, 6): @@ -150,7 +150,7 @@ ''') main.count = 10 bridge = parse(''' - # bridge out of Guard 18 with 13 ops + # bridge out of Guard 0x18 with 13 ops [i0, i1] int_add(i0, i1) ''') @@ -172,7 +172,7 @@ guard_true(v0, descr=) ''') bridge = parse(''' - # bridge out of Guard 1a + # bridge out of Guard 0x1a [] int_add(0, 1) ''') @@ -287,9 +287,7 @@ 'logtest2.log'))) for loop in loops: loop.force_asm() - assert 'cmp' in loops[1].operations[1].asm - # bridge - assert 'jo' in loops[3].operations[3].asm + assert 'cmp' in loops[1].operations[2].asm def test_Op_repr_is_pure(): op = Op('foobar', ['a', 'b'], 'c', 'mydescr') @@ -331,15 +329,15 @@ i113 = getfield_raw(151937600, descr=) ''') bridge = parse(''' - # bridge out of Guard 2 with 1 ops + # bridge out of Guard 0xaf with 1 ops [] i0 = int_lt(1, 2) finish(i0) ''') - bridge.comment = 'bridge out of Guard af with 1 ops' + bridge.comment = 'bridge out of Guard 0xaf with 1 ops' loop.comment = 'Loop 0' loops = split_trace(loop) + split_trace(bridge) - input = ['grrr:123\nasb:12\nbridge af:1234'] + input = ['grrr:123\nasb:12\nbridge 175:1234'] parse_log_counts(input, loops) assert loops[-1].count == 1234 assert loops[1].count == 123 @@ -349,10 +347,8 @@ loop = parse(""" [] debug_merge_point(0, 0, 'random') - debug_merge_point(0, 0, ' #15 COMPARE_OP') """) f = Function.from_operations(loop.operations, LoopStorage()) - assert f.chunks[-1].filename == 'x.py' assert f.filename is None def test_parse_2_levels_up(): diff --git a/pypy/tool/jitlogparser/test/x.py b/pypy/tool/jitlogparser/test/x.py --- a/pypy/tool/jitlogparser/test/x.py +++ b/pypy/tool/jitlogparser/test/x.py @@ -1,3 +1,6 @@ + +import pypyjit +pypyjit.set_param(threshold=3) def f(a, b): return a + b @@ -10,3 +13,6 @@ def h(): [x for x in range(10)] + +g() +h() diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -146,6 +146,10 @@ else: archive = str(builddir.join(name + '.tar.bz2')) if sys.platform == 'darwin' or sys.platform.startswith('freebsd'): + print >>sys.stderr, """Warning: tar on current platform does not suport overriding the uid and gid +for its contents. The tarball will contain your uid and gid. If you are +building the actual release for the PyPy website, you may want to be +using another platform...""" e = os.system('tar --numeric-owner -cvjf ' + archive + " " + name) elif sys.platform == 'cygwin': e = os.system('tar --owner=Administrator --group=Administrators --numeric-owner -cvjf ' + archive + " " + name) diff --git a/pypy/tool/release/test/test_package.py b/pypy/tool/release/test/test_package.py --- a/pypy/tool/release/test/test_package.py +++ b/pypy/tool/release/test/test_package.py @@ -45,8 +45,11 @@ assert exe.mode == 0755 assert exe.uname == '' assert exe.gname == '' - assert exe.uid == 0 - assert exe.gid == 0 + # The tar program on MacOSX or the FreeBSDs does not support + # setting the numeric uid and gid when creating a tar file. + if not(sys.platform == 'darwin' or sys.platform.startswith('freebsd')): + assert exe.uid == 0 + assert exe.gid == 0 # the headers file could be not there, because they are copied into # trunk/include only during translation diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -13,7 +13,7 @@ operations as regalloc_operations, operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER, debug_bridge from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.codewriter.effectinfo import EffectInfo @@ -709,11 +709,7 @@ self.update_frame_depth(frame_depth) self.teardown() - debug_start("jit-backend-addr") - debug_print("bridge out of Guard %d has address 0x%x to 0x%x" % - (descr_number, r_uint(rawstart), - r_uint(rawstart + codeendpos))) - debug_stop("jit-backend-addr") + debug_bridge(descr_number, rawstart, codeendpos) return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -1,13 +1,13 @@ from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.history import JitCellToken -from rpython.jit.backend.test.calling_convention_test import TestCallingConv, parse +from rpython.jit.backend.test.calling_convention_test import CallingConvTests, parse from rpython.rtyper.lltypesystem import lltype from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests skip_unless_run_slow_tests() -class TestARMCallingConvention(TestCallingConv): +class TestARMCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py def test_call_argument_spilling(self): 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 @@ -35,7 +35,7 @@ self.operations = [] for op in operations: if op.getdescr() is not None: - if op.is_guard(): + if op.is_guard() or op.getopnum() == rop.FINISH: newdescr = op.getdescr() else: newdescr = WeakrefDescr(op.getdescr()) diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -5,7 +5,8 @@ ConstInt, BoxInt) from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib import rgc -from rpython.rlib.debug import debug_start, debug_stop, have_debug_prints +from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints, + debug_print) from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype @@ -224,3 +225,12 @@ ResOperation(rop.SETFIELD_RAW, [c_adr, box2], None, descr=self.debug_counter_descr)] operations.extend(ops) + + +def debug_bridge(descr_number, rawstart, codeendpos): + debug_start("jit-backend-addr") + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart), + r_uint(rawstart + codeendpos))) + debug_stop("jit-backend-addr") + diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -10,6 +10,7 @@ from rpython.jit.backend.detect_cpu import getcpuclass from rpython.jit.backend.test.runner_test import Runner import py +import sys def boxfloat(x): return BoxFloat(longlong.getfloatstorage(x)) @@ -381,6 +382,8 @@ raise NotImplementedError def test_call_aligned_explicit_check(self): + if sys.maxint == 2 ** 31 - 1: + py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2,7 +2,8 @@ import os from rpython.jit.backend.llsupport import symbolic, jitframe -from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler, DEBUG_COUNTER +from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler, + DEBUG_COUNTER, debug_bridge) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box @@ -553,11 +554,7 @@ rawstart = self.materialize_loop(original_loop_token) self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, rawstart) - debug_start("jit-backend-addr") - debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % - (r_uint(descr_number), r_uint(rawstart), - r_uint(rawstart + codeendpos))) - debug_stop("jit-backend-addr") + debug_bridge(descr_number, rawstart, codeendpos) self.patch_pending_failure_recoveries(rawstart) # patch the jump from original guard self.patch_jump_for_descr(faildescr, rawstart) diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py --- a/rpython/jit/metainterp/logger.py +++ b/rpython/jit/metainterp/logger.py @@ -43,7 +43,7 @@ else: debug_start("jit-log-opt-bridge") debug_print("# bridge out of Guard", - "%x" % compute_unique_id(descr), + "0x%x" % compute_unique_id(descr), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset) debug_stop("jit-log-opt-bridge") @@ -134,7 +134,7 @@ descr = op.getdescr() if is_guard and self.guard_number: hash = compute_unique_id(descr) - r = "" % hash + r = "" % hash else: r = self.repr_of_descr(descr) if args: diff --git a/rpython/jit/metainterp/test/test_logger.py b/rpython/jit/metainterp/test/test_logger.py --- a/rpython/jit/metainterp/test/test_logger.py +++ b/rpython/jit/metainterp/test/test_logger.py @@ -166,7 +166,7 @@ loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd(), guard_number=True) output = logger.log_loop(loop) - assert re.match("guard_true\(i0, descr=\) \[i0\]", output.splitlines()[-1]) + assert re.match("guard_true\(i0, descr=\) \[i0\]", output.splitlines()[-1]) pure_parse(output) logger = Logger(self.make_metainterp_sd(), guard_number=False) @@ -200,7 +200,7 @@ def test_intro_bridge(self): bare_logger = logger.Logger(self.make_metainterp_sd()) output = capturing(bare_logger.log_bridge, [], [], 3) - assert re.match("# bridge out of Guard [\da-f]+ with 0 ops", + assert re.match("# bridge out of Guard 0x[\da-f]+ with 0 ops", output.splitlines()[0]) pure_parse(output) diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py --- a/rpython/rlib/rstacklet.py +++ b/rpython/rlib/rstacklet.py @@ -47,6 +47,10 @@ def get_null_handle(self): return self._gcrootfinder.get_null_handle() + def _freeze_(self): + raise Exception("StackletThread instances must not be seen during" + " translation.") + class StackletThreadDeleter(object): # quick hack: the __del__ is on another object, so that diff --git a/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt b/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt @@ -0,0 +1,206 @@ +# CompositionExclusions-6.0.0.txt +# Date: 2010-06-25, 14:34:00 PDT [KW] +# +# This file lists the characters for the Composition Exclusion Table +# defined in UAX #15, Unicode Normalization Forms. +# +# This file is a normative contributory data file in the +# Unicode Character Database. +# +# Copyright (c) 1991-2010 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# For more information, see +# http://www.unicode.org/unicode/reports/tr15/#Primary_Exclusion_List_Table +# +# For a full derivation of composition exclusions, see the derived property +# Full_Composition_Exclusion in DerivedNormalizationProps.txt +# + +# ================================================ +# (1) Script Specifics +# +# This list of characters cannot be derived from the UnicodeData.txt file. +# ================================================ + +0958 # DEVANAGARI LETTER QA +0959 # DEVANAGARI LETTER KHHA +095A # DEVANAGARI LETTER GHHA +095B # DEVANAGARI LETTER ZA +095C # DEVANAGARI LETTER DDDHA +095D # DEVANAGARI LETTER RHA +095E # DEVANAGARI LETTER FA +095F # DEVANAGARI LETTER YYA +09DC # BENGALI LETTER RRA +09DD # BENGALI LETTER RHA +09DF # BENGALI LETTER YYA +0A33 # GURMUKHI LETTER LLA +0A36 # GURMUKHI LETTER SHA +0A59 # GURMUKHI LETTER KHHA +0A5A # GURMUKHI LETTER GHHA +0A5B # GURMUKHI LETTER ZA +0A5E # GURMUKHI LETTER FA +0B5C # ORIYA LETTER RRA +0B5D # ORIYA LETTER RHA +0F43 # TIBETAN LETTER GHA +0F4D # TIBETAN LETTER DDHA +0F52 # TIBETAN LETTER DHA +0F57 # TIBETAN LETTER BHA +0F5C # TIBETAN LETTER DZHA +0F69 # TIBETAN LETTER KSSA +0F76 # TIBETAN VOWEL SIGN VOCALIC R +0F78 # TIBETAN VOWEL SIGN VOCALIC L +0F93 # TIBETAN SUBJOINED LETTER GHA +0F9D # TIBETAN SUBJOINED LETTER DDHA +0FA2 # TIBETAN SUBJOINED LETTER DHA +0FA7 # TIBETAN SUBJOINED LETTER BHA +0FAC # TIBETAN SUBJOINED LETTER DZHA +0FB9 # TIBETAN SUBJOINED LETTER KSSA +FB1D # HEBREW LETTER YOD WITH HIRIQ +FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH +FB2A # HEBREW LETTER SHIN WITH SHIN DOT +FB2B # HEBREW LETTER SHIN WITH SIN DOT +FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT +FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT +FB2E # HEBREW LETTER ALEF WITH PATAH +FB2F # HEBREW LETTER ALEF WITH QAMATS +FB30 # HEBREW LETTER ALEF WITH MAPIQ +FB31 # HEBREW LETTER BET WITH DAGESH +FB32 # HEBREW LETTER GIMEL WITH DAGESH +FB33 # HEBREW LETTER DALET WITH DAGESH +FB34 # HEBREW LETTER HE WITH MAPIQ +FB35 # HEBREW LETTER VAV WITH DAGESH +FB36 # HEBREW LETTER ZAYIN WITH DAGESH +FB38 # HEBREW LETTER TET WITH DAGESH +FB39 # HEBREW LETTER YOD WITH DAGESH +FB3A # HEBREW LETTER FINAL KAF WITH DAGESH +FB3B # HEBREW LETTER KAF WITH DAGESH +FB3C # HEBREW LETTER LAMED WITH DAGESH +FB3E # HEBREW LETTER MEM WITH DAGESH +FB40 # HEBREW LETTER NUN WITH DAGESH +FB41 # HEBREW LETTER SAMEKH WITH DAGESH +FB43 # HEBREW LETTER FINAL PE WITH DAGESH +FB44 # HEBREW LETTER PE WITH DAGESH +FB46 # HEBREW LETTER TSADI WITH DAGESH +FB47 # HEBREW LETTER QOF WITH DAGESH +FB48 # HEBREW LETTER RESH WITH DAGESH +FB49 # HEBREW LETTER SHIN WITH DAGESH +FB4A # HEBREW LETTER TAV WITH DAGESH +FB4B # HEBREW LETTER VAV WITH HOLAM +FB4C # HEBREW LETTER BET WITH RAFE +FB4D # HEBREW LETTER KAF WITH RAFE +FB4E # HEBREW LETTER PE WITH RAFE + +# Total code points: 67 + +# ================================================ +# (2) Post Composition Version precomposed characters +# +# These characters cannot be derived solely from the UnicodeData.txt file +# in this version of Unicode. +# +# Note that characters added to the standard after the +# Composition Version and which have canonical decomposition mappings +# are not automatically added to this list of Post Composition +# Version precomposed characters. +# ================================================ + +2ADC # FORKING +1D15E # MUSICAL SYMBOL HALF NOTE +1D15F # MUSICAL SYMBOL QUARTER NOTE +1D160 # MUSICAL SYMBOL EIGHTH NOTE +1D161 # MUSICAL SYMBOL SIXTEENTH NOTE +1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE +1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE +1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D1BB # MUSICAL SYMBOL MINIMA +1D1BC # MUSICAL SYMBOL MINIMA BLACK +1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE +1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK +1D1BF # MUSICAL SYMBOL FUSA WHITE +1D1C0 # MUSICAL SYMBOL FUSA BLACK + +# Total code points: 14 + +# ================================================ +# (3) Singleton Decompositions +# +# These characters can be derived from the UnicodeData.txt file +# by including all canonically decomposable characters whose +# canonical decomposition consists of a single character. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK +# 0343 COMBINING GREEK KORONIS +# 0374 GREEK NUMERAL SIGN +# 037E GREEK QUESTION MARK +# 0387 GREEK ANO TELEIA +# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA +# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA +# 1F75 GREEK SMALL LETTER ETA WITH OXIA +# 1F77 GREEK SMALL LETTER IOTA WITH OXIA +# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA +# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA +# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA +# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA +# 1FBE GREEK PROSGEGRAMMENI +# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA +# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA +# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA +# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA +# 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA +# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA +# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA +# 1FFD GREEK OXIA +# 2000..2001 [2] EN QUAD..EM QUAD +# 2126 OHM SIGN +# 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN +# 2329 LEFT-POINTING ANGLE BRACKET +# 232A RIGHT-POINTING ANGLE BRACKET +# F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D +# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10 +# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12 +# FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E +# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20 +# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22 +# FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26 +# FA2A..FA2D [4] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA2D +# FA30..FA6D [62] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6D +# FA70..FAD9 [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +# 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 1033 + +# ================================================ +# (4) Non-Starter Decompositions +# +# These characters can be derived from the UnicodeData file +# by including each expanding canonical decomposition +# (i.e., those which canonically decompose to a sequence +# of characters instead of a single character), such that: +# +# A. The character is not a Starter. +# +# OR (inclusive) +# +# B. The character's canonical decomposition begins +# with a character that is not a Starter. +# +# Note that a "Starter" is any character with a zero combining class. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0344 COMBINING GREEK DIALYTIKA TONOS +# 0F73 TIBETAN VOWEL SIGN II +# 0F75 TIBETAN VOWEL SIGN UU +# 0F81 TIBETAN VOWEL SIGN REVERSED II + +# Total code points: 4 + diff --git a/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt b/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt @@ -0,0 +1,9482 @@ +# DerivedCoreProperties-6.0.0.txt +# Date: 2010-08-19, 00:48:05 GMT [MD] +# +# Unicode Character Database +# Copyright (c) 1991-2010 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# For documentation, see http://www.unicode.org/reports/tr44/ + +# ================================================ + +# Derived Property: Math +# Generated from: Sm + Other_Math + +002B ; Math # Sm PLUS SIGN +003C..003E ; Math # Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN +005E ; Math # Sk CIRCUMFLEX ACCENT +007C ; Math # Sm VERTICAL LINE +007E ; Math # Sm TILDE +00AC ; Math # Sm NOT SIGN +00B1 ; Math # Sm PLUS-MINUS SIGN +00D7 ; Math # Sm MULTIPLICATION SIGN +00F7 ; Math # Sm DIVISION SIGN +03D0..03D2 ; Math # L& [3] GREEK BETA SYMBOL..GREEK UPSILON WITH HOOK SYMBOL +03D5 ; Math # L& GREEK PHI SYMBOL +03F0..03F1 ; Math # L& [2] GREEK KAPPA SYMBOL..GREEK RHO SYMBOL +03F4..03F5 ; Math # L& [2] GREEK CAPITAL THETA SYMBOL..GREEK LUNATE EPSILON SYMBOL +03F6 ; Math # Sm GREEK REVERSED LUNATE EPSILON SYMBOL +0606..0608 ; Math # Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY +2016 ; Math # Po DOUBLE VERTICAL LINE +2032..2034 ; Math # Po [3] PRIME..TRIPLE PRIME +2040 ; Math # Pc CHARACTER TIE +2044 ; Math # Sm FRACTION SLASH +2052 ; Math # Sm COMMERCIAL MINUS SIGN +2061..2064 ; Math # Cf [4] FUNCTION APPLICATION..INVISIBLE PLUS +207A..207C ; Math # Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN +207D ; Math # Ps SUPERSCRIPT LEFT PARENTHESIS +207E ; Math # Pe SUPERSCRIPT RIGHT PARENTHESIS +208A..208C ; Math # Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN +208D ; Math # Ps SUBSCRIPT LEFT PARENTHESIS +208E ; Math # Pe SUBSCRIPT RIGHT PARENTHESIS +20D0..20DC ; Math # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE +20E1 ; Math # Mn COMBINING LEFT RIGHT ARROW ABOVE +20E5..20E6 ; Math # Mn [2] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING DOUBLE VERTICAL STROKE OVERLAY +20EB..20EF ; Math # Mn [5] COMBINING LONG DOUBLE SOLIDUS OVERLAY..COMBINING RIGHT ARROW BELOW +2102 ; Math # L& DOUBLE-STRUCK CAPITAL C +2107 ; Math # L& EULER CONSTANT +210A..2113 ; Math # L& [10] SCRIPT SMALL G..SCRIPT SMALL L +2115 ; Math # L& DOUBLE-STRUCK CAPITAL N +2118 ; Math # Sm SCRIPT CAPITAL P +2119..211D ; Math # L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +2124 ; Math # L& DOUBLE-STRUCK CAPITAL Z +2128 ; Math # L& BLACK-LETTER CAPITAL Z +2129 ; Math # So TURNED GREEK SMALL LETTER IOTA +212C..212D ; Math # L& [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C +212F..2131 ; Math # L& [3] SCRIPT SMALL E..SCRIPT CAPITAL F +2133..2134 ; Math # L& [2] SCRIPT CAPITAL M..SCRIPT SMALL O +2135..2138 ; Math # Lo [4] ALEF SYMBOL..DALET SYMBOL +213C..213F ; Math # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI +2140..2144 ; Math # Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y +2145..2149 ; Math # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J +214B ; Math # Sm TURNED AMPERSAND +2190..2194 ; Math # Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW +2195..2199 ; Math # So [5] UP DOWN ARROW..SOUTH WEST ARROW +219A..219B ; Math # Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE +219C..219F ; Math # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW +21A0 ; Math # Sm RIGHTWARDS TWO HEADED ARROW +21A1..21A2 ; Math # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL +21A3 ; Math # Sm RIGHTWARDS ARROW WITH TAIL +21A4..21A5 ; Math # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR +21A6 ; Math # Sm RIGHTWARDS ARROW FROM BAR +21A7 ; Math # So DOWNWARDS ARROW FROM BAR +21A9..21AD ; Math # So [5] LEFTWARDS ARROW WITH HOOK..LEFT RIGHT WAVE ARROW +21AE ; Math # Sm LEFT RIGHT ARROW WITH STROKE +21B0..21B1 ; Math # So [2] UPWARDS ARROW WITH TIP LEFTWARDS..UPWARDS ARROW WITH TIP RIGHTWARDS +21B6..21B7 ; Math # So [2] ANTICLOCKWISE TOP SEMICIRCLE ARROW..CLOCKWISE TOP SEMICIRCLE ARROW +21BC..21CD ; Math # So [18] LEFTWARDS HARPOON WITH BARB UPWARDS..LEFTWARDS DOUBLE ARROW WITH STROKE +21CE..21CF ; Math # Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE +21D0..21D1 ; Math # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW +21D2 ; Math # Sm RIGHTWARDS DOUBLE ARROW +21D3 ; Math # So DOWNWARDS DOUBLE ARROW +21D4 ; Math # Sm LEFT RIGHT DOUBLE ARROW +21D5..21DB ; Math # So [7] UP DOWN DOUBLE ARROW..RIGHTWARDS TRIPLE ARROW +21DD ; Math # So RIGHTWARDS SQUIGGLE ARROW +21E4..21E5 ; Math # So [2] LEFTWARDS ARROW TO BAR..RIGHTWARDS ARROW TO BAR +21F4..22FF ; Math # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP +2308..230B ; Math # Sm [4] LEFT CEILING..RIGHT FLOOR +2320..2321 ; Math # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL +237C ; Math # Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +239B..23B3 ; Math # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM +23B4..23B5 ; Math # So [2] TOP SQUARE BRACKET..BOTTOM SQUARE BRACKET +23B7 ; Math # So RADICAL SYMBOL BOTTOM +23D0 ; Math # So VERTICAL LINE EXTENSION +23DC..23E1 ; Math # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET +23E2 ; Math # So WHITE TRAPEZIUM +25A0..25A1 ; Math # So [2] BLACK SQUARE..WHITE SQUARE +25AE..25B6 ; Math # So [9] BLACK VERTICAL RECTANGLE..BLACK RIGHT-POINTING TRIANGLE +25B7 ; Math # Sm WHITE RIGHT-POINTING TRIANGLE +25BC..25C0 ; Math # So [5] BLACK DOWN-POINTING TRIANGLE..BLACK LEFT-POINTING TRIANGLE +25C1 ; Math # Sm WHITE LEFT-POINTING TRIANGLE +25C6..25C7 ; Math # So [2] BLACK DIAMOND..WHITE DIAMOND +25CA..25CB ; Math # So [2] LOZENGE..WHITE CIRCLE +25CF..25D3 ; Math # So [5] BLACK CIRCLE..CIRCLE WITH UPPER HALF BLACK +25E2 ; Math # So BLACK LOWER RIGHT TRIANGLE +25E4 ; Math # So BLACK UPPER LEFT TRIANGLE +25E7..25EC ; Math # So [6] SQUARE WITH LEFT HALF BLACK..WHITE UP-POINTING TRIANGLE WITH DOT +25F8..25FF ; Math # Sm [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE +2605..2606 ; Math # So [2] BLACK STAR..WHITE STAR +2640 ; Math # So FEMALE SIGN +2642 ; Math # So MALE SIGN +2660..2663 ; Math # So [4] BLACK SPADE SUIT..BLACK CLUB SUIT +266D..266E ; Math # So [2] MUSIC FLAT SIGN..MUSIC NATURAL SIGN +266F ; Math # Sm MUSIC SHARP SIGN +27C0..27C4 ; Math # Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET +27C5 ; Math # Ps LEFT S-SHAPED BAG DELIMITER +27C6 ; Math # Pe RIGHT S-SHAPED BAG DELIMITER +27C7..27CA ; Math # Sm [4] OR WITH DOT INSIDE..VERTICAL BAR WITH HORIZONTAL STROKE +27CC ; Math # Sm LONG DIVISION +27CE..27E5 ; Math # Sm [24] SQUARED LOGICAL AND..WHITE SQUARE WITH RIGHTWARDS TICK +27E6 ; Math # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E7 ; Math # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E8 ; Math # Ps MATHEMATICAL LEFT ANGLE BRACKET +27E9 ; Math # Pe MATHEMATICAL RIGHT ANGLE BRACKET +27EA ; Math # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EB ; Math # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27EC ; Math # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27ED ; Math # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EE ; Math # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS +27EF ; Math # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS +27F0..27FF ; Math # Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW +2900..2982 ; Math # Sm [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON +2983 ; Math # Ps LEFT WHITE CURLY BRACKET +2984 ; Math # Pe RIGHT WHITE CURLY BRACKET +2985 ; Math # Ps LEFT WHITE PARENTHESIS +2986 ; Math # Pe RIGHT WHITE PARENTHESIS +2987 ; Math # Ps Z NOTATION LEFT IMAGE BRACKET +2988 ; Math # Pe Z NOTATION RIGHT IMAGE BRACKET +2989 ; Math # Ps Z NOTATION LEFT BINDING BRACKET +298A ; Math # Pe Z NOTATION RIGHT BINDING BRACKET +298B ; Math # Ps LEFT SQUARE BRACKET WITH UNDERBAR +298C ; Math # Pe RIGHT SQUARE BRACKET WITH UNDERBAR +298D ; Math # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298E ; Math # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +298F ; Math # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990 ; Math # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2991 ; Math # Ps LEFT ANGLE BRACKET WITH DOT +2992 ; Math # Pe RIGHT ANGLE BRACKET WITH DOT +2993 ; Math # Ps LEFT ARC LESS-THAN BRACKET +2994 ; Math # Pe RIGHT ARC GREATER-THAN BRACKET +2995 ; Math # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET +2996 ; Math # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET +2997 ; Math # Ps LEFT BLACK TORTOISE SHELL BRACKET +2998 ; Math # Pe RIGHT BLACK TORTOISE SHELL BRACKET +2999..29D7 ; Math # Sm [63] DOTTED FENCE..BLACK HOURGLASS +29D8 ; Math # Ps LEFT WIGGLY FENCE +29D9 ; Math # Pe RIGHT WIGGLY FENCE +29DA ; Math # Ps LEFT DOUBLE WIGGLY FENCE +29DB ; Math # Pe RIGHT DOUBLE WIGGLY FENCE +29DC..29FB ; Math # Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS +29FC ; Math # Ps LEFT-POINTING CURVED ANGLE BRACKET +29FD ; Math # Pe RIGHT-POINTING CURVED ANGLE BRACKET +29FE..2AFF ; Math # Sm [258] TINY..N-ARY WHITE VERTICAL BAR +2B30..2B44 ; Math # Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET +2B47..2B4C ; Math # Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +FB29 ; Math # Sm HEBREW LETTER ALTERNATIVE PLUS SIGN +FE61 ; Math # Po SMALL ASTERISK +FE62 ; Math # Sm SMALL PLUS SIGN +FE63 ; Math # Pd SMALL HYPHEN-MINUS +FE64..FE66 ; Math # Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN +FE68 ; Math # Po SMALL REVERSE SOLIDUS +FF0B ; Math # Sm FULLWIDTH PLUS SIGN +FF1C..FF1E ; Math # Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN +FF3C ; Math # Po FULLWIDTH REVERSE SOLIDUS +FF3E ; Math # Sk FULLWIDTH CIRCUMFLEX ACCENT +FF5C ; Math # Sm FULLWIDTH VERTICAL LINE +FF5E ; Math # Sm FULLWIDTH TILDE +FFE2 ; Math # Sm FULLWIDTH NOT SIGN +FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW +1D400..1D454 ; Math # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G +1D456..1D49C ; Math # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2 ; Math # L& MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6 ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC ; Math # L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B9 ; Math # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Math # L& MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Math # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D505 ; Math # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A ; Math # L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514 ; Math # L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C ; Math # L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D51E..1D539 ; Math # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E ; Math # L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544 ; Math # L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 ; Math # L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550 ; Math # L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552..1D6A5 ; Math # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6A8..1D6C0 ; Math # L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6C1 ; Math # Sm MATHEMATICAL BOLD NABLA +1D6C2..1D6DA ; Math # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DB ; Math # Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6DC..1D6FA ; Math # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FB ; Math # Sm MATHEMATICAL ITALIC NABLA +1D6FC..1D714 ; Math # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D715 ; Math # Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D716..1D734 ; Math # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D735 ; Math # Sm MATHEMATICAL BOLD ITALIC NABLA +1D736..1D74E ; Math # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D74F ; Math # Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D750..1D76E ; Math # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D76F ; Math # Sm MATHEMATICAL SANS-SERIF BOLD NABLA +1D770..1D788 ; Math # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D789 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D78A..1D7A8 ; Math # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7A9 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7AA..1D7C2 ; Math # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C3 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1D7C4..1D7CB ; Math # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1D7CE..1D7FF ; Math # Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + +# Total code points: 2165 + +# ================================================ + +# Derived Property: Alphabetic +# Generated from: Lu+Ll+Lt+Lm+Lo+Nl + Other_Alphabetic + +0041..005A ; Alphabetic # L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +0061..007A ; Alphabetic # L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00AA ; Alphabetic # L& FEMININE ORDINAL INDICATOR +00B5 ; Alphabetic # L& MICRO SIGN +00BA ; Alphabetic # L& MASCULINE ORDINAL INDICATOR +00C0..00D6 ; Alphabetic # L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS +00D8..00F6 ; Alphabetic # L& [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS +00F8..01BA ; Alphabetic # L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL +01BB ; Alphabetic # Lo LATIN LETTER TWO WITH STROKE +01BC..01BF ; Alphabetic # L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN +01C0..01C3 ; Alphabetic # Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK +01C4..0293 ; Alphabetic # L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL +0294 ; Alphabetic # Lo LATIN LETTER GLOTTAL STOP +0295..02AF ; Alphabetic # L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +02B0..02C1 ; Alphabetic # Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP +02C6..02D1 ; Alphabetic # Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON +02E0..02E4 ; Alphabetic # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +02EC ; Alphabetic # Lm MODIFIER LETTER VOICING +02EE ; Alphabetic # Lm MODIFIER LETTER DOUBLE APOSTROPHE +0345 ; Alphabetic # Mn COMBINING GREEK YPOGEGRAMMENI +0370..0373 ; Alphabetic # L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI +0374 ; Alphabetic # Lm GREEK NUMERAL SIGN +0376..0377 ; Alphabetic # L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037A ; Alphabetic # Lm GREEK YPOGEGRAMMENI +037B..037D ; Alphabetic # L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +0386 ; Alphabetic # L& GREEK CAPITAL LETTER ALPHA WITH TONOS +0388..038A ; Alphabetic # L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS +038C ; Alphabetic # L& GREEK CAPITAL LETTER OMICRON WITH TONOS +038E..03A1 ; Alphabetic # L& [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO +03A3..03F5 ; Alphabetic # L& [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL +03F7..0481 ; Alphabetic # L& [139] GREEK CAPITAL LETTER SHO..CYRILLIC SMALL LETTER KOPPA +048A..0527 ; Alphabetic # L& [158] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER SHHA WITH DESCENDER +0531..0556 ; Alphabetic # L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH +0559 ; Alphabetic # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING +0561..0587 ; Alphabetic # L& [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN +05B0..05BD ; Alphabetic # Mn [14] HEBREW POINT SHEVA..HEBREW POINT METEG +05BF ; Alphabetic # Mn HEBREW POINT RAFE +05C1..05C2 ; Alphabetic # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C4..05C5 ; Alphabetic # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT +05C7 ; Alphabetic # Mn HEBREW POINT QAMATS QATAN +05D0..05EA ; Alphabetic # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV +05F0..05F2 ; Alphabetic # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD +0610..061A ; Alphabetic # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA +0620..063F ; Alphabetic # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE +0640 ; Alphabetic # Lm ARABIC TATWEEL +0641..064A ; Alphabetic # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH +064B..0657 ; Alphabetic # Mn [13] ARABIC FATHATAN..ARABIC INVERTED DAMMA +0659..065F ; Alphabetic # Mn [7] ARABIC ZWARAKAY..ARABIC WAVY HAMZA BELOW +066E..066F ; Alphabetic # Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF +0670 ; Alphabetic # Mn ARABIC LETTER SUPERSCRIPT ALEF +0671..06D3 ; Alphabetic # Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +06D5 ; Alphabetic # Lo ARABIC LETTER AE +06D6..06DC ; Alphabetic # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN +06E1..06E4 ; Alphabetic # Mn [4] ARABIC SMALL HIGH DOTLESS HEAD OF KHAH..ARABIC SMALL HIGH MADDA +06E5..06E6 ; Alphabetic # Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH +06E7..06E8 ; Alphabetic # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +06ED ; Alphabetic # Mn ARABIC SMALL LOW MEEM +06EE..06EF ; Alphabetic # Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V +06FA..06FC ; Alphabetic # Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW +06FF ; Alphabetic # Lo ARABIC LETTER HEH WITH INVERTED V +0710 ; Alphabetic # Lo SYRIAC LETTER ALAPH +0711 ; Alphabetic # Mn SYRIAC LETTER SUPERSCRIPT ALAPH +0712..072F ; Alphabetic # Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH +0730..073F ; Alphabetic # Mn [16] SYRIAC PTHAHA ABOVE..SYRIAC RWAHA +074D..07A5 ; Alphabetic # Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU +07A6..07B0 ; Alphabetic # Mn [11] THAANA ABAFILI..THAANA SUKUN +07B1 ; Alphabetic # Lo THAANA LETTER NAA +07CA..07EA ; Alphabetic # Lo [33] NKO LETTER A..NKO LETTER JONA RA +07F4..07F5 ; Alphabetic # Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE +07FA ; Alphabetic # Lm NKO LAJANYALAN +0800..0815 ; Alphabetic # Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF +0816..0817 ; Alphabetic # Mn [2] SAMARITAN MARK IN..SAMARITAN MARK IN-ALAF +081A ; Alphabetic # Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT +081B..0823 ; Alphabetic # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A +0824 ; Alphabetic # Lm SAMARITAN MODIFIER LETTER SHORT A +0825..0827 ; Alphabetic # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U +0828 ; Alphabetic # Lm SAMARITAN MODIFIER LETTER I +0829..082C ; Alphabetic # Mn [4] SAMARITAN VOWEL SIGN LONG I..SAMARITAN VOWEL SIGN SUKUN +0840..0858 ; Alphabetic # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN +0900..0902 ; Alphabetic # Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA +0903 ; Alphabetic # Mc DEVANAGARI SIGN VISARGA +0904..0939 ; Alphabetic # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA +093A ; Alphabetic # Mn DEVANAGARI VOWEL SIGN OE +093B ; Alphabetic # Mc DEVANAGARI VOWEL SIGN OOE +093D ; Alphabetic # Lo DEVANAGARI SIGN AVAGRAHA +093E..0940 ; Alphabetic # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II +0941..0948 ; Alphabetic # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI +0949..094C ; Alphabetic # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU +094E..094F ; Alphabetic # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW +0950 ; Alphabetic # Lo DEVANAGARI OM +0955..0957 ; Alphabetic # Mn [3] DEVANAGARI VOWEL SIGN CANDRA LONG E..DEVANAGARI VOWEL SIGN UUE +0958..0961 ; Alphabetic # Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL +0962..0963 ; Alphabetic # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0971 ; Alphabetic # Lm DEVANAGARI SIGN HIGH SPACING DOT +0972..0977 ; Alphabetic # Lo [6] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER UUE +0979..097F ; Alphabetic # Lo [7] DEVANAGARI LETTER ZHA..DEVANAGARI LETTER BBA +0981 ; Alphabetic # Mn BENGALI SIGN CANDRABINDU +0982..0983 ; Alphabetic # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA +0985..098C ; Alphabetic # Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L +098F..0990 ; Alphabetic # Lo [2] BENGALI LETTER E..BENGALI LETTER AI +0993..09A8 ; Alphabetic # Lo [22] BENGALI LETTER O..BENGALI LETTER NA +09AA..09B0 ; Alphabetic # Lo [7] BENGALI LETTER PA..BENGALI LETTER RA +09B2 ; Alphabetic # Lo BENGALI LETTER LA +09B6..09B9 ; Alphabetic # Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA +09BD ; Alphabetic # Lo BENGALI SIGN AVAGRAHA +09BE..09C0 ; Alphabetic # Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II +09C1..09C4 ; Alphabetic # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR +09C7..09C8 ; Alphabetic # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CC ; Alphabetic # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU +09CE ; Alphabetic # Lo BENGALI LETTER KHANDA TA +09D7 ; Alphabetic # Mc BENGALI AU LENGTH MARK +09DC..09DD ; Alphabetic # Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA +09DF..09E1 ; Alphabetic # Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL +09E2..09E3 ; Alphabetic # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL +09F0..09F1 ; Alphabetic # Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL +0A01..0A02 ; Alphabetic # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI +0A03 ; Alphabetic # Mc GURMUKHI SIGN VISARGA +0A05..0A0A ; Alphabetic # Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU +0A0F..0A10 ; Alphabetic # Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI +0A13..0A28 ; Alphabetic # Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA +0A2A..0A30 ; Alphabetic # Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA +0A32..0A33 ; Alphabetic # Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA +0A35..0A36 ; Alphabetic # Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA +0A38..0A39 ; Alphabetic # Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA +0A3E..0A40 ; Alphabetic # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II +0A41..0A42 ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4C ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN OO..GURMUKHI VOWEL SIGN AU +0A51 ; Alphabetic # Mn GURMUKHI SIGN UDAAT +0A59..0A5C ; Alphabetic # Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA From noreply at buildbot.pypy.org Wed Mar 20 01:53:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:53:10 +0100 (CET) Subject: [pypy-commit] pypy default: update Message-ID: <20130320005310.B367E1C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62529:12d9f6fdc0a0 Date: 2013-03-19 17:49 -0700 http://bitbucket.org/pypy/pypy/changeset/12d9f6fdc0a0/ Log: update diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -1,121 +1,121 @@ -[3304d0bb187] {jit-backend-dump +[1cffd8feb691] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0ca602] jit-backend-dump} -[3304d0cfdf4] {jit-backend-dump +CODE_DUMP @7f5514b31000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd8ffaba6] jit-backend-dump} +[1cffd90012ee] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0d2b27] jit-backend-dump} -[3304d0d73d6] {jit-backend-dump +CODE_DUMP @7f5514b31085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd9003b76] jit-backend-dump} +[1cffd900719f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d512e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[3304d0d9073] jit-backend-dump} -[3304d0db1d8] {jit-backend-dump +CODE_DUMP @7f5514b3112e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1cffd9008c81] jit-backend-dump} +[1cffd900b384] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[3304d0dce9e] jit-backend-dump} -[3304d0dfc06] {jit-backend-dump +CODE_DUMP @7f5514b31191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1cffd900cf18] jit-backend-dump} +[1cffd9010345] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d51fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C25C80219034C8B2425C002190348C70425C00219030000000048C70425C80219030000000041BBC069120141FFD3F20F10442418488B44240848891C25C80219034C892425C0021903488B5C24284C8B642430488D642438C3 -[3304d0e1a04] jit-backend-dump} -[3304d0e4ae5] {jit-backend-dump +CODE_DUMP @7f5514b311fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 +[1cffd9011f0b] jit-backend-dump} +[1cffd9015bd8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C25C802190348894D38488B1C25C002190348C70425C00219030000000048C70425C80219030000000041BB90E3E80041FFD34889C5488B4D3848C745380000000048890C25C802190348891C25C00219034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[3304d0e9130] jit-backend-dump} -[3304d0ea4a1] {jit-backend-dump +CODE_DUMP @7f5514b31275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[1cffd901a191] jit-backend-dump} +[1cffd901b3a6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0ecf16] jit-backend-dump} -[3304d0ee1ff] {jit-backend-dump +CODE_DUMP @7f5514b31491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd901dc46] jit-backend-dump} +[1cffd901ef79] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0fca06] jit-backend-dump} -[3304d0fe4ac] {jit-backend-dump +CODE_DUMP @7f5514b31595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd902ce01] jit-backend-dump} +[1cffd902e819] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d56bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[3304d1018ac] jit-backend-dump} -[3304d103089] {jit-backend-dump +CODE_DUMP @7f5514b316bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1cffd9031b79] jit-backend-dump} +[1cffd90331b0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d581e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[3304d1062c0] jit-backend-dump} -[3304d1072c1] {jit-backend-dump +CODE_DUMP @7f5514b3181e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1cffd903629a] jit-backend-dump} +[1cffd903736b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5988 +0 488B0425C802190348C70425C00219030000000048C70425C8021903000000004889453848C745108064B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d1089ec] jit-backend-dump} -[3304d11572c] {jit-backend-dump +CODE_DUMP @7f5514b31988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd9038a70] jit-backend-dump} +[1cffd903e2cd] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d59e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBF0ACE80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD517D6A477F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25C8EEB50148C7452000000000C34883C40849BB88597D6A477F000041FFE3 -[3304d120245] jit-backend-dump} -[3304d122916] {jit-backend-dump +CODE_DUMP @7f5514b319e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD11B314557F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB8819B314557F000041FFE3 +[1cffd904265b] jit-backend-dump} +[1cffd90448f2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5bd6 +0 4889E74883EC0841BB9018210141FFD34883C408488B0425C00219034885C07501C34883C40849BB88597D6A477F000041FFE3 -[3304d1240c0] jit-backend-dump} -[3304d1246a0] {jit-backend-counts -[3304d124ab0] jit-backend-counts} -[3304d690a50] {jit-backend -[3304db64ec0] {jit-backend-dump +CODE_DUMP @7f5514b31bd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB8819B314557F000041FFE3 +[1cffd9045d15] jit-backend-dump} +[1cffd904647a] {jit-backend-counts +[1cffd9046851] jit-backend-counts} +[1cffd9636773] {jit-backend +[1cffd9afbdde] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBF0905D6D477F00004D8B3B4D8D770149BBF0905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08915D6D477F0000498B0B488D410149BB08915D6D477F00004989034983F8020F85000000004883FB017206813B680B00000F85000000004983FA000F850000000049BB20C0FC6A477F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425409519034983FC000F8C0000000049BB20915D6D477F00004D8B234D8D54240149BB20915D6D477F00004D89134883FB0A0F8D000000004C8D5301488B1C25409519034883FB000F8C000000004C89D3E9B9FFFFFF49BB2020FD6A477F0000415349BB405C7D6A477F0000415349BB00507D6A477F000041FFE349BB3806036B477F0000415349BB505C7D6A477F0000415349BB00507D6A477F000041FFE349BBC005036B477F0000415349BB605C7D6A477F0000415349BB00507D6A477F000041FFE349BB4805036B477F0000415349BB705C7D6A477F0000415349BB00507D6A477F000041FFE349BBD004036B477F0000415349BB805C7D6A477F0000415349BB00507D6A477F000041FFE349BB5804036B477F0000415349BB905C7D6A477F0000415349BB00507D6A477F000041FFE349BBE003036B477F0000415349BBA05C7D6A477F0000415349BB00507D6A477F000041FFE349BB6803036B477F0000415349BBB05C7D6A477F0000415349BB00507D6A477F000041FFE349BBF002036B477F0000415349BBC05C7D6A477F0000415349BB00507D6A477F000041FFE349BB7802036B477F0000415349BBD05C7D6A477F0000415349BB00507D6A477F000041FFE3 -[3304db7d5e4] jit-backend-dump} -[3304db7df74] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 0x7f476a7d5d30 to 0x7f476a7d5e80 (bootstrap 0x7f476a7d5ce0) -[3304db7f906] jit-backend-addr} -[3304db8036d] {jit-backend-dump +CODE_DUMP @7f5514b31ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD61BB314557F000041FFD349BBF0509317557F00004D8B3B4D8D770149BBF0509317557F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08519317557F0000498B0B488D410149BB08519317557F00004989034983F8020F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB20803215557F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425807816034983FC000F8C0000000049BB20519317557F00004D8B234D8D54240149BB20519317557F00004D89134883FB0A0F8D000000004C8D5301488B1C25807816034883FB000F8C000000004C89D3E9B9FFFFFF49BB20E03215557F0000415349BB401CB314557F0000415349BB0010B314557F000041FFE349BB38C63815557F0000415349BB501CB314557F0000415349BB0010B314557F000041FFE349BBC0C53815557F0000415349BB601CB314557F0000415349BB0010B314557F000041FFE349BB48C53815557F0000415349BB701CB314557F0000415349BB0010B314557F000041FFE349BBD0C43815557F0000415349BB801CB314557F0000415349BB0010B314557F000041FFE349BB58C43815557F0000415349BB901CB314557F0000415349BB0010B314557F000041FFE349BBE0C33815557F0000415349BBA01CB314557F0000415349BB0010B314557F000041FFE349BB68C33815557F0000415349BBB01CB314557F0000415349BB0010B314557F000041FFE349BBF0C23815557F0000415349BBC01CB314557F0000415349BB0010B314557F000041FFE349BB78C23815557F0000415349BBD01CB314557F0000415349BB0010B314557F000041FFE3 +[1cffd9b146d6] jit-backend-dump} +[1cffd9b14ff3] {jit-backend-addr +Loop 0 ( #9 LOAD_FAST) has address 0x7f5514b31d30 to 0x7f5514b31e80 (bootstrap 0x7f5514b31ce0) +[1cffd9b16753] jit-backend-addr} +[1cffd9b17245] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5de1 +0 9B000000 -[3304db81160] jit-backend-dump} -[3304db81772] {jit-backend-dump +CODE_DUMP @7f5514b31de1 +0 9B000000 +[1cffd9b18103] jit-backend-dump} +[1cffd9b18762] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5df3 +0 AE000000 -[3304db8217a] jit-backend-dump} -[3304db825e3] {jit-backend-dump +CODE_DUMP @7f5514b31df3 +0 AE000000 +[1cffd9b191ae] jit-backend-dump} +[1cffd9b1960b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5dfd +0 C9000000 -[3304db82ee8] jit-backend-dump} -[3304db83330] {jit-backend-dump +CODE_DUMP @7f5514b31dfd +0 C9000000 +[1cffd9b19f1f] jit-backend-dump} +[1cffd9b1a32f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e10 +0 DB000000 -[3304db83c9d] jit-backend-dump} -[3304db840c2] {jit-backend-dump +CODE_DUMP @7f5514b31e10 +0 DB000000 +[1cffd9b1ac8d] jit-backend-dump} +[1cffd9b1b091] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e1e +0 F2000000 -[3304db849f0] jit-backend-dump} -[3304db84f62] {jit-backend-dump +CODE_DUMP @7f5514b31e1e +0 F2000000 +[1cffd9b1ba54] jit-backend-dump} +[1cffd9b1bfec] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e35 +0 25010000 -[3304db8586f] jit-backend-dump} -[3304db85c9d] {jit-backend-dump +CODE_DUMP @7f5514b31e35 +0 25010000 +[1cffd9b1c8d3] jit-backend-dump} +[1cffd9b1ccfb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e5e +0 21010000 -[3304db86572] jit-backend-dump} -[3304db869e7] {jit-backend-dump +CODE_DUMP @7f5514b31e5e +0 21010000 +[1cffd9b1d5d6] jit-backend-dump} +[1cffd9b1da25] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e74 +0 55010000 -[3304db872e3] jit-backend-dump} -[3304db88112] jit-backend} -[3304db8ae6c] {jit-log-opt-loop +CODE_DUMP @7f5514b31e74 +0 55010000 +[1cffd9b1e3b8] jit-backend-dump} +[1cffd9b1f0b2] jit-backend} +[1cffd9b20d9f] {jit-log-opt-loop # Loop 0 ( #9 LOAD_FAST) : loop with 59 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -131,17 +131,17 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944714371104)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140003404595232)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] -+279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] ++251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] ++279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] ++289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] debug_merge_point(0, 0, ' #15 COMPARE_OP') +308: i23 = getfield_gc_pure(p11, descr=) +312: i25 = int_lt(i23, 10) -guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] +guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_CONST') debug_merge_point(0, 0, ' #24 STORE_FAST') @@ -151,17 +151,17 @@ +322: i27 = int_add(i23, 1) debug_merge_point(0, 0, ' #34 STORE_FAST') debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') -+327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] -+327: i29 = getfield_raw(52008256, descr=) ++327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] ++327: i29 = getfield_raw(51804288, descr=) +335: i31 = int_lt(i29, 0) -guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] +guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(139944714371192)) ++345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(140003404595320)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +376: i32 = int_lt(i27, 10) -guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] +guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_CONST') debug_merge_point(0, 0, ' #24 STORE_FAST') @@ -171,95 +171,95 @@ +386: i33 = int_add(i27, 1) debug_merge_point(0, 0, ' #34 STORE_FAST') debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') -+390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] -+390: i35 = getfield_raw(52008256, descr=) ++390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] ++390: i35 = getfield_raw(51804288, descr=) +398: i36 = int_lt(i35, 0) -guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] +guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(139944714371192)) ++408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(140003404595320)) +416: --end of the loop-- -[3304dc0f6eb] jit-log-opt-loop} -[3304ddc81da] {jit-backend -[3304dec8bed] {jit-backend-dump +[1cffd9ba83b9] jit-log-opt-loop} +[1cffd9d7af1e] {jit-backend +[1cffd9ea4873] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBD8905D6D477F00004D8B3B4D8D770149BBD8905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38915D6D477F0000498B0B488D590149BB38915D6D477F000049891B4983F8030F85000000008138704500000F85000000004C8B40104D85C00F8400000000488B5808498B48108139005305000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A909403000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB88607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C745200000000048833C25C0021903000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425409519034883F8000F8C00000000488B856801000049BB588C026B477F00004C39D80F850000000049BB50915D6D477F00004D8B13498D420149BB50915D6D477F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE8607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C74520000000004C8B958001000049895A0848833C25C0021903000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25409519034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0D6496D477F0000415349BB08607D6A477F0000415349BB00507D6A477F000041FFE349BB708A4D6D477F0000415349BB18607D6A477F0000415349BB00507D6A477F000041FFE349BBF8894D6D477F0000415349BB28607D6A477F0000415349BB00507D6A477F000041FFE349BB80894D6D477F0000415349BB38607D6A477F0000415349BB00507D6A477F000041FFE349BB08894D6D477F0000415349BB48607D6A477F0000415349BB00507D6A477F000041FFE349BB90884D6D477F0000415349BB58607D6A477F0000415349BB00507D6A477F000041FFE349BB18884D6D477F0000415349BB68607D6A477F0000415349BB00507D6A477F000041FFE349BBA0874D6D477F0000415349BB78607D6A477F0000415349BB00507D6A477F000041FFE349BB28874D6D477F0000415349BB98607D6A477F0000415349BB85507D6A477F000041FFE349BBB0864D6D477F0000415349BBA8607D6A477F0000415349BB00507D6A477F000041FFE349BB38864D6D477F0000415349BBB8607D6A477F0000415349BB00507D6A477F000041FFE349BBC0854D6D477F0000415349BBC8607D6A477F0000415349BB00507D6A477F000041FFE349BB48854D6D477F0000415349BBD8607D6A477F0000415349BB00507D6A477F000041FFE349BBD0844D6D477F0000415349BBF8607D6A477F0000415349BB85507D6A477F000041FFE349BB58844D6D477F0000415349BB08617D6A477F0000415349BB00507D6A477F000041FFE349BBE0834D6D477F0000415349BB18617D6A477F0000415349BB00507D6A477F000041FFE3 -[3304dedb0c9] jit-backend-dump} -[3304dedb9eb] {jit-backend-addr -Loop 1 ( #13 FOR_ITER) has address 0x7f476a7d6178 to 0x7f476a7d6470 (bootstrap 0x7f476a7d6128) -[3304dedcbfe] jit-backend-addr} -[3304dedd31e] {jit-backend-dump +CODE_DUMP @7f5514b32128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD61BB314557F000041FFD349BBD8509317557F00004D8B3B4D8D770149BBD8509317557F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38519317557F0000498B0B488D590149BB38519317557F000049891B4983F8030F85000000008138E82200000F85000000004C8B40104D85C00F8400000000488B5808498B48108139685505000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A089203000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB8820B314557F00004C895D2041BBE060730041FFD3F6450401740D49BBFD11B314557F000041FFD348C745200000000048833C2500E61503000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425807816034883F8000F8C00000000488B856801000049BB584C3815557F00004C39D80F850000000049BB50519317557F00004D8B13498D420149BB50519317557F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE820B314557F00004C895D2041BBE060730041FFD3F6450401740D49BBFD11B314557F000041FFD348C74520000000004C8B958001000049895A0848833C2500E61503000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25807816034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0967F17557F0000415349BB0820B314557F0000415349BB0010B314557F000041FFE349BB704A8317557F0000415349BB1820B314557F0000415349BB0010B314557F000041FFE349BBF8498317557F0000415349BB2820B314557F0000415349BB0010B314557F000041FFE349BB80498317557F0000415349BB3820B314557F0000415349BB0010B314557F000041FFE349BB08498317557F0000415349BB4820B314557F0000415349BB0010B314557F000041FFE349BB90488317557F0000415349BB5820B314557F0000415349BB0010B314557F000041FFE349BB18488317557F0000415349BB6820B314557F0000415349BB0010B314557F000041FFE349BBA0478317557F0000415349BB7820B314557F0000415349BB0010B314557F000041FFE349BB28478317557F0000415349BB9820B314557F0000415349BB8510B314557F000041FFE349BBB0468317557F0000415349BBA820B314557F0000415349BB0010B314557F000041FFE349BB38468317557F0000415349BBB820B314557F0000415349BB0010B314557F000041FFE349BBC0458317557F0000415349BBC820B314557F0000415349BB0010B314557F000041FFE349BB48458317557F0000415349BBD820B314557F0000415349BB0010B314557F000041FFE349BBD0448317557F0000415349BBF820B314557F0000415349BB8510B314557F000041FFE349BB58448317557F0000415349BB0821B314557F0000415349BB0010B314557F000041FFE349BBE0438317557F0000415349BB1821B314557F0000415349BB0010B314557F000041FFE3 +[1cffd9ebc29f] jit-backend-dump} +[1cffd9ebcab0] {jit-backend-addr +Loop 1 ( #13 FOR_ITER) has address 0x7f5514b32178 to 0x7f5514b32470 (bootstrap 0x7f5514b32128) +[1cffd9ebde77] jit-backend-addr} +[1cffd9ebe969] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6222 +0 4A020000 -[3304dede364] jit-backend-dump} -[3304dede8d3] {jit-backend-dump +CODE_DUMP @7f5514b32222 +0 4A020000 +[1cffd9ebfa23] jit-backend-dump} +[1cffd9ec0059] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d622e +0 63020000 -[3304dedf2ce] jit-backend-dump} -[3304dedf728] {jit-backend-dump +CODE_DUMP @7f5514b3222e +0 63020000 +[1cffd9ec0ae6] jit-backend-dump} +[1cffd9ec0f4f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d623b +0 7B020000 -[3304dedffef] jit-backend-dump} -[3304dee040e] {jit-backend-dump +CODE_DUMP @7f5514b3223b +0 7B020000 +[1cffd9ec18bc] jit-backend-dump} +[1cffd9ec1d28] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d624f +0 8C020000 -[3304dee0d4e] jit-backend-dump} -[3304dee115b] {jit-backend-dump +CODE_DUMP @7f5514b3224f +0 8C020000 +[1cffd9ec2689] jit-backend-dump} +[1cffd9ec2b07] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6269 +0 97020000 -[3304dee1a98] jit-backend-dump} -[3304dee1e9f] {jit-backend-dump +CODE_DUMP @7f5514b32269 +0 97020000 +[1cffd9ec3474] jit-backend-dump} +[1cffd9ec38bc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6272 +0 B3020000 -[3304dee2789] jit-backend-dump} -[3304dee2bb1] {jit-backend-dump +CODE_DUMP @7f5514b32272 +0 B3020000 +[1cffd9ec4220] jit-backend-dump} +[1cffd9ec4677] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6291 +0 B9020000 -[3304dee34bf] jit-backend-dump} -[3304dee38cc] {jit-backend-dump +CODE_DUMP @7f5514b32291 +0 B9020000 +[1cffd9ec5011] jit-backend-dump} +[1cffd9ec5459] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d62a2 +0 CD020000 -[3304dee41c5] jit-backend-dump} -[3304dee45e1] {jit-backend-dump +CODE_DUMP @7f5514b322a2 +0 CD020000 +[1cffd9ec5e1c] jit-backend-dump} +[1cffd9ec6279] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d632d +0 67020000 -[3304dee4ec5] jit-backend-dump} -[3304dee543c] {jit-backend-dump +CODE_DUMP @7f5514b3232d +0 67020000 +[1cffd9ec6bd7] jit-backend-dump} +[1cffd9ec77c9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d635d +0 81020000 -[3304dee5d03] jit-backend-dump} -[3304dee6139] {jit-backend-dump +CODE_DUMP @7f5514b3235d +0 81020000 +[1cffd9ec8142] jit-backend-dump} +[1cffd9ec85c0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6377 +0 8C020000 -[3304dee69fa] jit-backend-dump} -[3304dee6e10] {jit-backend-dump +CODE_DUMP @7f5514b32377 +0 8C020000 +[1cffd9ecbf8d] jit-backend-dump} +[1cffd9ecc51d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d63a2 +0 86020000 -[3304dee9db8] jit-backend-dump} -[3304deea2e6] {jit-backend-dump +CODE_DUMP @7f5514b323a2 +0 86020000 +[1cffd9eccee0] jit-backend-dump} +[1cffd9ecd33a] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6426 +0 27020000 -[3304deeac17] jit-backend-dump} -[3304deeb092] {jit-backend-dump +CODE_DUMP @7f5514b32426 +0 27020000 +[1cffd9ecdc8f] jit-backend-dump} +[1cffd9ece160] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d644f +0 48020000 -[3304deeb97f] jit-backend-dump} -[3304deec304] jit-backend} -[3304deed1f1] {jit-log-opt-loop +CODE_DUMP @7f5514b3244f +0 48020000 +[1cffd9eceab8] jit-backend-dump} +[1cffd9ecf545] jit-backend} +[1cffd9ed0c35] {jit-log-opt-loop # Loop 1 ( #13 FOR_ITER) : loop with 82 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -275,53 +275,53 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944753096184)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140003443320224)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+254: guard_class(p15, 25719440, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] ++244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++254: guard_class(p15, 26177128, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] +266: p21 = getfield_gc(p15, descr=) -+270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] +279: i22 = getfield_gc(p15, descr=) +283: p23 = getfield_gc(p21, descr=) -+287: guard_class(p23, 26050592, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++287: guard_class(p23, 26517736, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] +299: p25 = getfield_gc(p21, descr=) +303: i26 = getfield_gc_pure(p25, descr=) +307: i27 = getfield_gc_pure(p25, descr=) +311: i28 = getfield_gc_pure(p25, descr=) +315: i30 = int_lt(i22, 0) -guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +325: i31 = int_ge(i22, i28) -guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +334: i32 = int_mul(i22, i27) +341: i33 = int_add(i26, i32) +347: i35 = int_add(i22, 1) +351: setfield_gc(p15, i35, descr=) -+355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] ++355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_FAST') debug_merge_point(0, 0, ' #22 LIST_APPEND') +365: p37 = getfield_gc(p13, descr=) -+369: guard_class(p37, 25936304, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] ++369: guard_class(p37, 26402184, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] +382: p39 = getfield_gc(p13, descr=) +386: i40 = getfield_gc(p39, descr=) +390: i42 = int_add(i40, 1) +394: p43 = getfield_gc(p39, descr=) +394: i44 = arraylen_gc(p43, descr=) -+394: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i42, descr=) -+506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] ++394: call(ConstClass(_ll_list_resize_ge_trampoline__v672___simple_call__function__), p39, i42, descr=) ++506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] +521: p47 = getfield_gc(p39, descr=) +532: setarrayitem_gc(p47, i40, i33, descr=) debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') -+551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] -+551: i49 = getfield_raw(52008256, descr=) ++551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++551: i49 = getfield_raw(51804288, descr=) +559: i51 = int_lt(i49, 0) -guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] -+569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] +guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] debug_merge_point(0, 0, ' #13 FOR_ITER') -+595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(140003443320312)) debug_merge_point(0, 0, ' #13 FOR_ITER') +625: i53 = int_ge(i35, i28) -guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] +guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] +638: i54 = int_mul(i35, i27) +649: i55 = int_add(i26, i54) +655: i56 = int_add(i35, 1) @@ -332,25 +332,25 @@ +663: i58 = int_add(i57, 1) +667: p59 = getfield_gc(p39, descr=) +667: i60 = arraylen_gc(p59, descr=) -+667: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i58, descr=) ++667: call(ConstClass(_ll_list_resize_ge_trampoline__v672___simple_call__function__), p39, i58, descr=) +744: setfield_gc(p15, i56, descr=) -+755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] ++755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] +770: p61 = getfield_gc(p39, descr=) +781: setarrayitem_gc(p61, i57, i55, descr=) debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') -+793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] -+793: i62 = getfield_raw(52008256, descr=) ++793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] ++793: i62 = getfield_raw(51804288, descr=) +801: i63 = int_lt(i62, 0) -guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] +guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] debug_merge_point(0, 0, ' #13 FOR_ITER') -+811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(140003443320312)) +840: --end of the loop-- -[3304df359fe] jit-log-opt-loop} -[3304df6aed1] {jit-backend-counts +[1cffd9f27224] jit-log-opt-loop} +[1cffd9f6f244] {jit-backend-counts entry 0:1 -TargetToken(139944714371104):1 -TargetToken(139944714371192):4 +TargetToken(140003404595232):1 +TargetToken(140003404595320):4 entry 1:1 -TargetToken(139944753096184):1 -TargetToken(139944753096272):4 -[3304df6da3a] jit-backend-counts} +TargetToken(140003443320224):1 +TargetToken(140003443320312):4 +[1cffd9f72430] jit-backend-counts} From noreply at buildbot.pypy.org Wed Mar 20 01:55:58 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:55:58 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: just to make sure Message-ID: <20130320005558.EA5731C13F4@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62530:a457b8cfefca Date: 2013-03-19 17:55 -0700 http://bitbucket.org/pypy/pypy/changeset/a457b8cfefca/ Log: just to make sure diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -14,7 +14,7 @@ ops = parse(''' [i7] i9 = int_lt(i7, 1003) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) ''').operations assert len(ops) == 3 @@ -137,7 +137,7 @@ ops = parse(""" [p6, p1] debug_merge_point(0, 0, ' #17 FOR_ITER') - guard_class(p6, 144264192, descr=) + guard_class(p6, 144264192, descr=) p12 = getfield_gc(p6, descr=) """ % locals()) res = Function.from_operations(ops.operations, LoopStorage()) @@ -146,7 +146,7 @@ def test_reassign_loops(): main = parse(''' [v0] - guard_false(v0, descr=) [] + guard_false(v0, descr=) [] ''') main.count = 10 bridge = parse(''' @@ -168,8 +168,8 @@ def test_adjust_bridges(): main = parse(''' [v0] - guard_false(v0, descr=) - guard_true(v0, descr=) + guard_false(v0, descr=) + guard_true(v0, descr=) ''') bridge = parse(''' # bridge out of Guard 0x1a @@ -198,7 +198,7 @@ [p0, p1, p2, p3, i4] debug_merge_point(0, 0, ' #15 COMPARE_OP') +166: i6 = int_lt(i4, 10000) - guard_true(i6, descr=) [p1, p0, p2, p3, i4] + guard_true(i6, descr=) [p1, p0, p2, p3, i4] debug_merge_point(0, 0, ' #27 INPLACE_ADD') +179: i8 = int_add(i4, 1) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') @@ -206,7 +206,7 @@ +191: i12 = int_sub(i10, 1) +195: setfield_raw(40564608, i12, descr=) +203: i14 = int_lt(i12, 0) - guard_false(i14, descr=) [p1, p0, p2, p3, i8, None] + guard_false(i14, descr=) [p1, p0, p2, p3, i8, None] debug_merge_point(0, ' #9 LOAD_FAST') +213: jump(p0, p1, p2, p3, i8, descr=) +218: --end of the loop--""", backend_dump=backend_dump, @@ -228,7 +228,7 @@ +88: label(i0, i1, p2, descr=TargetToken(1081858608)) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +116: i3 = int_lt(i0, i1) -guard_true(i3, descr=) [i1, i0, p2] +guard_true(i3, descr=) [i1, i0, p2] +124: p4 = getfield_gc(p2, descr=) +128: i5 = strgetitem(p4, i0) +136: i7 = int_eq(40, i5) @@ -241,13 +241,13 @@ +204: i18 = int_is_true(i17) +216: i19 = int_or(i10, i18) +220: i20 = int_is_true(i19) -guard_false(i20, descr=) [i1, i0, p2] +guard_false(i20, descr=) [i1, i0, p2] +228: i22 = int_add(i0, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +232: label(i22, i1, p2, p4, descr=TargetToken(1081858656)) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +264: i23 = int_lt(i22, i1) -guard_true(i23, descr=) [i1, i22, p2] +guard_true(i23, descr=) [i1, i22, p2] +272: i24 = strgetitem(p4, i22) +280: i25 = int_eq(40, i24) +296: i26 = int_eq(41, i24) @@ -259,7 +259,7 @@ +348: i32 = int_is_true(i31) +360: i33 = int_or(i27, i32) +364: i34 = int_is_true(i33) -guard_false(i34, descr=) [i1, i22, p2] +guard_false(i34, descr=) [i1, i22, p2] +372: i35 = int_add(i22, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +376: jump(i35, i1, p2, p4, descr=TargetToken(1081858656)) @@ -300,11 +300,11 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) - guard_true(i19, descr=) [] + guard_true(i19, descr=) [] i113 = getfield_raw(151937600, descr=) ''') loop.comment = 'Loop 0' @@ -321,11 +321,11 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) - guard_true(i19, descr=) [] + guard_true(i19, descr=) [] i113 = getfield_raw(151937600, descr=) ''') bridge = parse(''' From noreply at buildbot.pypy.org Wed Mar 20 01:56:00 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 01:56:00 +0100 (CET) Subject: [pypy-commit] pypy default: just to make sure Message-ID: <20130320005600.28D851C13F4@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62531:fb6f326f73df Date: 2013-03-19 17:55 -0700 http://bitbucket.org/pypy/pypy/changeset/fb6f326f73df/ Log: just to make sure diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -14,7 +14,7 @@ ops = parse(''' [i7] i9 = int_lt(i7, 1003) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) ''').operations assert len(ops) == 3 @@ -137,7 +137,7 @@ ops = parse(""" [p6, p1] debug_merge_point(0, 0, ' #17 FOR_ITER') - guard_class(p6, 144264192, descr=) + guard_class(p6, 144264192, descr=) p12 = getfield_gc(p6, descr=) """ % locals()) res = Function.from_operations(ops.operations, LoopStorage()) @@ -146,7 +146,7 @@ def test_reassign_loops(): main = parse(''' [v0] - guard_false(v0, descr=) [] + guard_false(v0, descr=) [] ''') main.count = 10 bridge = parse(''' @@ -168,8 +168,8 @@ def test_adjust_bridges(): main = parse(''' [v0] - guard_false(v0, descr=) - guard_true(v0, descr=) + guard_false(v0, descr=) + guard_true(v0, descr=) ''') bridge = parse(''' # bridge out of Guard 0x1a @@ -198,7 +198,7 @@ [p0, p1, p2, p3, i4] debug_merge_point(0, 0, ' #15 COMPARE_OP') +166: i6 = int_lt(i4, 10000) - guard_true(i6, descr=) [p1, p0, p2, p3, i4] + guard_true(i6, descr=) [p1, p0, p2, p3, i4] debug_merge_point(0, 0, ' #27 INPLACE_ADD') +179: i8 = int_add(i4, 1) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') @@ -206,7 +206,7 @@ +191: i12 = int_sub(i10, 1) +195: setfield_raw(40564608, i12, descr=) +203: i14 = int_lt(i12, 0) - guard_false(i14, descr=) [p1, p0, p2, p3, i8, None] + guard_false(i14, descr=) [p1, p0, p2, p3, i8, None] debug_merge_point(0, ' #9 LOAD_FAST') +213: jump(p0, p1, p2, p3, i8, descr=) +218: --end of the loop--""", backend_dump=backend_dump, @@ -228,7 +228,7 @@ +88: label(i0, i1, p2, descr=TargetToken(1081858608)) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +116: i3 = int_lt(i0, i1) -guard_true(i3, descr=) [i1, i0, p2] +guard_true(i3, descr=) [i1, i0, p2] +124: p4 = getfield_gc(p2, descr=) +128: i5 = strgetitem(p4, i0) +136: i7 = int_eq(40, i5) @@ -241,13 +241,13 @@ +204: i18 = int_is_true(i17) +216: i19 = int_or(i10, i18) +220: i20 = int_is_true(i19) -guard_false(i20, descr=) [i1, i0, p2] +guard_false(i20, descr=) [i1, i0, p2] +228: i22 = int_add(i0, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +232: label(i22, i1, p2, p4, descr=TargetToken(1081858656)) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +264: i23 = int_lt(i22, i1) -guard_true(i23, descr=) [i1, i22, p2] +guard_true(i23, descr=) [i1, i22, p2] +272: i24 = strgetitem(p4, i22) +280: i25 = int_eq(40, i24) +296: i26 = int_eq(41, i24) @@ -259,7 +259,7 @@ +348: i32 = int_is_true(i31) +360: i33 = int_or(i27, i32) +364: i34 = int_is_true(i33) -guard_false(i34, descr=) [i1, i22, p2] +guard_false(i34, descr=) [i1, i22, p2] +372: i35 = int_add(i22, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +376: jump(i35, i1, p2, p4, descr=TargetToken(1081858656)) @@ -300,11 +300,11 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) - guard_true(i19, descr=) [] + guard_true(i19, descr=) [] i113 = getfield_raw(151937600, descr=) ''') loop.comment = 'Loop 0' @@ -321,11 +321,11 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) - guard_true(i19, descr=) [] + guard_true(i19, descr=) [] i113 = getfield_raw(151937600, descr=) ''') bridge = parse(''' From noreply at buildbot.pypy.org Wed Mar 20 01:56:28 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Mar 2013 01:56:28 +0100 (CET) Subject: [pypy-commit] pypy py3k: initialize the locale before fsdecoding Message-ID: <20130320005628.C68E81C13F4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62532:1df60071a1fe Date: 2013-03-19 17:52 -0700 http://bitbucket.org/pypy/pypy/changeset/1df60071a1fe/ Log: initialize the locale before fsdecoding diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -10,6 +10,10 @@ from pypy.tool.option import make_objspace from pypy.conftest import pypydir +_WIN32 = sys.platform == 'win32' +if not _WIN32: + from rpython.rlib.rlocale import LC_ALL, setlocale + thisdir = py.path.local(__file__).dirpath() try: @@ -49,9 +53,14 @@ try: try: space.call_function(w_run_toplevel, w_call_startup_gateway) + if not _WIN32: + oldlocale = setlocale(LC_ALL, None) + setlocale(LC_ALL, '') w_executable = space.fsdecode(space.wrapbytes(argv[0])) w_argv = space.newlist([space.fsdecode(space.wrapbytes(s)) for s in argv[1:]]) + if not _WIN32: + setlocale(LC_ALL, oldlocale) w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) exitcode = space.int_w(w_exitcode) # try to pull it all in From noreply at buildbot.pypy.org Wed Mar 20 02:00:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 02:00:42 +0100 (CET) Subject: [pypy-commit] jitviewer default: update Message-ID: <20130320010042.52BC91C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r217:73be4e5960a6 Date: 2013-03-19 18:00 -0700 http://bitbucket.org/pypy/jitviewer/changeset/73be4e5960a6/ Log: update diff too long, truncating to 2000 out of 4474 lines diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -220,6 +220,7 @@ parse_log_counts(extract_category(log, 'jit-backend-count'), loops) storage.loops = [loop for loop in loops if not loop.descr.startswith('bridge')] + storage.reconnect_loops(storage.loops) storage.loop_dict = create_loop_dict(loops) app = OverrideFlask('_jitviewer') server = Server(filename, storage) diff --git a/log.pypylog b/log.pypylog --- a/log.pypylog +++ b/log.pypylog @@ -1,121 +1,121 @@ -[230587c52823] {jit-backend-dump +[1ce3a81d0bf7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[230587c63451] jit-backend-dump} -[230587c691fa] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1ce3a81e1ef9] jit-backend-dump} +[1ce3a81e8972] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[230587c6bb6a] jit-backend-dump} -[230587c707c4] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1ce3a81eb566] jit-backend-dump} +[1ce3a81ee823] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c12e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[230587c72437] jit-backend-dump} -[230587c744c6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e12e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1ce3a81f04ef] jit-backend-dump} +[1ce3a81f2d06] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[230587c7619e] jit-backend-dump} -[230587c78f6b] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1ce3a81f4c86] jit-backend-dump} +[1ce3a81f85ce] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c1fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C25C80219034C8B2425C002190348C70425C00219030000000048C70425C80219030000000041BBC069120141FFD3F20F10442418488B44240848891C25C80219034C892425C0021903488B5C24284C8B642430488D642438C3 -[230587c7ad96] jit-backend-dump} -[230587c7d700] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e1fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 +[1ce3a81fa494] jit-backend-dump} +[1ce3a81fe75a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C25C802190348894D38488B1C25C002190348C70425C00219030000000048C70425C80219030000000041BB90E3E80041FFD34889C5488B4D3848C745380000000048890C25C802190348891C25C00219034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[230587c81da4] jit-backend-dump} -[230587c82f7e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[1ce3a8203464] jit-backend-dump} +[1ce3a82046fc] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[230587c85915] jit-backend-dump} -[230587c86b77] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1ce3a820724d] jit-backend-dump} +[1ce3a82087e7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[230587c95952] jit-backend-dump} -[230587c97358] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1ce3a821855b] jit-backend-dump} +[1ce3a821a1ef] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c6bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[230587c9a7a5] jit-backend-dump} -[230587c9bec1] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e6bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1ce3a821d5e3] jit-backend-dump} +[1ce3a821ec8b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c81e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[230587c9f1fd] jit-backend-dump} -[230587ca01cf] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e81e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1ce3a82221b7] jit-backend-dump} +[1ce3a82233d9] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c988 +0 488B0425C802190348C70425C00219030000000048C70425C8021903000000004889453848C745108064B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[230587ca195f] jit-backend-dump} -[230587ca72e6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1ce3a8224b24] jit-backend-dump} +[1ce3a822aa70] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1c9e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBF0ACE80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFDC1C11F5C7F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25C8EEB50148C7452000000000C34883C40849BB88C9C11F5C7F000041FFE3 -[230587cab5d6] jit-backend-dump} -[230587cad4e3] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17e9e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFDE1179E467F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB88E9179E467F000041FFE3 +[1ce3a822ee4e] jit-backend-dump} +[1ce3a82310c7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1cbd6 +0 4889E74883EC0841BB9018210141FFD34883C408488B0425C00219034885C07501C34883C40849BB88C9C11F5C7F000041FFE3 -[230587caea2c] jit-backend-dump} -[230587caef92] {jit-backend-counts -[230587caf375] jit-backend-counts} -[23058821c205] {jit-backend -[23058846e9f5] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ebd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB88E9179E467F000041FFE3 +[1ce3a823258e] jit-backend-dump} +[1ce3a8232c9f] {jit-backend-counts +[1ce3a8233062] jit-backend-counts} +[1ce3a89027aa] {jit-backend +[1ce3a8be3976] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1cce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD6CBC11F5C7F000041FFD349BBF010AA225C7F00004D8B3B4D8D770149BBF010AA225C7F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB0811AA225C7F0000498B03488D500149BB0811AA225C7F00004989134983F8010F85000000004883FB017206813B680B00000F85000000004983FA000F850000000049BB10ED4E205C7F00004D39DC0F85000000004C8B63084981FC4F0400000F8D00000000498D5C24014C8B2425409519034983FC000F8C0000000049BB2011AA225C7F00004D8B234D8D54240149BB2011AA225C7F00004D89134881FB4F0400000F8D000000004C8D5301488B1C25409519034883FB000F8C000000004C89D3E9B6FFFFFF49BBF829D41F5C7F0000415349BB40CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBD033D41F5C7F0000415349BB50CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB5833D41F5C7F0000415349BB60CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE032D41F5C7F0000415349BB70CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB6832D41F5C7F0000415349BB80CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF031D41F5C7F0000415349BB90CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB7831D41F5C7F0000415349BBA0CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB0031D41F5C7F0000415349BBB0CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB8830D41F5C7F0000415349BBC0CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB1030D41F5C7F0000415349BBD0CCC11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[23058848539c] jit-backend-dump} -[230588485ca1] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 0x7f5c1fc1cd30 to 0x7f5c1fc1ce7b (bootstrap 0x7f5c1fc1cce0) -[23058848737f] jit-backend-addr} -[230588487cdd] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ece0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BBF03000A1467F00004D8B3B4D8D770149BBF03000A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB083100A1467F0000498B03488D500149BB083100A1467F00004989134983F8010F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB100DA59E467F00004D39DC0F85000000004C8B63084981FC4F0400000F8D00000000498D5C24014C8B2425807816034983FC000F8C0000000049BB203100A1467F00004D8B234D8D54240149BB203100A1467F00004D89134881FB4F0400000F8D000000004C8D5301488B1C25807816034883FB000F8C000000004C89D3E9B6FFFFFF49BBF8492A9E467F0000415349BB40EC179E467F0000415349BB00E0179E467F000041FFE349BBD0532A9E467F0000415349BB50EC179E467F0000415349BB00E0179E467F000041FFE349BB58532A9E467F0000415349BB60EC179E467F0000415349BB00E0179E467F000041FFE349BBE0522A9E467F0000415349BB70EC179E467F0000415349BB00E0179E467F000041FFE349BB68522A9E467F0000415349BB80EC179E467F0000415349BB00E0179E467F000041FFE349BBF0512A9E467F0000415349BB90EC179E467F0000415349BB00E0179E467F000041FFE349BB78512A9E467F0000415349BBA0EC179E467F0000415349BB00E0179E467F000041FFE349BB00512A9E467F0000415349BBB0EC179E467F0000415349BB00E0179E467F000041FFE349BB88502A9E467F0000415349BBC0EC179E467F0000415349BB00E0179E467F000041FFE349BB10502A9E467F0000415349BBD0EC179E467F0000415349BB00E0179E467F000041FFE3 +[1ce3a8bfbea3] jit-backend-dump} +[1ce3a8bfca00] {jit-backend-addr +Loop 0 ( #9 LOAD_FAST) has address 0x7f469e17ed30 to 0x7f469e17ee7b (bootstrap 0x7f469e17ece0) +[1ce3a8bfe00b] jit-backend-addr} +[1ce3a8bfea4e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1cdd6 +0 A1000000 -[230588488b56] jit-backend-dump} -[230588489145] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17edd6 +0 A1000000 +[1ce3a8bff959] jit-backend-dump} +[1ce3a8c0004d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1cde8 +0 B4000000 -[230588489b2e] jit-backend-dump} -[230588489f5f] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ede8 +0 B4000000 +[1ce3a8c00a8f] jit-backend-dump} +[1ce3a8c00f2b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1cdf2 +0 CF000000 -[23058848a904] jit-backend-dump} -[23058848ad26] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17edf2 +0 CF000000 +[1ce3a8c018fa] jit-backend-dump} +[1ce3a8c01d69] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ce05 +0 E1000000 -[23058848b640] jit-backend-dump} -[23058848ba76] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ee05 +0 E1000000 +[1ce3a8c02720] jit-backend-dump} +[1ce3a8c02b74] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ce16 +0 F5000000 -[23058848c346] jit-backend-dump} -[23058848c8a8] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ee16 +0 F5000000 +[1ce3a8c035c9] jit-backend-dump} +[1ce3a8c03dd4] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ce2d +0 28010000 -[23058848d18c] jit-backend-dump} -[23058848d5c0] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ee2d +0 28010000 +[1ce3a8c04867] jit-backend-dump} +[1ce3a8c04d0c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ce59 +0 21010000 -[23058848dec2] jit-backend-dump} -[23058848e346] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ee59 +0 21010000 +[1ce3a8c05757] jit-backend-dump} +[1ce3a8c05c99] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ce6f +0 55010000 -[23058848ec39] jit-backend-dump} -[23058848f80a] jit-backend} -[230588491ca6] {jit-log-opt-loop +SYS_EXECUTABLE python +CODE_DUMP @7f469e17ee6f +0 55010000 +[1ce3a8c06645] jit-backend-dump} +[1ce3a8c0767f] jit-backend} +[1ce3a8c09553] {jit-log-opt-loop # Loop 0 ( #9 LOAD_FAST) : loop with 54 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -130,17 +130,17 @@ +160: p13 = getarrayitem_gc(p9, 1, descr=) +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p16 = getfield_gc(p0, descr=) -+168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(140033647686320)) ++168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(139941277979224)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] -+250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] -+268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] ++240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] ++250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] ++268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] ++278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] debug_merge_point(0, 0, ' #15 COMPARE_OP') +297: i21 = getfield_gc_pure(p11, descr=) +301: i23 = int_lt(i21, 1103) -guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] +guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_FAST') debug_merge_point(0, 0, ' #24 LOAD_CONST') @@ -148,17 +148,17 @@ +314: i25 = int_add(i21, 1) debug_merge_point(0, 0, ' #28 STORE_FAST') debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+319: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i25] -+319: i27 = getfield_raw(52008256, descr=) ++319: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i25] ++319: i27 = getfield_raw(51804288, descr=) +327: i29 = int_lt(i27, 0) -guard_false(i29, descr=) [p1, p0, p2, p3, p6, i25] +guard_false(i29, descr=) [p1, p0, p2, p3, p6, i25] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+337: label(p0, p1, p2, p3, p6, i25, descr=TargetToken(140033647686408)) ++337: label(p0, p1, p2, p3, p6, i25, descr=TargetToken(139941277979312)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +368: i30 = int_lt(i25, 1103) -guard_true(i30, descr=) [p1, p0, p2, p3, p6, i25] +guard_true(i30, descr=) [p1, p0, p2, p3, p6, i25] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_FAST') debug_merge_point(0, 0, ' #24 LOAD_CONST') @@ -166,85 +166,85 @@ +381: i31 = int_add(i25, 1) debug_merge_point(0, 0, ' #28 STORE_FAST') debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+385: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i31, None] -+385: i33 = getfield_raw(52008256, descr=) ++385: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i31, None] ++385: i33 = getfield_raw(51804288, descr=) +393: i34 = int_lt(i33, 0) -guard_false(i34, descr=) [p1, p0, p2, p3, p6, i31, None] +guard_false(i34, descr=) [p1, p0, p2, p3, p6, i31, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+403: jump(p0, p1, p2, p3, p6, i31, descr=TargetToken(140033647686408)) ++403: jump(p0, p1, p2, p3, p6, i31, descr=TargetToken(139941277979312)) +411: --end of the loop-- -[230588512b10] jit-log-opt-loop} -[2305887fbbbc] {jit-backend -[23058892381b] {jit-backend-dump +[1ce3a8ca19fa] jit-log-opt-loop} +[1ce3a903b35c] {jit-backend +[1ce3a91672ee] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d100 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD6CBC11F5C7F000041FFD349BBD810AA225C7F00004D8B3B4D8D770149BBD810AA225C7F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB3811AA225C7F0000498B03488D500149BB3811AA225C7F00004989134983F8010F85000000004883FB017206813B680B00000F85000000004983FA000F850000000049BB80EE4E205C7F00004D39DC0F85000000004C8B63084981FC4F0400000F8D000000004D8B560849BBC8E048205C7F00004D39DA0F85000000004D8B421049BBA82E4E205C7F00004D39D80F850000000048899D380100004C89B56001000049BB80D0C11F5C7F00004C895D2041BB0080840041FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C74520000000004C8B70504889EB4C8B50604D85D20F85000000004C8B50404983FA000F85000000004D8D5424014C8B2425409519034983FC000F8C0000000049BB5011AA225C7F00004D8B234D8D74240149BB5011AA225C7F00004D89334981FA4F0400000F8D000000004D8D72014C8B1425409519034983FA000F8C000000004D89F2E9B6FFFFFF49BBF0F1D61F5C7F0000415349BB00D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB404DD81F5C7F0000415349BB10D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBC84CD81F5C7F0000415349BB20D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB504CD81F5C7F0000415349BB30D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBD84BD81F5C7F0000415349BB40D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB604BD81F5C7F0000415349BB50D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE84AD81F5C7F0000415349BB60D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB704AD81F5C7F0000415349BB70D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF849D81F5C7F0000415349BB90D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB8049D81F5C7F0000415349BBA0D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB0849D81F5C7F0000415349BBB0D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB9048D81F5C7F0000415349BBC0D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB1848D81F5C7F0000415349BBD0D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBA047D81F5C7F0000415349BBE0D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB2847D81F5C7F0000415349BBF0D0C11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[23058893b3d8] jit-backend-dump} -[23058893be12] {jit-backend-addr -Loop 1 ( #9 LOAD_FAST) has address 0x7f5c1fc1d150 to 0x7f5c1fc1d32b (bootstrap 0x7f5c1fc1d100) -[23058893d792] jit-backend-addr} -[23058893e191] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f100 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BBD83000A1467F00004D8B3B4D8D770149BBD83000A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB383100A1467F0000498B03488D500149BB383100A1467F00004989134983F8010F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB800EA59E467F00004D39DC0F85000000004C8B63084981FC4F0400000F8D000000004D8B560849BBC8009F9E467F00004D39DA0F85000000004D8B421049BBA84EA49E467F00004D39D80F85000000004C89B53801000048899D6001000049BB80F0179E467F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDE1179E467F000041FFD348C7452000000000488B58504989EE4C8B50604D85D20F85000000004C8B50404983FA000F85000000004D8D5424014C8B2425807816034983FC000F8C0000000049BB503100A1467F00004D8B234D8D74240149BB503100A1467F00004D89334981FA4F0400000F8D000000004D8D72014C8B1425807816034983FA000F8C000000004D89F2E9B6FFFFFF49BBF0112D9E467F0000415349BB00F0179E467F0000415349BB00E0179E467F000041FFE349BB406D2E9E467F0000415349BB10F0179E467F0000415349BB00E0179E467F000041FFE349BBC86C2E9E467F0000415349BB20F0179E467F0000415349BB00E0179E467F000041FFE349BB506C2E9E467F0000415349BB30F0179E467F0000415349BB00E0179E467F000041FFE349BBD86B2E9E467F0000415349BB40F0179E467F0000415349BB00E0179E467F000041FFE349BB606B2E9E467F0000415349BB50F0179E467F0000415349BB00E0179E467F000041FFE349BBE86A2E9E467F0000415349BB60F0179E467F0000415349BB00E0179E467F000041FFE349BB706A2E9E467F0000415349BB70F0179E467F0000415349BB00E0179E467F000041FFE349BBF8692E9E467F0000415349BB90F0179E467F0000415349BB00E0179E467F000041FFE349BB80692E9E467F0000415349BBA0F0179E467F0000415349BB00E0179E467F000041FFE349BB08692E9E467F0000415349BBB0F0179E467F0000415349BB00E0179E467F000041FFE349BB90682E9E467F0000415349BBC0F0179E467F0000415349BB00E0179E467F000041FFE349BB18682E9E467F0000415349BBD0F0179E467F0000415349BB00E0179E467F000041FFE349BBA0672E9E467F0000415349BBE0F0179E467F0000415349BB00E0179E467F000041FFE349BB28672E9E467F0000415349BBF0F0179E467F0000415349BB00E0179E467F000041FFE3 +[1ce3a917f7da] jit-backend-dump} +[1ce3a918019d] {jit-backend-addr +Loop 1 ( #9 LOAD_FAST) has address 0x7f469e17f150 to 0x7f469e17f32b (bootstrap 0x7f469e17f100) +[1ce3a9181915] jit-backend-addr} +[1ce3a918245a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d1f6 +0 31010000 -[23058893f084] jit-backend-dump} -[23058893f9d3] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f1f6 +0 31010000 +[1ce3a91833b0] jit-backend-dump} +[1ce3a9183a06] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d208 +0 44010000 -[2305889405b9] jit-backend-dump} -[230588940a6f] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f208 +0 44010000 +[1ce3a91843e1] jit-backend-dump} +[1ce3a9184844] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d212 +0 5F010000 -[230588941535] jit-backend-dump} -[230588941a65] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f212 +0 5F010000 +[1ce3a9185196] jit-backend-dump} +[1ce3a9185608] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d225 +0 71010000 -[230588942454] jit-backend-dump} -[23058894288b] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f225 +0 71010000 +[1ce3a91860ad] jit-backend-dump} +[1ce3a9186507] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d236 +0 85010000 -[230588943260] jit-backend-dump} -[2305889436ae] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f236 +0 85010000 +[1ce3a9186ee2] jit-backend-dump} +[1ce3a9187333] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d24d +0 93010000 -[230588944065] jit-backend-dump} -[230588944560] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f24d +0 93010000 +[1ce3a9187c8e] jit-backend-dump} +[1ce3a91880e0] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d264 +0 A1010000 -[230588944ee8] jit-backend-dump} -[230588945500] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f264 +0 A1010000 +[1ce3a9188a61] jit-backend-dump} +[1ce3a918907f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d2b8 +0 97010000 -[230588945f60] jit-backend-dump} -[2305889463c9] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f2b8 +0 97010000 +[1ce3a91899d1] jit-backend-dump} +[1ce3a9189e52] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d2c6 +0 AE010000 -[230588946d92] jit-backend-dump} -[23058894726f] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f2c6 +0 AE010000 +[1ce3a918a7bf] jit-backend-dump} +[1ce3a918acbd] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d2dd +0 E1010000 -[230588947c20] jit-backend-dump} -[230588948089] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f2dd +0 E1010000 +[1ce3a918b62c] jit-backend-dump} +[1ce3a918baad] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d309 +0 DA010000 -[2305889489f3] jit-backend-dump} -[230588948e86] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f309 +0 DA010000 +[1ce3a918c467] jit-backend-dump} +[1ce3a918c8eb] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d31f +0 0E020000 -[2305889497f6] jit-backend-dump} -[23058894a593] jit-backend} -[23058894beea] {jit-log-opt-loop +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f31f +0 0E020000 +[1ce3a918d25e] jit-backend-dump} +[1ce3a918df82] jit-backend} +[1ce3a918f7df] {jit-log-opt-loop # Loop 1 ( #9 LOAD_FAST) : loop with 77 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -259,34 +259,34 @@ +160: p13 = getarrayitem_gc(p9, 1, descr=) +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p16 = getfield_gc(p0, descr=) -+168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(140033647687464)) ++168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(139941277980368)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] -+250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] -+268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] ++240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] ++250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] ++268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] ++278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] debug_merge_point(0, 0, ' #15 COMPARE_OP') +297: i21 = getfield_gc_pure(p11, descr=) +301: i23 = int_lt(i21, 1103) -guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] +guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_GLOBAL') +314: p24 = getfield_gc(p0, descr=) -+318: guard_value(p24, ConstPtr(ptr25), descr=) [p1, p0, p24, p2, p3, p6, p11] ++318: guard_value(p24, ConstPtr(ptr25), descr=) [p1, p0, p24, p2, p3, p6, p11] +337: p26 = getfield_gc(p24, descr=) -+341: guard_value(p26, ConstPtr(ptr27), descr=) [p1, p0, p26, p24, p2, p3, p6, p11] -+360: guard_not_invalidated(descr=) [p1, p0, p24, p2, p3, p6, p11] ++341: guard_value(p26, ConstPtr(ptr27), descr=) [p1, p0, p26, p24, p2, p3, p6, p11] ++360: guard_not_invalidated(descr=) [p1, p0, p24, p2, p3, p6, p11] debug_merge_point(0, 0, ' #24 LOAD_FAST') debug_merge_point(0, 0, ' #27 CALL_FUNCTION') +360: p29 = call(ConstClass(getexecutioncontext), descr=) +424: p30 = getfield_gc(p29, descr=) +428: p31 = force_token() +431: p32 = getfield_gc(p29, descr=) -+435: guard_isnull(p32, descr=) [p1, p0, p29, p32, p2, p3, p6, p11, p31, p30] ++435: guard_isnull(p32, descr=) [p1, p0, p29, p32, p2, p3, p6, p11, p30, p31] +444: i33 = getfield_gc(p29, descr=) +448: i34 = int_is_zero(i33) -guard_true(i34, descr=) [p1, p0, p29, p2, p3, p6, p11, p31, p30] +guard_true(i34, descr=) [p1, p0, p29, p2, p3, p6, p11, p30, p31] debug_merge_point(1, 1, ' #0 LOAD_FAST') debug_merge_point(1, 1, ' #3 LOAD_CONST') debug_merge_point(1, 1, ' #6 BINARY_ADD') @@ -294,21 +294,21 @@ debug_merge_point(1, 1, ' #7 RETURN_VALUE') debug_merge_point(0, 0, ' #30 STORE_FAST') debug_merge_point(0, 0, ' #33 JUMP_ABSOLUTE') -+463: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36, None, None] -+463: i39 = getfield_raw(52008256, descr=) ++463: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36, None, None] ++463: i39 = getfield_raw(51804288, descr=) +471: i41 = int_lt(i39, 0) -guard_false(i41, descr=) [p1, p0, p2, p3, p6, i36, None, None] +guard_false(i41, descr=) [p1, p0, p2, p3, p6, i36, None, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') +481: p42 = same_as(ConstPtr(ptr27)) -+481: label(p0, p1, p2, p3, p6, i36, descr=TargetToken(140033647687552)) ++481: label(p0, p1, p2, p3, p6, i36, descr=TargetToken(139941277980456)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +512: i43 = int_lt(i36, 1103) -guard_true(i43, descr=) [p1, p0, p2, p3, p6, i36] +guard_true(i43, descr=) [p1, p0, p2, p3, p6, i36] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_GLOBAL') -+525: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36] ++525: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36] debug_merge_point(0, 0, ' #24 LOAD_FAST') debug_merge_point(0, 0, ' #27 CALL_FUNCTION') +525: p44 = force_token() @@ -319,109 +319,109 @@ debug_merge_point(1, 1, ' #7 RETURN_VALUE') debug_merge_point(0, 0, ' #30 STORE_FAST') debug_merge_point(0, 0, ' #33 JUMP_ABSOLUTE') -+529: i46 = getfield_raw(52008256, descr=) ++529: i46 = getfield_raw(51804288, descr=) +537: i47 = int_lt(i46, 0) -guard_false(i47, descr=) [p1, p0, p2, p3, p6, i45, None] +guard_false(i47, descr=) [p1, p0, p2, p3, p6, i45, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+547: jump(p0, p1, p2, p3, p6, i45, descr=TargetToken(140033647687552)) ++547: jump(p0, p1, p2, p3, p6, i45, descr=TargetToken(139941277980456)) +555: --end of the loop-- -[2305889955f6] jit-log-opt-loop} -[2305889b471c] {jit-backend-dump +[1ce3a91d8ed9] jit-log-opt-loop} +[1ce3a91f3c53] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d268 +0 E9C1010000 -[2305889b64ed] jit-backend-dump} -[2305889b6c05] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f268 +0 E9C1010000 +[1ce3a91f56a9] jit-backend-dump} +[1ce3a91f5c6e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d2cf +0 E9C9010000 -[2305889b77a6] jit-backend-dump} -[2305889b7bf8] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f2cf +0 E9C9010000 +[1ce3a91f6793] jit-backend-dump} +[1ce3a91f6bf6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d30d +0 E9FA010000 -[2305889b87c0] jit-backend-dump} -[230588d6c246] {jit-backend -[230588e769ad] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f30d +0 E9FA010000 +[1ce3a91f761e] jit-backend-dump} +[1ce3a97dca13] {jit-backend +[1ce3a98bbdbb] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d668 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD6CBC11F5C7F000041FFD349BB6811AA225C7F00004D8B3B4D8D770149BB6811AA225C7F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C898D480100004C8B4E304C89BD500100004C89AD580100004889BD600100004889956801000048898D700100004C898D7801000049BB8011AA225C7F00004D8B0B498D490149BB8011AA225C7F000049890B4983F8030F85000000008138704500000F85000000004C8B40104D85C00F8400000000488B48084D8B4810418139005305000F85000000004D8B48084D8B4108498B5110498B79184883F9000F8C000000004839F90F8D000000004989C9480FAFCA4D89C54901C8498D4901488948084983FA000F85000000004883FB017206813B680B00000F850000000049BB38EF4E205C7F00004D39DC0F85000000004C8B63084983C4010F8000000000488B1C25409519034883FB000F8C000000004C89856001000049BB9811AA225C7F00004D8B03498D580149BB9811AA225C7F000049891B4839F90F8D000000004889CB480FAFCA4D89E84901CD488D4B01488948084C89E34983C4010F8000000000488B1C25409519034883FB000F8C000000004C89AD600100004D89C5E996FFFFFF49BBA84ED81F5C7F0000415349BB68D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB9048D91F5C7F0000415349BB78D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBA047D91F5C7F0000415349BB88D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB2847D91F5C7F0000415349BB98D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBB046D91F5C7F0000415349BBA8D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB3846D91F5C7F0000415349BBB8D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBC045D91F5C7F0000415349BBC8D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB4845D91F5C7F0000415349BBD8D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBD044D91F5C7F0000415349BBE8D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB5844D91F5C7F0000415349BBF8D5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE043D91F5C7F0000415349BB08D6C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB6843D91F5C7F0000415349BB18D6C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF042D91F5C7F0000415349BB28D6C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB7842D91F5C7F0000415349BB38D6C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB0042D91F5C7F0000415349BB48D6C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB8841D91F5C7F0000415349BB58D6C11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[230588ed281a] jit-backend-dump} -[230588ed386c] {jit-backend-addr -Loop 2 ( #19 FOR_ITER) has address 0x7f5c1fc1d6b8 to 0x7f5c1fc1d897 (bootstrap 0x7f5c1fc1d668) -[230588ed7ace] jit-backend-addr} -[230588ed8bcc] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f668 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BB683100A1467F00004D8B3B4D8D770149BB683100A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89AD480100004C8B6E304C89BD500100004C898D580100004889BD600100004889956801000048898D700100004C89AD7801000049BB803100A1467F00004D8B2B498D4D0149BB803100A1467F000049890B4983F8030F85000000008138E82200000F85000000004C8B40104D85C00F8400000000488B48084D8B681041817D00685505000F85000000004D8B68084D8B4508498B5510498B7D184883F9000F8C000000004839F90F8D000000004989CD480FAFCA4D89C14901C8498D4D01488948084983FA000F85000000004883FB017206813B180C00000F850000000049BB380FA59E467F00004D39DC0F85000000004C8B63084983C4010F8000000000488B1C25807816034883FB000F8C000000004C89856001000049BB983100A1467F00004D8B03498D580149BB983100A1467F000049891B4839F90F8D000000004889CB480FAFCA4D89C84901C9488D4B01488948084C89E34983C4010F8000000000488B1C25807816034883FB000F8C000000004C898D600100004D89C1E996FFFFFF49BBA86E2E9E467F0000415349BB68F5179E467F0000415349BB00E0179E467F000041FFE349BB90882F9E467F0000415349BB78F5179E467F0000415349BB00E0179E467F000041FFE349BBA0872F9E467F0000415349BB88F5179E467F0000415349BB00E0179E467F000041FFE349BB28872F9E467F0000415349BB98F5179E467F0000415349BB00E0179E467F000041FFE349BBB0862F9E467F0000415349BBA8F5179E467F0000415349BB00E0179E467F000041FFE349BB38862F9E467F0000415349BBB8F5179E467F0000415349BB00E0179E467F000041FFE349BBC0852F9E467F0000415349BBC8F5179E467F0000415349BB00E0179E467F000041FFE349BB48852F9E467F0000415349BBD8F5179E467F0000415349BB00E0179E467F000041FFE349BBD0842F9E467F0000415349BBE8F5179E467F0000415349BB00E0179E467F000041FFE349BB58842F9E467F0000415349BBF8F5179E467F0000415349BB00E0179E467F000041FFE349BBE0832F9E467F0000415349BB08F6179E467F0000415349BB00E0179E467F000041FFE349BB68832F9E467F0000415349BB18F6179E467F0000415349BB00E0179E467F000041FFE349BBF0822F9E467F0000415349BB28F6179E467F0000415349BB00E0179E467F000041FFE349BB78822F9E467F0000415349BB38F6179E467F0000415349BB00E0179E467F000041FFE349BB00822F9E467F0000415349BB48F6179E467F0000415349BB00E0179E467F000041FFE349BB88812F9E467F0000415349BB58F6179E467F0000415349BB00E0179E467F000041FFE3 +[1ce3a98d2d3c] jit-backend-dump} +[1ce3a98d3611] {jit-backend-addr +Loop 2 ( #19 FOR_ITER) has address 0x7f469e17f6b8 to 0x7f469e17f898 (bootstrap 0x7f469e17f668) +[1ce3a98d4877] jit-backend-addr} +[1ce3a98d517f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d76d +0 26010000 -[230588eda1fd] jit-backend-dump} -[230588eda898] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f76d +0 27010000 +[1ce3a98d60e6] jit-backend-dump} +[1ce3a98d672e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d779 +0 3F010000 -[230588edbe82] jit-backend-dump} -[230588edc5c6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f779 +0 40010000 +[1ce3a98d7185] jit-backend-dump} +[1ce3a98d7577] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d786 +0 57010000 -[230588edcf83] jit-backend-dump} -[230588edd3a5] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f786 +0 58010000 +[1ce3a98d7f7c] jit-backend-dump} +[1ce3a98d8374] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d79b +0 67010000 -[230588ede403] jit-backend-dump} -[230588ede848] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f79c +0 67010000 +[1ce3a98d8c3a] jit-backend-dump} +[1ce3a98d903e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d7b5 +0 72010000 -[230588edf13b] jit-backend-dump} -[230588edf557] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f7b6 +0 72010000 +[1ce3a98d98f9] jit-backend-dump} +[1ce3a98d9ceb] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d7be +0 8E010000 -[230588ee058e] jit-backend-dump} -[230588ee09b6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f7bf +0 8E010000 +[1ce3a98da5d2] jit-backend-dump} +[1ce3a98da9c5] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d7dd +0 94010000 -[230588ee12ac] jit-backend-dump} -[230588ee16dc] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f7de +0 94010000 +[1ce3a98db297] jit-backend-dump} +[1ce3a98db69b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d7ef +0 A7010000 -[230588ee22d7] jit-backend-dump} -[230588ee2afd] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f7f0 +0 A7010000 +[1ce3a98dbf3e] jit-backend-dump} +[1ce3a98dc339] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d802 +0 B9010000 -[230588ee3700] jit-backend-dump} -[230588ee474c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f803 +0 B9010000 +[1ce3a98dcc7c] jit-backend-dump} +[1ce3a98dd103] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d810 +0 D0010000 -[230588ee504e] jit-backend-dump} -[230588ee5d0a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f811 +0 D0010000 +[1ce3a98dd9cc] jit-backend-dump} +[1ce3a98ddf6e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d822 +0 08020000 -[230588ee6611] jit-backend-dump} -[230588ee6a60] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f823 +0 08020000 +[1ce3a98de85e] jit-backend-dump} +[1ce3a98dec7c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d850 +0 FF010000 -[230588ee79d0] jit-backend-dump} -[230588ee8457] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f851 +0 FF010000 +[1ce3a98df51c] jit-backend-dump} +[1ce3a98df9cd] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d872 +0 02020000 -[230588ee8ef9] jit-backend-dump} -[230588ee96e0] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f873 +0 02020000 +[1ce3a98e033f] jit-backend-dump} +[1ce3a98e08d8] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d884 +0 3A020000 -[230588eea120] jit-backend-dump} -[230588eec4f8] jit-backend} -[230588ef2086] {jit-log-opt-loop +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f885 +0 3A020000 +[1ce3a98e1696] jit-backend-dump} +[1ce3a98e22f2] jit-backend} +[1ce3a98e35cc] {jit-log-opt-loop # Loop 2 ( #19 FOR_ITER) : loop with 74 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -438,154 +438,154 @@ +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p19 = getarrayitem_gc(p9, 4, descr=) +183: p20 = getfield_gc(p0, descr=) -+183: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, descr=TargetToken(140033647688080)) ++183: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, descr=TargetToken(139941277980984)) debug_merge_point(0, 0, ' #19 FOR_ITER') -+255: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19] -+265: guard_class(p15, 25719440, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++255: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19] ++265: guard_class(p15, 26177128, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17, p19] +277: p23 = getfield_gc(p15, descr=) -+281: guard_nonnull(p23, descr=) [p1, p0, p15, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++281: guard_nonnull(p23, descr=) [p1, p0, p15, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] +290: i24 = getfield_gc(p15, descr=) +294: p25 = getfield_gc(p23, descr=) -+298: guard_class(p25, 26050592, descr=) [p1, p0, p15, i24, p25, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] -+311: p27 = getfield_gc(p23, descr=) -+315: i28 = getfield_gc_pure(p27, descr=) -+319: i29 = getfield_gc_pure(p27, descr=) -+323: i30 = getfield_gc_pure(p27, descr=) -+327: i32 = int_lt(i24, 0) -guard_false(i32, descr=) [p1, p0, p15, i24, i30, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] -+337: i33 = int_ge(i24, i30) -guard_false(i33, descr=) [p1, p0, p15, i24, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] -+346: i34 = int_mul(i24, i29) -+353: i35 = int_add(i28, i34) -+359: i37 = int_add(i24, 1) -+363: setfield_gc(p15, i37, descr=) -+367: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p19, i35] ++298: guard_class(p25, 26517736, descr=) [p1, p0, p15, i24, p25, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++312: p27 = getfield_gc(p23, descr=) ++316: i28 = getfield_gc_pure(p27, descr=) ++320: i29 = getfield_gc_pure(p27, descr=) ++324: i30 = getfield_gc_pure(p27, descr=) ++328: i32 = int_lt(i24, 0) +guard_false(i32, descr=) [p1, p0, p15, i24, i30, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++338: i33 = int_ge(i24, i30) +guard_false(i33, descr=) [p1, p0, p15, i24, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++347: i34 = int_mul(i24, i29) ++354: i35 = int_add(i28, i34) ++360: i37 = int_add(i24, 1) ++364: setfield_gc(p15, i37, descr=) ++368: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p19, i35] debug_merge_point(0, 0, ' #22 STORE_FAST') debug_merge_point(0, 0, ' #25 LOAD_FAST') -+377: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, p6, p15, p19, i35] ++378: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, p6, p15, p19, i35] debug_merge_point(0, 0, ' #28 LOAD_CONST') -+395: guard_value(p4, ConstPtr(ptr40), descr=) [p1, p0, p4, p2, p3, p6, p11, p15, p19, i35] ++396: guard_value(p4, ConstPtr(ptr40), descr=) [p1, p0, p4, p2, p3, p6, p11, p15, p19, i35] debug_merge_point(0, 0, ' #31 INPLACE_ADD') -+414: i41 = getfield_gc_pure(p11, descr=) -+418: i43 = int_add_ovf(i41, 1) -guard_no_overflow(descr=) [p1, p0, p11, i43, p2, p3, p6, p15, i35] ++415: i41 = getfield_gc_pure(p11, descr=) ++419: i43 = int_add_ovf(i41, 1) +guard_no_overflow(descr=) [p1, p0, p11, i43, p2, p3, p6, p15, i35] debug_merge_point(0, 0, ' #32 STORE_FAST') debug_merge_point(0, 0, ' #35 JUMP_ABSOLUTE') -+428: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i43, i35] -+428: i45 = getfield_raw(52008256, descr=) -+436: i47 = int_lt(i45, 0) -guard_false(i47, descr=) [p1, p0, p2, p3, p6, p15, i43, i35] ++429: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i43, i35] ++429: i45 = getfield_raw(51804288, descr=) ++437: i47 = int_lt(i45, 0) +guard_false(i47, descr=) [p1, p0, p2, p3, p6, p15, i43, i35] debug_merge_point(0, 0, ' #19 FOR_ITER') -+446: label(p0, p1, p2, p3, p6, i43, i35, p15, i37, i30, i29, i28, descr=TargetToken(140033647688168)) ++447: label(p0, p1, p2, p3, p6, i43, i35, p15, i37, i30, i29, i28, descr=TargetToken(139941277981072)) debug_merge_point(0, 0, ' #19 FOR_ITER') -+483: i48 = int_ge(i37, i30) -guard_false(i48, descr=) [p1, p0, p15, i37, i29, i28, p2, p3, p6, i43, i35] -+492: i49 = int_mul(i37, i29) -+499: i50 = int_add(i28, i49) -+505: i51 = int_add(i37, 1) ++484: i48 = int_ge(i37, i30) +guard_false(i48, descr=) [p1, p0, p15, i37, i29, i28, p2, p3, p6, i35, i43] ++493: i49 = int_mul(i37, i29) ++500: i50 = int_add(i28, i49) ++506: i51 = int_add(i37, 1) debug_merge_point(0, 0, ' #22 STORE_FAST') debug_merge_point(0, 0, ' #25 LOAD_FAST') debug_merge_point(0, 0, ' #28 LOAD_CONST') debug_merge_point(0, 0, ' #31 INPLACE_ADD') -+509: setfield_gc(p15, i51, descr=) -+513: i52 = int_add_ovf(i43, 1) -guard_no_overflow(descr=) [p1, p0, i52, p2, p3, p6, p15, i50, i43, None] ++510: setfield_gc(p15, i51, descr=) ++514: i52 = int_add_ovf(i43, 1) +guard_no_overflow(descr=) [p1, p0, i52, p2, p3, p6, p15, i50, None, i43] debug_merge_point(0, 0, ' #32 STORE_FAST') debug_merge_point(0, 0, ' #35 JUMP_ABSOLUTE') -+526: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] -+526: i54 = getfield_raw(52008256, descr=) -+534: i55 = int_lt(i54, 0) -guard_false(i55, descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] ++527: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] ++527: i54 = getfield_raw(51804288, descr=) ++535: i55 = int_lt(i54, 0) +guard_false(i55, descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] debug_merge_point(0, 0, ' #19 FOR_ITER') -+544: jump(p0, p1, p2, p3, p6, i52, i50, p15, i51, i30, i29, i28, descr=TargetToken(140033647688168)) -+559: --end of the loop-- -[230588fa6ce3] jit-log-opt-loop} -[2305893ba1d3] {jit-backend -[23058947f3b7] {jit-backend-dump ++545: jump(p0, p1, p2, p3, p6, i52, i50, p15, i51, i30, i29, i28, descr=TargetToken(139941277981072)) ++560: --end of the loop-- +[1ce3a992d953] jit-log-opt-loop} +[1ce3a9c745fd] {jit-backend +[1ce3a9d2ff07] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dc08 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD6CBC11F5C7F000041FFD349BBB011AA225C7F00004D8B3B4D8D770149BBB011AA225C7F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD600100004889856801000048898D7001000049BBC811AA225C7F0000498B0B488D410149BBC811AA225C7F00004989034983F8020F85000000004883FA017206813A680B00000F85000000004983FA000F850000000049BBF0EF4E205C7F00004D39DC0F85000000004C8B62084981FC102700000F8D0000000049BB00000000000000804D39DC0F84000000004C89E0B9020000004889956001000048898568010000489948F7F94889D048C1FA3F41BC020000004921D44C01E04883F8000F85000000004883FB017206813B680B00000F8500000000488B43084883C0010F8000000000488B9D680100004883C3014C8B2425409519034983FC000F8C0000000049BBE011AA225C7F00004D8B23498D54240149BBE011AA225C7F00004989134881FB102700000F8D0000000049BB00000000000000804C39DB0F8400000000488985600100004889D8B90200000048898568010000489948F7F94889D048C1FA3FBB020000004821D34801D84883F8000F8500000000488B85600100004883C0010F8000000000488B9D680100004883C301488B1425409519034883FA000F8C00000000E957FFFFFF49BB8049D91F5C7F0000415349BBF8DAC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE859D91F5C7F0000415349BB08DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB7059D91F5C7F0000415349BB18DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF858D91F5C7F0000415349BB28DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB8058D91F5C7F0000415349BB38DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB0858D91F5C7F0000415349BB48DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB9057D91F5C7F0000415349BB58DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB1857D91F5C7F0000415349BB68DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBA056D91F5C7F0000415349BB78DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB2856D91F5C7F0000415349BB88DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBB055D91F5C7F0000415349BB98DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB3855D91F5C7F0000415349BBA8DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBC054D91F5C7F0000415349BBB8DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB4854D91F5C7F0000415349BBC8DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBD053D91F5C7F0000415349BBD8DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB5853D91F5C7F0000415349BBE8DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE052D91F5C7F0000415349BBF8DBC11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[230589489b4a] jit-backend-dump} -[23058948a2e7] {jit-backend-addr -Loop 3 ( #15 LOAD_FAST) has address 0x7f5c1fc1dc58 to 0x7f5c1fc1de77 (bootstrap 0x7f5c1fc1dc08) -[23058948b8a8] jit-backend-addr} -[23058948c054] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fc08 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BBB03100A1467F00004D8B3B4D8D770149BBB03100A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD600100004889856801000048898D7001000049BBC83100A1467F0000498B0B488D410149BBC83100A1467F00004989034983F8020F85000000004883FA017206813A180C00000F85000000004983FA000F850000000049BBF00FA59E467F00004D39DC0F85000000004C8B62084981FC102700000F8D0000000049BB00000000000000804D39DC0F84000000004C89E0B9020000004889956001000048898568010000489948F7F94889D048C1FA3F41BC020000004921D44C01E04883F8000F85000000004883FB017206813B180C00000F8500000000488B43084883C0010F8000000000488B9D680100004883C3014C8B2425807816034983FC000F8C0000000049BBE03100A1467F00004D8B23498D54240149BBE03100A1467F00004989134881FB102700000F8D0000000049BB00000000000000804C39DB0F8400000000488985600100004889D8B90200000048898568010000489948F7F94889D048C1FA3FBB020000004821D34801D84883F8000F8500000000488B85600100004883C0010F8000000000488B9D680100004883C301488B1425807816034883FA000F8C00000000E957FFFFFF49BB80892F9E467F0000415349BBF8FA179E467F0000415349BB00E0179E467F000041FFE349BBE8992F9E467F0000415349BB08FB179E467F0000415349BB00E0179E467F000041FFE349BB70992F9E467F0000415349BB18FB179E467F0000415349BB00E0179E467F000041FFE349BBF8982F9E467F0000415349BB28FB179E467F0000415349BB00E0179E467F000041FFE349BB80982F9E467F0000415349BB38FB179E467F0000415349BB00E0179E467F000041FFE349BB08982F9E467F0000415349BB48FB179E467F0000415349BB00E0179E467F000041FFE349BB90972F9E467F0000415349BB58FB179E467F0000415349BB00E0179E467F000041FFE349BB18972F9E467F0000415349BB68FB179E467F0000415349BB00E0179E467F000041FFE349BBA0962F9E467F0000415349BB78FB179E467F0000415349BB00E0179E467F000041FFE349BB28962F9E467F0000415349BB88FB179E467F0000415349BB00E0179E467F000041FFE349BBB0952F9E467F0000415349BB98FB179E467F0000415349BB00E0179E467F000041FFE349BB38952F9E467F0000415349BBA8FB179E467F0000415349BB00E0179E467F000041FFE349BBC0942F9E467F0000415349BBB8FB179E467F0000415349BB00E0179E467F000041FFE349BB48942F9E467F0000415349BBC8FB179E467F0000415349BB00E0179E467F000041FFE349BBD0932F9E467F0000415349BBD8FB179E467F0000415349BB00E0179E467F000041FFE349BB58932F9E467F0000415349BBE8FB179E467F0000415349BB00E0179E467F000041FFE349BBE0922F9E467F0000415349BBF8FB179E467F0000415349BB00E0179E467F000041FFE3 +[1ce3a9d39fa9] jit-backend-dump} +[1ce3a9d3a740] {jit-backend-addr +Loop 3 ( #15 LOAD_FAST) has address 0x7f469e17fc58 to 0x7f469e17fe77 (bootstrap 0x7f469e17fc08) +[1ce3a9d3b798] jit-backend-addr} +[1ce3a9d3c01d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd02 +0 71010000 -[23058948cd6b] jit-backend-dump} -[23058948d318] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd02 +0 71010000 +[1ce3a9d43248] jit-backend-dump} +[1ce3a9d43a6e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd14 +0 84010000 -[23058948dd55] jit-backend-dump} -[23058948e1df] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd14 +0 84010000 +[1ce3a9d4470f] jit-backend-dump} +[1ce3a9d44b3f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd1e +0 9F010000 -[230589498778] jit-backend-dump} -[230589498c88] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd1e +0 9F010000 +[1ce3a9d454c4] jit-backend-dump} +[1ce3a9d458d4] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd31 +0 B1010000 -[2305894995a2] jit-backend-dump} -[2305894999ea] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd31 +0 B1010000 +[1ce3a9d4623b] jit-backend-dump} +[1ce3a9d46651] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd42 +0 C5010000 -[23058949a2e9] jit-backend-dump} -[23058949a72b] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd42 +0 C5010000 +[1ce3a9d46fa0] jit-backend-dump} +[1ce3a9d473bc] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd55 +0 D7010000 -[23058949aff8] jit-backend-dump} -[23058949b449] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd55 +0 D7010000 +[1ce3a9d47cb2] jit-backend-dump} +[1ce3a9d480c5] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd8d +0 C4010000 -[23058949bd80] jit-backend-dump} -[23058949c1d5] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd8d +0 C4010000 +[1ce3a9d489ac] jit-backend-dump} +[1ce3a9d48db9] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1dd9f +0 D7010000 -[23058949cad7] jit-backend-dump} -[23058949cf31] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fd9f +0 D7010000 +[1ce3a9d49691] jit-backend-dump} +[1ce3a9d49a95] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ddad +0 EE010000 -[23058949d7ee] jit-backend-dump} -[23058949ddcb] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fdad +0 EE010000 +[1ce3a9d4a39a] jit-backend-dump} +[1ce3a9d4a9de] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ddca +0 1B020000 -[23058949e6cd] jit-backend-dump} -[23058949eb2d] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fdca +0 1B020000 +[1ce3a9d4b2d1] jit-backend-dump} +[1ce3a9d4b70e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ddf6 +0 14020000 -[23058949f44d] jit-backend-dump} -[23058949f854] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fdf6 +0 14020000 +[1ce3a9d4bfe0] jit-backend-dump} +[1ce3a9d4c3f3] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1de09 +0 26020000 -[2305894a01f3] jit-backend-dump} -[2305894a0638] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fe09 +0 26020000 +[1ce3a9d4cd54] jit-backend-dump} +[1ce3a9d4d16d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1de40 +0 14020000 -[2305894a0eea] jit-backend-dump} -[2305894a12eb] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fe40 +0 14020000 +[1ce3a9d4dad7] jit-backend-dump} +[1ce3a9d4ded5] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1de51 +0 28020000 -[2305894a1b97] jit-backend-dump} -[2305894a201e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fe51 +0 28020000 +[1ce3a9d4e7a7] jit-backend-dump} +[1ce3a9d4ec37] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1de6e +0 55020000 -[2305894a2973] jit-backend-dump} -[2305894a33b8] jit-backend} -[2305894a42a6] {jit-log-opt-loop +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fe6e +0 55020000 +[1ce3a9d4f51e] jit-backend-dump} +[1ce3a9d4fe32] jit-backend} +[1ce3a9d50c1a] {jit-log-opt-loop # Loop 3 ( #15 LOAD_FAST) : loop with 93 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -601,37 +601,37 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140033647688784)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139941277981688)) debug_merge_point(0, 0, ' #15 LOAD_FAST') -+244: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+254: guard_nonnull_class(p13, ConstClass(W_IntObject), descr=) [p1, p0, p13, p2, p3, p4, i5, p6, p11, p15, p17] -+272: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] ++244: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++254: guard_nonnull_class(p13, ConstClass(W_IntObject), descr=) [p1, p0, p13, p2, p3, p4, i5, p6, p11, p15, p17] ++272: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] debug_merge_point(0, 0, ' #18 LOAD_CONST') -+282: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] ++282: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] debug_merge_point(0, 0, ' #21 COMPARE_OP') +301: i23 = getfield_gc_pure(p13, descr=) +305: i25 = int_lt(i23, 10000) -guard_true(i25, descr=) [p1, p0, p13, p2, p3, p6, p11] +guard_true(i25, descr=) [p1, p0, p13, p2, p3, p6, p11] debug_merge_point(0, 0, ' #24 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #27 LOAD_FAST') debug_merge_point(0, 0, ' #30 LOAD_CONST') debug_merge_point(0, 0, ' #33 BINARY_MODULO') +318: i27 = int_eq(i23, -9223372036854775808) -guard_false(i27, descr=) [p1, p0, p13, i23, p2, p3, p6, p11] +guard_false(i27, descr=) [p1, p0, p13, i23, p2, p3, p6, p11] +337: i29 = int_mod(i23, 2) +364: i31 = int_rshift(i29, 63) +371: i32 = int_and(2, i31) +380: i33 = int_add(i29, i32) debug_merge_point(0, 0, ' #34 POP_JUMP_IF_FALSE') +383: i34 = int_is_true(i33) -guard_false(i34, descr=) [p1, p0, p2, p3, p6, p11, p13, i33] +guard_false(i34, descr=) [p1, p0, p2, p3, p6, p11, p13, i33] debug_merge_point(0, 0, ' #53 LOAD_FAST') -+393: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p6, p13, None] ++393: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p6, p13, None] debug_merge_point(0, 0, ' #56 LOAD_CONST') debug_merge_point(0, 0, ' #59 INPLACE_ADD') +411: i37 = getfield_gc_pure(p11, descr=) +415: i39 = int_add_ovf(i37, 1) -guard_no_overflow(descr=) [p1, p0, p11, i39, p2, p3, p6, p13, None] +guard_no_overflow(descr=) [p1, p0, p11, i39, p2, p3, p6, p13, None] debug_merge_point(0, 0, ' #60 STORE_FAST') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') @@ -639,35 +639,35 @@ +425: i41 = int_add(i23, 1) debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+436: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i41, i39, None] -+436: i43 = getfield_raw(52008256, descr=) ++436: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i39, i41, None] ++436: i43 = getfield_raw(51804288, descr=) +444: i45 = int_lt(i43, 0) -guard_false(i45, descr=) [p1, p0, p2, p3, p6, i41, i39, None] +guard_false(i45, descr=) [p1, p0, p2, p3, p6, i39, i41, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+454: label(p0, p1, p2, p3, p6, i39, i41, descr=TargetToken(140033647688872)) ++454: label(p0, p1, p2, p3, p6, i39, i41, descr=TargetToken(139941277981776)) debug_merge_point(0, 0, ' #15 LOAD_FAST') debug_merge_point(0, 0, ' #18 LOAD_CONST') debug_merge_point(0, 0, ' #21 COMPARE_OP') +485: i46 = int_lt(i41, 10000) -guard_true(i46, descr=) [p1, p0, p2, p3, p6, i41, i39] +guard_true(i46, descr=) [p1, p0, p2, p3, p6, i39, i41] debug_merge_point(0, 0, ' #24 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #27 LOAD_FAST') debug_merge_point(0, 0, ' #30 LOAD_CONST') debug_merge_point(0, 0, ' #33 BINARY_MODULO') +498: i47 = int_eq(i41, -9223372036854775808) -guard_false(i47, descr=) [p1, p0, i41, p2, p3, p6, None, i39] +guard_false(i47, descr=) [p1, p0, i41, p2, p3, p6, i39, None] +517: i48 = int_mod(i41, 2) +544: i49 = int_rshift(i48, 63) +551: i50 = int_and(2, i49) +559: i51 = int_add(i48, i50) debug_merge_point(0, 0, ' #34 POP_JUMP_IF_FALSE') +562: i52 = int_is_true(i51) -guard_false(i52, descr=) [p1, p0, p2, p3, p6, i51, i41, i39] +guard_false(i52, descr=) [p1, p0, p2, p3, p6, i51, i39, i41] debug_merge_point(0, 0, ' #53 LOAD_FAST') debug_merge_point(0, 0, ' #56 LOAD_CONST') debug_merge_point(0, 0, ' #59 INPLACE_ADD') +572: i53 = int_add_ovf(i39, 1) -guard_no_overflow(descr=) [p1, p0, i53, p2, p3, p6, None, i41, i39] +guard_no_overflow(descr=) [p1, p0, i53, p2, p3, p6, None, i39, i41] debug_merge_point(0, 0, ' #60 STORE_FAST') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') @@ -675,60 +675,60 @@ +589: i54 = int_add(i41, 1) debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+600: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i53, i54, None, None, None] -+600: i55 = getfield_raw(52008256, descr=) ++600: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i54, i53, None, None, None] ++600: i55 = getfield_raw(51804288, descr=) +608: i56 = int_lt(i55, 0) -guard_false(i56, descr=) [p1, p0, p2, p3, p6, i53, i54, None, None, None] +guard_false(i56, descr=) [p1, p0, p2, p3, p6, i54, i53, None, None, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+618: jump(p0, p1, p2, p3, p6, i53, i54, descr=TargetToken(140033647688872)) ++618: jump(p0, p1, p2, p3, p6, i53, i54, descr=TargetToken(139941277981776)) +623: --end of the loop-- -[2305894edfe2] jit-log-opt-loop} -[2305895ae455] {jit-backend -[23058963bda8] {jit-backend-dump +[1ce3a9da8a39] jit-log-opt-loop} +[1ce3a9e66b10] {jit-backend +[1ce3a9ee434f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e130 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBF0E0C11F5C7F00004C891C2449BB75C2C11F5C7F000041FFD349BBF811AA225C7F00004D8B2B498D550149BBF811AA225C7F0000498913488B95480100004C8B6A10488B4A1848C74010000000004883F9020F85000000004D85ED0F85000000004C8BAD38010000498B4D68488B0425C8EEB501488D7820483B3C25E8EEB501761B49BB20E1C11F5C7F00004C891C2449BBE3C9C11F5C7F000041FFD348893C25C8EEB50148C700680B000041C6858D00000001488BBD5001000041F6450401740F415549BB2EC1C11F5C7F000041FFD34989BD80000000488BBD5801000041F6450401740F415549BB2EC1C11F5C7F000041FFD349897D5041F6450401740F415549BB2EC1C11F5C7F000041FFD349BB38EF4E205C7F00004D895D7041C6858E0000000049C745600000000049C745780200000049C745582A000000F6410481741678105149BB91C1C11F5C7F000041FFD379048049FF01488941104C8D681049C74500680B0000488BBD6001000049897D08F6410481741678105149BB91C1C11F5C7F000041FFD379048049FF014C89691848C741200000000048C741280000000048C74130000000004C8960084889455848C745102099EA0149BB3040AA225C7F00004C895D204889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB405CD91F5C7F0000415349BB00E1C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB98E096225C7F0000415349BB10E1C11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[230589642385] jit-backend-dump} -[230589642d27] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180130 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBF000189E467F00004C891C2449BB75E2179E467F000041FFD349BBF83100A1467F00004D8B0B498D510149BBF83100A1467F0000498913488B95580100004C8B4A10488B4A1848C74010000000004883F9020F85000000004D85C90F85000000004C8B8D38010000498B4968488B0425484CB601488D7820483B3C25684CB601761B49BB2001189E467F00004C891C2449BBE3E9179E467F000041FFD348893C25484CB60148C700180C000041C6818D00000001488BBD5001000041F6410401740F415149BB2EE1179E467F000041FFD34989B980000000488BBD4801000041F6410401740F415149BB2EE1179E467F000041FFD34989795041F6410401740F415149BB2EE1179E467F000041FFD349BB380FA59E467F00004D89597041C6818E0000000049C741600000000049C741780200000049C741582A000000F6410481741678105149BB91E1179E467F000041FFD379048049FF01488941104C8D481049C701180C0000488BBD6001000049897908F6410481741678105149BB91E1179E467F000041FFD379048049FF014C89491848C741200000000048C741280000000048C74130000000004C8960084889455848C745108042EA0149BB306000A1467F00004C895D204889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB409C2F9E467F0000415349BB0001189E467F0000415349BB00E0179E467F000041FFE349BB9800EDA0467F0000415349BB1001189E467F0000415349BB00E0179E467F000041FFE3 +[1ce3a9eeacb9] jit-backend-dump} +[1ce3a9eeb70b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e134 +0 22000000 -[2305896439e3] jit-backend-dump} -[230589643e58] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180134 +0 22000000 +[1ce3a9eec253] jit-backend-dump} +[1ce3a9eec730] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e13f +0 22000000 -[2305896447f7] jit-backend-dump} -[230589644cdd] {jit-backend-addr -bridge out of Guard 0x7f5c1fd942f0 has address 0x7f5c1fc1e130 to 0x7f5c1fc1e33e -[230589645a78] jit-backend-addr} -[230589645fef] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18013f +0 22000000 +[1ce3a9eed097] jit-backend-dump} +[1ce3a9eed72f] {jit-backend-addr +bridge out of Guard 0x7f469e2f82f0 has address 0x7f469e180130 to 0x7f469e18033d +[1ce3a9eee408] jit-backend-addr} +[1ce3a9eee927] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e199 +0 A1010000 -[230589646941] jit-backend-dump} -[230589646d78] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180199 +0 A0010000 +[1ce3a9eef2d2] jit-backend-dump} +[1ce3a9eef71a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e1a2 +0 BD010000 -[230589647662] jit-backend-dump} -[230589647dac] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1801a2 +0 BC010000 +[1ce3a9eeffe7] jit-backend-dump} +[1ce3a9ef05ff] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1d850 +0 DC080000 -[23058964869f] jit-backend-dump} -[23058964902a] jit-backend} -[230589649b54] {jit-log-opt-bridge -# bridge out of Guard 7f5c1fd942f0 with 28 ops +SYS_EXECUTABLE python +CODE_DUMP @7f469e17f851 +0 DB080000 +[1ce3a9ef0eec] jit-backend-dump} +[1ce3a9ef16fa] jit-backend} +[1ce3a9ef225a] {jit-log-opt-bridge +# bridge out of Guard 0x7f469e2f82f0 with 28 ops [p0, p1, p2, i3, i4, i5, p6, p7, p8, i9, i10] debug_merge_point(0, 0, ' #38 POP_BLOCK') +76: p11 = getfield_gc_pure(p8, descr=) +87: i12 = getfield_gc_pure(p8, descr=) +91: setfield_gc(p2, ConstPtr(ptr13), descr=) -+99: guard_value(i12, 2, descr=) [p0, p1, i12, p6, p7, p11, i10, i9] ++99: guard_value(i12, 2, descr=) [p0, p1, i12, p6, p7, p11, i10, i9] debug_merge_point(0, 0, ' #39 LOAD_FAST') debug_merge_point(0, 0, ' #42 RETURN_VALUE') -+109: guard_isnull(p11, descr=) [p0, p1, p11, p6, p7, i10, i9] ++109: guard_isnull(p11, descr=) [p0, p1, p11, p6, p7, i10, i9] +118: p15 = getfield_gc(p1, descr=) +129: p16 = getfield_gc(p1, descr=) p18 = new_with_vtable(ConstClass(W_IntObject)) @@ -742,166 +742,166 @@ +330: setfield_gc(p1, 42, descr=) setarrayitem_gc(p15, 0, p18, descr=) p27 = new_with_vtable(ConstClass(W_IntObject)) -+382: setfield_gc(p27, i10, descr=) ++381: setfield_gc(p27, i9, descr=) setarrayitem_gc(p15, 1, p27, descr=) -+425: setarrayitem_gc(p15, 2, ConstPtr(ptr30), descr=) -+433: setarrayitem_gc(p15, 3, ConstPtr(ptr32), descr=) -+441: setarrayitem_gc(p15, 4, ConstPtr(ptr32), descr=) -+449: setfield_gc(p18, i9, descr=) -+453: finish(p18, descr=) -+526: --end of the loop-- -[23058966a2b4] jit-log-opt-bridge} -[230589ae6ce5] {jit-backend -[230589c5404d] {jit-backend-dump ++424: setarrayitem_gc(p15, 2, ConstPtr(ptr30), descr=) ++432: setarrayitem_gc(p15, 3, ConstPtr(ptr32), descr=) ++440: setarrayitem_gc(p15, 4, ConstPtr(ptr32), descr=) ++448: setfield_gc(p18, i10, descr=) ++452: finish(p18, descr=) ++525: --end of the loop-- +[1ce3a9f131a1] jit-log-opt-bridge} +[1ce3aa3c4c80] {jit-backend +[1ce3aa535471] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e568 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88E3C11F5C7F00004C891C2449BB75C2C11F5C7F000041FFD349BB1012AA225C7F0000498B034C8D780149BB1012AA225C7F00004D893B4C8BBD38010000498B470849BBC8E048205C7F00004C39D80F85000000004C8B701049BBA82E4E205C7F00004D39DE0F850000000049BBC8E3C11F5C7F00004C895D2041BB0080840041FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C74520000000004C8B78504989EE4C8B68604D85ED0F85000000004C8B68404983FD000F85000000004C8B2C2540D7CE014981FD30C3D4010F85000000004C8B2C25409519034983FD000F8C000000004989ED48898570010000488B0425C8EEB501488DB840010000483B3C25E8EEB501761B49BB28E4C11F5C7F00004C891C2449BBE3C9C11F5C7F000041FFD348893C25C8EEB50148C700407E0100488DB89000000048C707C800000048C74708050000004C8D673849C70424680B00004D8D54241049C702680B00004D8D4A1049C701704500004D8D411849C700E86B0000498D701848C706C800000048C7460800000000488D5E1048C703180600004C8973084C8BB57001000041F6460401740F415649BB2EC1C11F5C7F000041FFD349895E50488B9538010000F6420401740E5249BB2EC1C11F5C7F000041FFD34C896A1849BB809F96225C7F00004C89586048C74058130000004C89783049C7442408010000004C8967104C89571849C740104004F10149BBA09F96225C7F00004D8958084D89411049C74108010000004C894F2048897868C780880000001500000049BB38EF4E205C7F00004C8958704889702849BBC8E048205C7F00004C89580848C740780300000049BB60D5C11F5C7F0000498B3348898578010000488B3C25C8EEB5014889F84801F7483B3C25E8EEB501761B49BB38E4C11F5C7F00004C891C2449BBE3C9C11F5C7F000041FFD348893C25C8EEB50148C7000800000049BB58D5C11F5C7F0000498B334889705049BB58D5C11F5C7F00004C895808488BB5780100004889B0380100004C89B04001000048899D8001000049BBA0EC98225C7F00004C895D184889C749BB58E4C11F5C7F00004C895D2049BB68D6C11F5C7F000041FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C7452000000000488178102099EA01743E4889C7488BB57801000049BB68E4C11F5C7F00004C895D2041BBE08D080141FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C7452000000000EB13488B957801000048C7421800000000488B405848837D10000F850000000048833C25C0021903000F8500000000488B9570010000488B72604885F60F8500000000488B7240488B9D7801000048C74350000000004883FE000F8500000000488B72504C8B7330480FB6BB8C000000F6420401740E5249BB2EC1C11F5C7F000041FFD34C8972504885FF0F8500000000488BBD8001000048C74708000000008138680B00000F8500000000488B7808488B95600100004801FA0F8000000000488BBD680100004883C7010F8000000000488B0425409519034883F8000F8C0000000049BB2812AA225C7F0000498B03488D580149BB2812AA225C7F000049891B4881FF102700000F8D0000000049BB00000000000000804C39DF0F84000000004889F8B9020000004889956001000048898568010000489948F7F94889D048C1FA3FBF020000004821D74801F84883F8000F8500000000488B85600100004883C0010F8000000000488BBD680100004883C701488B1425409519034883FA000F8C000000004889FB49BBCEDDC11F5C7F000041FFE349BB78E296225C7F0000415349BB98E3C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB581399225C7F0000415349BBA8E3C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE01299225C7F0000415349BBB8E3C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB681299225C7F0000415349BBD8E3C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF01199225C7F0000415349BBE8E3C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB781199225C7F0000415349BBF8E3C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB001199225C7F0000415349BB08E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB881099225C7F0000415349BB18E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBA0EC98225C7F0000415349BB48E4C11F5C7F0000415349BB85C0C11F5C7F000041FFE349BB101099225C7F0000415349BB78E4C11F5C7F0000415349BB85C0C11F5C7F000041FFE349BB980F99225C7F0000415349BB88E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB200F99225C7F0000415349BB98E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBA80E99225C7F0000415349BBA8E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB300E99225C7F0000415349BBB8E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBB80D99225C7F0000415349BBC8E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB400D99225C7F0000415349BBD8E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBC80C99225C7F0000415349BBE8E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB500C99225C7F0000415349BBF8E4C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBD80B99225C7F0000415349BB08E5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB600B99225C7F0000415349BB18E5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE80A99225C7F0000415349BB28E5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB700A99225C7F0000415349BB38E5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF80999225C7F0000415349BB48E5C11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB800999225C7F0000415349BB58E5C11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[230589c706d9] jit-backend-dump} -[230589c714e2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180568 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB8803189E467F00004C891C2449BB75E2179E467F000041FFD349BB103200A1467F0000498B034C8D780149BB103200A1467F00004D893B4C8BBD38010000498B470849BBC8009F9E467F00004C39D80F85000000004C8B701049BBA84EA49E467F00004D39DE0F850000000049BBC803189E467F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDE1179E467F000041FFD348C74520000000004C8B78504989EE4C8B68604D85ED0F85000000004C8B68404983FD000F85000000004C8B2C2500EFCE014981FDF0EED4010F85000000004C8B2C25807816034983FD000F8C000000004989ED48898570010000488B0425484CB601488DB840010000483B3C25684CB601761B49BB2804189E467F00004C891C2449BBE3E9179E467F000041FFD348893C25484CB60148C700407E0100488DB89000000048C707C800000048C74708050000004C8D673849C70424180C00004D8D54241049C702180C00004D8D4A1049C701E82200004D8D411849C70070400000498D701848C706C800000048C7460800000000488D5E1048C703180600004C8973084C8BB57001000041F6460401740F415649BB2EE1179E467F000041FFD349895E50488B9538010000F6420401740E5249BB2EE1179E467F000041FFD34C896A1849C7442408010000004C8967104C89571849BB60BFECA0467F00004D89580849C74010C01CF1014D89411049C74108010000004C894F204889786848C740780300000049BB80BFECA0467F00004C8958604C89783048C740581300000048897028C780880000001500000049BBC8009F9E467F00004C89580849BB380FA59E467F00004C89587049BB60F5179E467F0000498B3348898578010000488B3C25484CB6014889F84801F7483B3C25684CB601761B49BB3804189E467F00004C891C2449BBE3E9179E467F000041FFD348893C25484CB60148C7000800000049BB58F5179E467F0000498B334889705049BB58F5179E467F00004C895808488BB5780100004889B0380100004C89B04001000048899D8001000049BBA00CEFA0467F00004C895D184889C749BB5804189E467F00004C895D2049BB68F6179E467F000041FFD3F6450401740D49BBFDE1179E467F000041FFD348C7452000000000488178108042EA01743E4889C7488BB57801000049BB6804189E467F00004C895D2041BB908D080141FFD3F6450401740D49BBFDE1179E467F000041FFD348C7452000000000EB13488B957801000048C7421800000000488B405848837D10000F850000000048833C2500E61503000F8500000000488B9570010000488B72604885F60F8500000000488B72404C8BB57801000049C74650000000004883FE000F8500000000488B7250498B5E30490FB6BE8C000000F6420401740E5249BB2EE1179E467F000041FFD348895A504885FF0F8500000000488BBD8001000048C74708000000008138180C00000F8500000000488B7808488B95600100004801FA0F8000000000488BBD680100004883C7010F8000000000488B0425807816034883F8000F8C0000000049BB283200A1467F0000498B034C8D700149BB283200A1467F00004D89334881FF102700000F8D0000000049BB00000000000000804C39DF0F84000000004889F8B9020000004889956001000048898568010000489948F7F94889D048C1FA3FBF020000004821D74801F84883F8000F8500000000488B85600100004883C0010F8000000000488BBD680100004883C701488B1425807816034883FA000F8C000000004889FB49BBCEFD179E467F000041FFE349BB7802EDA0467F0000415349BB9803189E467F0000415349BB00E0179E467F000041FFE349BB5833EFA0467F0000415349BBA803189E467F0000415349BB00E0179E467F000041FFE349BBE032EFA0467F0000415349BBB803189E467F0000415349BB00E0179E467F000041FFE349BB6832EFA0467F0000415349BBD803189E467F0000415349BB00E0179E467F000041FFE349BBF031EFA0467F0000415349BBE803189E467F0000415349BB00E0179E467F000041FFE349BB7831EFA0467F0000415349BBF803189E467F0000415349BB00E0179E467F000041FFE349BB0031EFA0467F0000415349BB0804189E467F0000415349BB00E0179E467F000041FFE349BB8830EFA0467F0000415349BB1804189E467F0000415349BB00E0179E467F000041FFE349BBA00CEFA0467F0000415349BB4804189E467F0000415349BB85E0179E467F000041FFE349BB1030EFA0467F0000415349BB7804189E467F0000415349BB85E0179E467F000041FFE349BB982FEFA0467F0000415349BB8804189E467F0000415349BB00E0179E467F000041FFE349BB202FEFA0467F0000415349BB9804189E467F0000415349BB00E0179E467F000041FFE349BBA82EEFA0467F0000415349BBA804189E467F0000415349BB00E0179E467F000041FFE349BB302EEFA0467F0000415349BBB804189E467F0000415349BB00E0179E467F000041FFE349BBB82DEFA0467F0000415349BBC804189E467F0000415349BB00E0179E467F000041FFE349BB402DEFA0467F0000415349BBD804189E467F0000415349BB00E0179E467F000041FFE349BBC82CEFA0467F0000415349BBE804189E467F0000415349BB00E0179E467F000041FFE349BB502CEFA0467F0000415349BBF804189E467F0000415349BB00E0179E467F000041FFE349BBD82BEFA0467F0000415349BB0805189E467F0000415349BB00E0179E467F000041FFE349BB602BEFA0467F0000415349BB1805189E467F0000415349BB00E0179E467F000041FFE349BBE82AEFA0467F0000415349BB2805189E467F0000415349BB00E0179E467F000041FFE349BB702AEFA0467F0000415349BB3805189E467F0000415349BB00E0179E467F000041FFE349BBF829EFA0467F0000415349BB4805189E467F0000415349BB00E0179E467F000041FFE349BB8029EFA0467F0000415349BB5805189E467F0000415349BB00E0179E467F000041FFE3 +[1ce3aa54fb27] jit-backend-dump} +[1ce3aa550a05] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e56c +0 26000000 -[230589c72607] jit-backend-dump} -[230589c72ba8] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18056c +0 26000000 +[1ce3aa551990] jit-backend-dump} +[1ce3aa551ea8] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e577 +0 26000000 -[230589c735c1] jit-backend-dump} -[230589c73b24] {jit-backend-addr -bridge out of Guard 0x7f5c1fd95448 has address 0x7f5c1fc1e568 to 0x7f5c1fc1ea92 -[230589c749b2] jit-backend-addr} -[230589c75234] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180577 +0 26000000 +[1ce3aa552915] jit-backend-dump} +[1ce3aa552df8] {jit-backend-addr +bridge out of Guard 0x7f469e2f9448 has address 0x7f469e180568 to 0x7f469e180a92 +[1ce3aa553bb9] jit-backend-addr} +[1ce3aa55430f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e5ce +0 C0040000 -[230589c75bdf] jit-backend-dump} -[230589c76166] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1805ce +0 C0040000 +[1ce3aa554ca2] jit-backend-dump} +[1ce3aa5551e1] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e5e5 +0 CE040000 -[230589c76b37] jit-backend-dump} -[230589c770ca] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1805e5 +0 CE040000 +[1ce3aa555ad1] jit-backend-dump} +[1ce3aa556013] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e62b +0 D2040000 -[230589c779fb] jit-backend-dump} -[230589c77e26] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18062b +0 D2040000 +[1ce3aa5569cd] jit-backend-dump} +[1ce3aa556e1f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e639 +0 E9040000 -[230589c787aa] jit-backend-dump} -[230589c78cd5] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180639 +0 E9040000 +[1ce3aa557771] jit-backend-dump} +[1ce3aa557bf5] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e64e +0 1E050000 -[230589c79665] jit-backend-dump} -[230589c79a63] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18064e +0 1E050000 +[1ce3aa5584ca] jit-backend-dump} +[1ce3aa5588f2] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e660 +0 31050000 -[230589c7a37a] jit-backend-dump} -[230589c7a784] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180660 +0 31050000 +[1ce3aa5591c4] jit-backend-dump} +[1ce3aa5595d4] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e918 +0 9E020000 -[230589c7b08c] jit-backend-dump} -[230589c7b493] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180918 +0 9E020000 +[1ce3aa559ee5] jit-backend-dump} +[1ce3aa55a2fe] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e927 +0 B4020000 -[230589c7bdb5] jit-backend-dump} -[230589c7c1d1] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180927 +0 B4020000 +[1ce3aa55abc7] jit-backend-dump} +[1ce3aa55b012] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e93b +0 C5020000 -[230589c7cab8] jit-backend-dump} -[230589c7cec5] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18093b +0 C5020000 +[1ce3aa55df15] jit-backend-dump} +[1ce3aa55e492] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e958 +0 CD020000 -[230589c7d7b8] jit-backend-dump} -[230589c7dbb6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180958 +0 CD020000 +[1ce3aa55ee46] jit-backend-dump} +[1ce3aa55f26e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e989 +0 C1020000 -[230589c80948] jit-backend-dump} -[230589c80ea2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180989 +0 C1020000 +[1ce3aa55fce6] jit-backend-dump} +[1ce3aa560111] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e9a4 +0 CB020000 -[230589c81803] jit-backend-dump} -[230589c81c0d] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1809a4 +0 CB020000 +[1ce3aa5609ce] jit-backend-dump} +[1ce3aa560df3] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e9b8 +0 DC020000 -[230589c824f7] jit-backend-dump} -[230589c828fe] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1809b8 +0 DC020000 +[1ce3aa561725] jit-backend-dump} +[1ce3aa561b3e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e9c9 +0 F0020000 -[230589c83218] jit-backend-dump} -[230589c842c9] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1809c9 +0 F0020000 +[1ce3aa5623e9] jit-backend-dump} +[1ce3aa562e4d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e9db +0 28030000 -[230589c84be2] jit-backend-dump} -[230589c84fef] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1809db +0 28030000 +[1ce3aa563737] jit-backend-dump} +[1ce3aa563b44] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ea06 +0 22030000 -[230589c858c8] jit-backend-dump} -[230589c85cdb] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180a06 +0 22030000 +[1ce3aa564407] jit-backend-dump} +[1ce3aa564823] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ea19 +0 34030000 -[230589c865ee] jit-backend-dump} -[230589c86a01] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180a19 +0 34030000 +[1ce3aa5650c9] jit-backend-dump} +[1ce3aa5654df] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ea50 +0 22030000 -[230589c872d9] jit-backend-dump} -[230589c8772e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180a50 +0 22030000 +[1ce3aa565d76] jit-backend-dump} +[1ce3aa5661a6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ea61 +0 36030000 -[230589c88036] jit-backend-dump} -[230589c8847b] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180a61 +0 36030000 +[1ce3aa566a58] jit-backend-dump} +[1ce3aa566ed3] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ea7e +0 63030000 -[230589c88d59] jit-backend-dump} -[230589c89532] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180a7e +0 63030000 +[1ce3aa5677a2] jit-backend-dump} +[1ce3aa567e34] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1de40 +0 24070000 -[230589c89e46] jit-backend-dump} -[230589c8ab5a] jit-backend} -[230589c8be49] {jit-log-opt-bridge -# bridge out of Guard 7f5c1fd95448 with 137 ops +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fe40 +0 24070000 +[1ce3aa56872d] jit-backend-dump} +[1ce3aa569310] jit-backend} +[1ce3aa56a308] {jit-log-opt-bridge +# bridge out of Guard 0x7f469e2f9448 with 137 ops [p0, p1, p2, p3, p4, i5, i6, i7] debug_merge_point(0, 0, ' #37 LOAD_FAST') debug_merge_point(0, 0, ' #40 LOAD_GLOBAL') +76: p8 = getfield_gc(p1, descr=) -+87: guard_value(p8, ConstPtr(ptr9), descr=) [p0, p1, p8, p2, p3, p4, i7, i6] ++87: guard_value(p8, ConstPtr(ptr9), descr=) [p0, p1, p8, p2, p3, p4, i6, i7] +106: p10 = getfield_gc(p8, descr=) -+110: guard_value(p10, ConstPtr(ptr11), descr=) [p0, p1, p10, p8, p2, p3, p4, i7, i6] -+129: guard_not_invalidated(descr=) [p0, p1, p8, p2, p3, p4, i7, i6] ++110: guard_value(p10, ConstPtr(ptr11), descr=) [p0, p1, p10, p8, p2, p3, p4, i6, i7] ++129: guard_not_invalidated(descr=) [p0, p1, p8, p2, p3, p4, i6, i7] debug_merge_point(0, 0, ' #43 CALL_FUNCTION') +129: p13 = call(ConstClass(getexecutioncontext), descr=) +179: p14 = getfield_gc(p13, descr=) +183: p15 = force_token() +186: p16 = getfield_gc(p13, descr=) -+190: guard_isnull(p16, descr=) [p0, p1, p13, p16, p2, p3, p4, p14, p15, i7, i6] ++190: guard_isnull(p16, descr=) [p0, p1, p13, p16, p2, p3, p4, p14, p15, i6, i7] +199: i17 = getfield_gc(p13, descr=) +203: i18 = int_is_zero(i17) -guard_true(i18, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i7, i6] +guard_true(i18, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] debug_merge_point(1, 1, ' #0 LOAD_CONST') debug_merge_point(1, 1, ' #3 STORE_FAST') debug_merge_point(1, 1, ' #6 SETUP_LOOP') debug_merge_point(1, 1, ' #9 LOAD_GLOBAL') -+213: guard_not_invalidated(descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i7, i6] ++213: guard_not_invalidated(descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] +213: p20 = getfield_gc(ConstPtr(ptr19), descr=) -+221: guard_value(p20, ConstPtr(ptr21), descr=) [p0, p1, p13, p20, p2, p3, p4, p14, p15, i7, i6] ++221: guard_value(p20, ConstPtr(ptr21), descr=) [p0, p1, p13, p20, p2, p3, p4, p14, p15, i6, i7] debug_merge_point(1, 1, ' #12 LOAD_CONST') debug_merge_point(1, 1, ' #15 CALL_FUNCTION') debug_merge_point(1, 1, ' #18 GET_ITER') @@ -912,97 +912,97 @@ debug_merge_point(1, 1, ' #31 INPLACE_ADD') debug_merge_point(1, 1, ' #32 STORE_FAST') debug_merge_point(1, 1, ' #35 JUMP_ABSOLUTE') -+234: i23 = getfield_raw(52008256, descr=) ++234: i23 = getfield_raw(51804288, descr=) +242: i25 = int_lt(i23, 0) -guard_false(i25, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i7, i6] +guard_false(i25, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] debug_merge_point(1, 1, ' #19 FOR_ITER') +252: p26 = force_token() -p28 = new_with_vtable(25799520) +p28 = new_with_vtable(26266048) p30 = new_array(5, descr=) p32 = new_with_vtable(ConstClass(W_IntObject)) p34 = new_with_vtable(ConstClass(W_IntObject)) -p36 = new_with_vtable(25719440) +p36 = new_with_vtable(26177128) p38 = new_with_vtable(ConstClass(W_ListObject)) p40 = new_array(0, descr=) -p42 = new_with_vtable(25703224) +p42 = new_with_vtable(26169752) +427: setfield_gc(p42, p15, descr=) setfield_gc(p13, p42, descr=) setfield_gc(p1, p26, descr=) -+495: setfield_gc(p28, ConstPtr(ptr43), descr=) -+509: setfield_gc(p28, 19, descr=) -+517: setfield_gc(p28, p14, descr=) -+521: setfield_gc(p32, 1, descr=) -+530: setarrayitem_gc(p30, 0, p32, descr=) -+534: setarrayitem_gc(p30, 1, p34, descr=) -+538: setfield_gc(p38, ConstPtr(ptr48), descr=) -+546: setfield_gc(p38, ConstPtr(ptr49), descr=) -+560: setfield_gc(p36, p38, descr=) -+564: setfield_gc(p36, 1, descr=) -+572: setarrayitem_gc(p30, 2, p36, descr=) -+576: setfield_gc(p28, p30, descr=) -+580: setfield_gc(p28, 21, descr=) -+590: setfield_gc(p28, ConstPtr(ptr53), descr=) -+604: setfield_gc(p28, p40, descr=) -+608: setfield_gc(p28, ConstPtr(ptr9), descr=) -+622: setfield_gc(p28, 3, descr=) ++495: setfield_gc(p32, 1, descr=) ++504: setarrayitem_gc(p30, 0, p32, descr=) ++508: setarrayitem_gc(p30, 1, p34, descr=) ++512: setfield_gc(p38, ConstPtr(ptr46), descr=) ++526: setfield_gc(p38, ConstPtr(ptr47), descr=) ++534: setfield_gc(p36, p38, descr=) ++538: setfield_gc(p36, 1, descr=) ++546: setarrayitem_gc(p30, 2, p36, descr=) ++550: setfield_gc(p28, p30, descr=) ++554: setfield_gc(p28, 3, descr=) ++562: setfield_gc(p28, ConstPtr(ptr51), descr=) ++576: setfield_gc(p28, p14, descr=) ++580: setfield_gc(p28, 19, descr=) ++588: setfield_gc(p28, p40, descr=) ++592: setfield_gc(p28, 21, descr=) ++602: setfield_gc(p28, ConstPtr(ptr9), descr=) ++616: setfield_gc(p28, ConstPtr(ptr54), descr=) p55 = call_assembler(p28, p13, descr=) -guard_not_forced(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i7, i6] +guard_not_forced(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i6, i7] +948: keepalive(p28) -+948: guard_no_exception(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i7, i6] ++948: guard_no_exception(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i6, i7] +963: p56 = getfield_gc(p13, descr=) -+974: guard_isnull(p56, descr=) [p0, p1, p55, p13, p28, p56, p42, p2, p3, p4, i7, i6] ++974: guard_isnull(p56, descr=) [p0, p1, p55, p13, p28, p56, p42, p2, p3, p4, i6, i7] +983: i57 = getfield_gc(p13, descr=) +987: setfield_gc(p28, ConstPtr(ptr58), descr=) +1002: i59 = int_is_true(i57) -guard_false(i59, descr=) [p0, p1, p55, p28, p13, p42, p2, p3, p4, i7, i6] +guard_false(i59, descr=) [p0, p1, p55, p28, p13, p42, p2, p3, p4, i6, i7] +1012: p60 = getfield_gc(p13, descr=) +1016: p61 = getfield_gc(p28, descr=) +1020: i62 = getfield_gc(p28, descr=) setfield_gc(p13, p61, descr=) -+1052: guard_false(i62, descr=) [p0, p1, p55, p60, p28, p13, p42, p2, p3, p4, i7, i6] ++1052: guard_false(i62, descr=) [p0, p1, p55, p60, p28, p13, p42, p2, p3, p4, i6, i7] debug_merge_point(0, 0, ' #46 INPLACE_ADD') +1061: setfield_gc(p42, ConstPtr(ptr63), descr=) -+1076: guard_class(p55, ConstClass(W_IntObject), descr=) [p0, p1, p55, p2, p3, p4, i7, i6] ++1076: guard_class(p55, ConstClass(W_IntObject), descr=) [p0, p1, p55, p2, p3, p4, i6, i7] +1088: i65 = getfield_gc_pure(p55, descr=) -+1092: i66 = int_add_ovf(i7, i65) -guard_no_overflow(descr=) [p0, p1, p55, i66, p2, p3, p4, i7, i6] ++1092: i66 = int_add_ovf(i6, i65) +guard_no_overflow(descr=) [p0, p1, p55, i66, p2, p3, p4, i6, i7] debug_merge_point(0, 0, ' #47 STORE_FAST') debug_merge_point(0, 0, ' #50 JUMP_FORWARD') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') debug_merge_point(0, 0, ' #69 INPLACE_ADD') -+1108: i68 = int_add_ovf(i6, 1) -guard_no_overflow(descr=) [p0, p1, i68, p2, p3, p4, i66, None, i6] ++1108: i68 = int_add_ovf(i7, 1) +guard_no_overflow(descr=) [p0, p1, i68, p2, p3, p4, i66, None, i7] debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+1125: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] -+1125: i71 = getfield_raw(52008256, descr=) ++1125: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] ++1125: i71 = getfield_raw(51804288, descr=) +1133: i73 = int_lt(i71, 0) -guard_false(i73, descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] +guard_false(i73, descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+1143: label(p1, p0, p2, p3, p4, i66, i68, descr=TargetToken(140033694065200)) ++1143: label(p1, p0, p2, p3, p4, i66, i68, descr=TargetToken(139941324358104)) debug_merge_point(0, 0, ' #18 LOAD_CONST') debug_merge_point(0, 0, ' #21 COMPARE_OP') +1173: i75 = int_lt(i68, 10000) -guard_true(i75, descr=) [p0, p1, p2, p3, p4, i68, i66] +guard_true(i75, descr=) [p0, p1, p2, p3, p4, i66, i68] debug_merge_point(0, 0, ' #24 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #27 LOAD_FAST') debug_merge_point(0, 0, ' #30 LOAD_CONST') debug_merge_point(0, 0, ' #33 BINARY_MODULO') +1186: i77 = int_eq(i68, -9223372036854775808) -guard_false(i77, descr=) [p0, p1, i68, p2, p3, p4, None, i66] +guard_false(i77, descr=) [p0, p1, i68, p2, p3, p4, i66, None] +1205: i79 = int_mod(i68, 2) +1232: i81 = int_rshift(i79, 63) +1239: i82 = int_and(2, i81) +1247: i83 = int_add(i79, i82) debug_merge_point(0, 0, ' #34 POP_JUMP_IF_FALSE') +1250: i84 = int_is_true(i83) -guard_false(i84, descr=) [p0, p1, p2, p3, p4, i83, i68, i66] +guard_false(i84, descr=) [p0, p1, p2, p3, p4, i83, i66, i68] debug_merge_point(0, 0, ' #53 LOAD_FAST') debug_merge_point(0, 0, ' #56 LOAD_CONST') debug_merge_point(0, 0, ' #59 INPLACE_ADD') +1260: i86 = int_add_ovf(i66, 1) -guard_no_overflow(descr=) [p0, p1, i86, p2, p3, p4, None, i68, i66] +guard_no_overflow(descr=) [p0, p1, i86, p2, p3, p4, None, i66, i68] debug_merge_point(0, 0, ' #60 STORE_FAST') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') @@ -1010,150 +1010,150 @@ +1277: i88 = int_add(i68, 1) debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+1288: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] -+1288: i90 = getfield_raw(52008256, descr=) ++1288: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] ++1288: i90 = getfield_raw(51804288, descr=) +1296: i92 = int_lt(i90, 0) -guard_false(i92, descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] +guard_false(i92, descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+1306: jump(p1, p0, p2, p3, p4, i86, i88, descr=TargetToken(140033647688872)) ++1306: jump(p1, p0, p2, p3, p4, i86, i88, descr=TargetToken(139941277981776)) +1322: --end of the loop-- -[230589d074a6] jit-log-opt-bridge} -[230589edd70d] {jit-backend-dump +[1ce3aa5e579f] jit-log-opt-bridge} +[1ce3aa7e0c3a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ddbc +0 E903020000 -[230589ee23a0] jit-backend-dump} -[230589ee2979] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fdbc +0 E903020000 +[1ce3aa7e555a] jit-backend-dump} +[1ce3aa7e5d06] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1de60 +0 E93D020000 -[230589ee347d] jit-backend-dump} -[230589ee3af7] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e17fe60 +0 E93D020000 +[1ce3aa7e6960] jit-backend-dump} +[1ce3aa7e6d8e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e5e9 +0 E9EE040000 -[230589ee4666] jit-backend-dump} -[230589ee4b08] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1805e9 +0 E9EE040000 +[1ce3aa7e7803] jit-backend-dump} +[1ce3aa7e7e36] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e63d +0 E909050000 -[230589ee547d] jit-backend-dump} -[230589ee5873] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18063d +0 E909050000 +[1ce3aa7e885b] jit-backend-dump} +[1ce3aa7e8cd6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1e9cd +0 E910030000 -[230589ee61a7] jit-backend-dump} -[230589ee6660] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1809cd +0 E910030000 +[1ce3aa7e962e] jit-backend-dump} +[1ce3aa7e9a26] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1ea70 +0 E94B030000 -[230589ee6f77] jit-backend-dump} -[23058a3b5326] {jit-backend -[23058a46c37b] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180a70 +0 E94B030000 +[1ce3aa7ea378] jit-backend-dump} +[1ce3aac76e4f] {jit-backend +[1ce3aad31fe8] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1efb0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD6CBC11F5C7F000041FFD349BB4012AA225C7F00004D8B3B4D8D770149BB4012AA225C7F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89AD480100004C8B6E304C89AD500100004C8B6E3848899558010000488B564048898D60010000488B4E484C89BD680100004C898D700100004889BD7801000048899D80010000488985880100004C89AD900100004889959801000048898DA001000049BB5812AA225C7F0000498B0B488D510149BB5812AA225C7F00004989134983F8050F85000000004C8B8550010000418138704500000F8500000000498B50104885D20F8400000000498B48084C8B6A1041817D00005305000F85000000004C8B6A08498B5508498B4510498B5D184883F9000F8C000000004839D90F8D000000004989CD480FAFC84889D74801CA498D4D01498948084983FA000F850000000049BBA8F04E205C7F00004D39DC0F85000000004D8B660849BBC8E048205C7F00004D39DC0F85000000004D8B54241049BBA82E4E205C7F00004D39DA0F85000000004C8B242540D7CE014981FC30C3D4010F850000000048898538010000488995780100004C89B5800100004889BD9001000048898D980100004889D749BBE0EEC11F5C7F00004C895D2041BB005E250141FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C745200000000048833C25C0021903000F8500000000488B8D600100004C8B4110418138D09503000F85000000004C8B4108498B78084C8D7701488985A80100004889BDB00100004C8985B80100004C89C74C89F649BB10EFC11F5C7F00004C895D2041BB105B730041FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C745200000000048833C25C0021903000F85000000004C8B85B8010000498B7810488B85B00100004C8BB5A8010000F6470481742178105749BB91C1C11F5C7F000041FFD3790F4989C349C1EB074983F3F84C0FAB1F4C8974C7104C8B3425409519034983FE000F8C0000000049BB7012AA225C7F00004D8B33498D460149BB7012AA225C7F000049890348399D980100000F8D00000000488B8598010000480FAF85380100004C8BB5900100004901C6488B85980100004883C001488BBD5001000048894708488985780100004C8985980100004C89F749BB60EFC11F5C7F00004C895D2041BB005E250141FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C745200000000048833C25C0021903000F85000000004C8B8598010000498B7808488D4F014889BDA8010000488985B00100004C89C74889CE49BB80EFC11F5C7F00004C895D2041BB105B730041FFD3F6450401740D49BBFDC1C11F5C7F000041FFD348C745200000000048833C25C0021903000F8500000000488B85980100004C8B4010488BBDA8010000488B8DB001000041F640048174227811415049BB91C1C11F5C7F000041FFD3790F4989FB49C1EB074983F3F84D0FAB1849894CF810488B0C25409519034883F9000F8C000000004C8B9D780100004C899D980100004989C04C89B578010000E97AFEFFFF49BBA0769A225C7F0000415349BB20EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB48659A225C7F0000415349BB30EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBC0659A225C7F0000415349BB40EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE0639A225C7F0000415349BB50EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB28769A225C7F0000415349BB60EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBB0759A225C7F0000415349BB70EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB38759A225C7F0000415349BB80EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB48749A225C7F0000415349BB90EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB58739A225C7F0000415349BBA0EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBE0729A225C7F0000415349BBB0EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBF0719A225C7F0000415349BBC0EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB00719A225C7F0000415349BBD0EEC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB88709A225C7F0000415349BBF0EEC11F5C7F0000415349BB85C0C11F5C7F000041FFE349BB58649A225C7F0000415349BB00EFC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB10709A225C7F0000415349BB20EFC11F5C7F0000415349BB85C0C11F5C7F000041FFE349BB986F9A225C7F0000415349BB30EFC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BBC86C9A225C7F0000415349BB40EFC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB80699A225C7F0000415349BB50EFC11F5C7F0000415349BB00C0C11F5C7F000041FFE349BB90779A225C7F0000415349BB70EFC11F5C7F0000415349BB85C0C11F5C7F000041FFE349BB80789A225C7F0000415349BB90EFC11F5C7F0000415349BB85C0C11F5C7F000041FFE349BB08789A225C7F0000415349BBA0EFC11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[23058a488498] jit-backend-dump} -[23058a488eea] {jit-backend-addr -Loop 4 ( #13 FOR_ITER) has address 0x7f5c1fc1f000 to 0x7f5c1fc1f47c (bootstrap 0x7f5c1fc1efb0) -[23058a48ab9b] jit-backend-addr} -[23058a48b4af] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e180fb0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BB403200A1467F00004D8B3B4D8D770149BB403200A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89AD480100004C8B6E304C89AD500100004C8B6E3848899558010000488B564048898D60010000488B4E484C89BD680100004C898D700100004889BD7801000048899D80010000488985880100004C89AD900100004889959801000048898DA001000049BB583200A1467F0000498B0B488D510149BB583200A1467F00004989134983F8050F85000000004C8B8550010000418138E82200000F8500000000498B50104885D20F8400000000498B48084C8B6A1041817D00685505000F85000000004C8B6A08498B5508498B4510498B5D184883F9000F8C000000004839D90F8D000000004989CD480FAFC84889D74801CA498D4D01498948084983FA000F850000000049BBA810A59E467F00004D39DC0F85000000004D8B660849BBC8009F9E467F00004D39DC0F85000000004D8B54241049BBA84EA49E467F00004D39DA0F85000000004C8B242500EFCE014981FCF0EED4010F8500000000488985380100004889957801000048898D800100004C89B5900100004889BD980100004889D749BBE00E189E467F00004C895D2041BB5050250141FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488BBD600100004C8B771041813E489303000F85000000004C8B7708498B4E08488D5101488985A801000048898DB00100004C89B5B80100004C89F74889D649BB100F189E467F00004C895D2041BBB05F730041FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488B95B80100004C8B7210488BBDB0010000488B8DA801000041F646048174227811415649BB91E1179E467F000041FFD3790F4989FB49C1EB074983F3F84D0FAB1E49894CFE10488B0C25807816034883F9000F8C0000000049BB703200A1467F0000498B0B488D790149BB703200A1467F000049893B48399D800100000F8D00000000488BBD80010000480FAFBD38010000488B8D980100004801F9488BBD800100004883C7014C8BB55001000049897E084889957801000048898D800100004889BDA80100004889CF49BB600F189E467F00004C895D2041BB5050250141FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488BBD78010000488B4F084C8D710148898DB0010000488985B80100004C89F649BB800F189E467F00004C895D2041BBB05F730041FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488B8578010000488B48104C8BB5B0010000488BBDB8010000F6410481742178105149BB91E1179E467F000041FFD3790F4D89F349C1EB074983F3F84C0FAB194A897CF110488B3C25807816034883FF000F8C000000004C8B9D800100004C899D780100004C8B9DA80100004C899D800100004889C2E971FEFFFF49BBF878F0A0467F0000415349BB200E189E467F0000415349BB00E0179E467F000041FFE349BB7871F0A0467F0000415349BB300E189E467F0000415349BB00E0179E467F000041FFE349BB986FF0A0467F0000415349BB400E189E467F0000415349BB00E0179E467F000041FFE349BB0071F0A0467F0000415349BB500E189E467F0000415349BB00E0179E467F000041FFE349BB8078F0A0467F0000415349BB600E189E467F0000415349BB00E0179E467F000041FFE349BB0878F0A0467F0000415349BB700E189E467F0000415349BB00E0179E467F000041FFE349BB9077F0A0467F0000415349BB800E189E467F0000415349BB00E0179E467F000041FFE349BBA076F0A0467F0000415349BB900E189E467F0000415349BB00E0179E467F000041FFE349BBB075F0A0467F0000415349BBA00E189E467F0000415349BB00E0179E467F000041FFE349BB3875F0A0467F0000415349BBB00E189E467F0000415349BB00E0179E467F000041FFE349BB4874F0A0467F0000415349BBC00E189E467F0000415349BB00E0179E467F000041FFE349BB5873F0A0467F0000415349BBD00E189E467F0000415349BB00E0179E467F000041FFE349BBE072F0A0467F0000415349BBF00E189E467F0000415349BB85E0179E467F000041FFE349BB1070F0A0467F0000415349BB000F189E467F0000415349BB00E0179E467F000041FFE349BB6872F0A0467F0000415349BB200F189E467F0000415349BB85E0179E467F000041FFE349BBF071F0A0467F0000415349BB300F189E467F0000415349BB00E0179E467F000041FFE349BB506CF0A0467F0000415349BB400F189E467F0000415349BB00E0179E467F000041FFE349BB0869F0A0467F0000415349BB500F189E467F0000415349BB00E0179E467F000041FFE349BBD033EFA0467F0000415349BB700F189E467F0000415349BB85E0179E467F000041FFE349BBE879F0A0467F0000415349BB900F189E467F0000415349BB85E0179E467F000041FFE349BB607AF0A0467F0000415349BBA00F189E467F0000415349BB00E0179E467F000041FFE3 +[1ce3aad4eb07] jit-backend-dump} +[1ce3aad4f6d8] {jit-backend-addr +Loop 4 ( #13 FOR_ITER) has address 0x7f469e181000 to 0x7f469e181487 (bootstrap 0x7f469e180fb0) +[1ce3aad50b8d] jit-backend-addr} +[1ce3aad51292] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f0e4 +0 94030000 -[23058a48c40a] jit-backend-dump} -[23058a48ca78] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1810e4 +0 9F030000 +[1ce3aad520a4] jit-backend-dump} +[1ce3aad526f7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f0f8 +0 A5030000 -[23058a48d4b8] jit-backend-dump} -[23058a48d90c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1810f8 +0 B0030000 +[1ce3aad53178] jit-backend-dump} +[1ce3aad53597] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f105 +0 BD030000 -[23058a48e255] jit-backend-dump} -[23058a48e6a4] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e181105 +0 C8030000 +[1ce3aad53f07] jit-backend-dump} +[1ce3aad54317] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f11b +0 CC030000 -[23058a48efc3] jit-backend-dump} -[23058a48f3ee] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18111b +0 D7030000 +[1ce3aad54c16] jit-backend-dump} +[1ce3aad5503e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f135 +0 D7030000 -[23058a48fcc6] jit-backend-dump} -[23058a4900fd] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e181135 +0 E2030000 +[1ce3aad55901] jit-backend-dump} +[1ce3aad55d1d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f13e +0 F3030000 -[23058a4909ff] jit-backend-dump} -[23058a490e2f] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18113e +0 FE030000 +[1ce3aad565ba] jit-backend-dump} +[1ce3aad569ca] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f15d +0 F9030000 -[23058a491722] jit-backend-dump} -[23058a491b44] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18115d +0 04040000 +[1ce3aad57293] jit-backend-dump} +[1ce3aad576a6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f170 +0 0B040000 -[23058a49243a] jit-backend-dump} -[23058a492859] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e181170 +0 16040000 +[1ce3aad57f84] jit-backend-dump} +[1ce3aad5838b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f187 +0 19040000 -[23058a493131] jit-backend-dump} -[23058a493553] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e181187 +0 24040000 +[1ce3aad58c2e] jit-backend-dump} +[1ce3aad59059] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f19f +0 26040000 -[23058a493e40] jit-backend-dump} -[23058a49441a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18119f +0 31040000 +[1ce3aad59955] jit-backend-dump} +[1ce3aad59f8a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f1b4 +0 5B040000 -[23058a494d07] jit-backend-dump} -[23058a49514c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1811b4 +0 66040000 +[1ce3aad5a898] jit-backend-dump} +[1ce3aad5acd2] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f21b +0 19040000 -[23058a495a3f] jit-backend-dump} -[23058a495e4f] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18121b +0 24040000 +[1ce3aad5b5b3] jit-backend-dump} +[1ce3aad5b9e9] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f233 +0 26040000 -[23058a49673f] jit-backend-dump} -[23058a496b58] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e181233 +0 31040000 +[1ce3aad5c2a1] jit-backend-dump} +[1ce3aad5c6b4] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f29b +0 E3030000 -[23058a49743c] jit-backend-dump} -[23058a49784f] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18129b +0 EE030000 +[1ce3aad5d083] jit-backend-dump} +[1ce3aad603b3] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f2f2 +0 B1030000 -[23058a49813c] jit-backend-dump} -[23058a498555] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1812f4 +0 BA030000 +[1ce3aad60f25] jit-backend-dump} +[1ce3aad61355] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f31d +0 AB030000 -[23058a498ea1] jit-backend-dump} -[23058a4992f6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e18131f +0 B4030000 +[1ce3aad61c3c] jit-backend-dump} +[1ce3aad620e4] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f39e +0 74030000 -[23058a499c1e] jit-backend-dump} -[23058a49c13d] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1813a7 +0 76030000 +[1ce3aad629e3] jit-backend-dump} +[1ce3aad62de7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f402 +0 35030000 -[23058a49cd25] jit-backend-dump} -[23058a49d17a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e181408 +0 3A030000 +[1ce3aad636a1] jit-backend-dump} +[1ce3aad63ac6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f45b +0 01030000 -[23058a49da5e] jit-backend-dump} -[23058a49e816] jit-backend} -[23058a49f698] {jit-log-opt-loop +SYS_EXECUTABLE python +CODE_DUMP @7f469e18145f +0 08030000 +[1ce3aad643f5] jit-backend-dump} +[1ce3aad6551f] jit-backend} +[1ce3aad66ac2] {jit-log-opt-loop # Loop 4 ( #13 FOR_ITER) : loop with 101 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -1173,617 +1173,617 @@ +194: p23 = getarrayitem_gc(p9, 6, descr=) +205: p25 = getarrayitem_gc(p9, 7, descr=) +216: p26 = getfield_gc(p0, descr=) -+216: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, descr=TargetToken(140033694066168)) ++216: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, descr=TargetToken(139941324359072)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+302: guard_value(i7, 5, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19, p21, p23, p25] -+312: guard_class(p19, 25719440, descr=) [p1, p0, p19, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++302: guard_value(i7, 5, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19, p21, p23, p25] ++312: guard_class(p19, 26177128, descr=) [p1, p0, p19, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +332: p29 = getfield_gc(p19, descr=) -+336: guard_nonnull(p29, descr=) [p1, p0, p19, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++336: guard_nonnull(p29, descr=) [p1, p0, p19, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +345: i30 = getfield_gc(p19, descr=) +349: p31 = getfield_gc(p29, descr=) -+353: guard_class(p31, 26050592, descr=) [p1, p0, p19, i30, p31, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++353: guard_class(p31, 26517736, descr=) [p1, p0, p19, i30, p31, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +367: p33 = getfield_gc(p29, descr=) +371: i34 = getfield_gc_pure(p33, descr=) +375: i35 = getfield_gc_pure(p33, descr=) +379: i36 = getfield_gc_pure(p33, descr=) +383: i38 = int_lt(i30, 0) -guard_false(i38, descr=) [p1, p0, p19, i30, i36, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +guard_false(i38, descr=) [p1, p0, p19, i30, i36, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +393: i39 = int_ge(i30, i36) -guard_false(i39, descr=) [p1, p0, p19, i30, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +guard_false(i39, descr=) [p1, p0, p19, i30, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +402: i40 = int_mul(i30, i35) +409: i41 = int_add(i34, i40) +415: i43 = int_add(i30, 1) +419: setfield_gc(p19, i43, descr=) -+423: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p17, p19, p23, p25, i41] ++423: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p17, p19, p23, p25, i41] debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_GLOBAL') -+433: guard_value(p4, ConstPtr(ptr45), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++433: guard_value(p4, ConstPtr(ptr45), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] +452: p46 = getfield_gc(p0, descr=) -+456: guard_value(p46, ConstPtr(ptr47), descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++456: guard_value(p46, ConstPtr(ptr47), descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] +475: p48 = getfield_gc(p46, descr=) -+480: guard_value(p48, ConstPtr(ptr49), descr=) [p1, p0, p48, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] -+499: guard_not_invalidated(descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++480: guard_value(p48, ConstPtr(ptr49), descr=) [p1, p0, p48, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++499: guard_not_invalidated(descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] +499: p51 = getfield_gc(ConstPtr(ptr50), descr=) -+507: guard_value(p51, ConstPtr(ptr52), descr=) [p1, p0, p51, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++507: guard_value(p51, ConstPtr(ptr52), descr=) [p1, p0, p51, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] debug_merge_point(0, 0, ' #22 LOAD_FAST') debug_merge_point(0, 0, ' #25 CALL_FUNCTION') +520: p54 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i41, descr=) -+608: guard_no_exception(descr=) [p1, p0, p54, p2, p3, p6, p13, p15, p17, p19, p25, i41] ++608: guard_no_exception(descr=) [p1, p0, p54, p2, p3, p6, p13, p15, p17, p19, p25, i41] debug_merge_point(0, 0, ' #28 LIST_APPEND') +623: p55 = getfield_gc(p17, descr=) -+634: guard_class(p55, 25936624, descr=) [p1, p0, p55, p17, p2, p3, p6, p13, p15, p19, p25, p54, i41] ++634: guard_class(p55, 26402504, descr=) [p1, p0, p55, p17, p2, p3, p6, p13, p15, p19, p25, p54, i41] +647: p57 = getfield_gc(p17, descr=) +651: i58 = getfield_gc(p57, descr=) +655: i60 = int_add(i58, 1) +659: p61 = getfield_gc(p57, descr=) +659: i62 = arraylen_gc(p61, descr=) -+659: call(ConstClass(_ll_list_resize_ge_trampoline__v1054___simple_call__function_), p57, i60, descr=) -+736: guard_no_exception(descr=) [p1, p0, i58, p54, p57, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] ++659: call(ConstClass(_ll_list_resize_ge_trampoline__v1053___simple_call__function_), p57, i60, descr=) ++736: guard_no_exception(descr=) [p1, p0, i58, p54, p57, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] +751: p65 = getfield_gc(p57, descr=) setarrayitem_gc(p65, i58, p54, descr=) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+820: i67 = getfield_raw(52008256, descr=) -+828: i69 = int_lt(i67, 0) -guard_false(i69, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] ++822: i67 = getfield_raw(51804288, descr=) ++830: i69 = int_lt(i67, 0) +guard_false(i69, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] debug_merge_point(0, 0, ' #13 FOR_ITER') -+838: p70 = same_as(ConstPtr(ptr49)) -+838: label(p0, p1, p2, p3, p6, i41, p13, p15, p17, p19, p25, i43, i36, i35, i34, p57, descr=TargetToken(140033694066080)) ++840: p70 = same_as(ConstPtr(ptr49)) ++840: label(p0, p1, p2, p3, p6, i41, p13, p15, p17, p19, p25, i43, i36, i35, i34, p57, descr=TargetToken(139941324358984)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+868: i71 = int_ge(i43, i36) -guard_false(i71, descr=) [p1, p0, p19, i43, i35, i34, p2, p3, p6, p13, p15, p17, p25, i41] -+881: i72 = int_mul(i43, i35) -+896: i73 = int_add(i34, i72) -+906: i74 = int_add(i43, 1) ++870: i71 = int_ge(i43, i36) +guard_false(i71, descr=) [p1, p0, p19, i43, i35, i34, p2, p3, p6, p13, p15, p17, p25, i41] ++883: i72 = int_mul(i43, i35) ++898: i73 = int_add(i34, i72) ++908: i74 = int_add(i43, 1) debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_GLOBAL') -+917: setfield_gc(p19, i74, descr=) -+928: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++919: setfield_gc(p19, i74, descr=) ++930: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] debug_merge_point(0, 0, ' #22 LOAD_FAST') debug_merge_point(0, 0, ' #25 CALL_FUNCTION') -+928: p75 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i73, descr=) -+995: guard_no_exception(descr=) [p1, p0, p75, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++930: p75 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i73, descr=) ++1004: guard_no_exception(descr=) [p1, p0, p75, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] debug_merge_point(0, 0, ' #28 LIST_APPEND') -+1010: i76 = getfield_gc(p57, descr=) -+1021: i77 = int_add(i76, 1) -+1025: p78 = getfield_gc(p57, descr=) -+1025: i79 = arraylen_gc(p78, descr=) -+1025: call(ConstClass(_ll_list_resize_ge_trampoline__v1054___simple_call__function_), p57, i77, descr=) -+1095: guard_no_exception(descr=) [p1, p0, i76, p75, p57, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] -+1110: p80 = getfield_gc(p57, descr=) ++1019: i76 = getfield_gc(p57, descr=) ++1030: i77 = int_add(i76, 1) ++1034: p78 = getfield_gc(p57, descr=) ++1034: i79 = arraylen_gc(p78, descr=) ++1034: call(ConstClass(_ll_list_resize_ge_trampoline__v1053___simple_call__function_), p57, i77, descr=) ++1101: guard_no_exception(descr=) [p1, p0, i76, p75, p57, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++1116: p80 = getfield_gc(p57, descr=) setarrayitem_gc(p80, i76, p75, descr=) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+1181: i81 = getfield_raw(52008256, descr=) -+1189: i82 = int_lt(i81, 0) -guard_false(i82, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++1185: i81 = getfield_raw(51804288, descr=) ++1193: i82 = int_lt(i81, 0) +guard_false(i82, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] debug_merge_point(0, 0, ' #13 FOR_ITER') -+1199: jump(p0, p1, p2, p3, p6, i73, p13, p15, p17, p19, p25, i74, i36, i35, i34, p57, descr=TargetToken(140033694066080)) -+1228: --end of the loop-- -[23058a519316] jit-log-opt-loop} -[23058a9b27f2] {jit-backend -[23058aa64710] {jit-backend-dump ++1203: jump(p0, p1, p2, p3, p6, i73, p13, p15, p17, p19, p25, i74, i36, i35, i34, p57, descr=TargetToken(139941324358984)) ++1239: --end of the loop-- +[1ce3aade160f] jit-log-opt-loop} +[1ce3ab299257] {jit-backend +[1ce3ab32a8f2] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f7a8 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD6CBC11F5C7F000041FFD349BB8812AA225C7F00004D8B3B4D8D770149BB8812AA225C7F00004D89334C8BB5400100004D8B7E404C8BAD380100004F0FB6642F184983FC330F85000000004D8D65014D89661849C74620000000004D896E2848C745580100000048C74510A0ABFA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBF0A29B225C7F0000415349BB98F7C11F5C7F0000415349BB00C0C11F5C7F000041FFE3 -[23058aa69522] jit-backend-dump} -[23058aa69bae] {jit-backend-addr -Loop 5 (re StrLiteralSearch at 11/51 [17, 8, 3, 1, 1, 1, 1, 51, 0, 19, 51, 1]) has address 0x7f5c1fc1f7f8 to 0x7f5c1fc1f893 (bootstrap 0x7f5c1fc1f7a8) -[23058aa6ae3d] jit-backend-addr} -[23058aa6b636] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7f469e1817b0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BB883200A1467F00004D8B3B4D8D770149BB883200A1467F00004D89334C8BB5400100004D8B7E404C8BAD380100004F0FB6642F184983FC330F85000000004D8D65014D89661849C74620000000004D896E2848C745580100000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBF0C2F1A0467F0000415349BBA017189E467F0000415349BB00E0179E467F000041FFE3 +[1ce3ab32f473] jit-backend-dump} +[1ce3ab32fb31] {jit-backend-addr +Loop 5 (re StrLiteralSearch at 11/51 [17, 8, 3, 1, 1, 1, 1, 51, 0, 19, 51, 1]) has address 0x7f469e181800 to 0x7f469e18189b (bootstrap 0x7f469e1817b0) +[1ce3ab330ae0] jit-backend-addr} +[1ce3ab331277] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @7f5c1fc1f834 +0 5B000000 -[23058aa6c2ba] jit-backend-dump} -[23058aa6cc7d] jit-backend} From noreply at buildbot.pypy.org Wed Mar 20 02:08:03 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 02:08:03 +0100 (CET) Subject: [pypy-commit] pypy scalar_get_set: close about-to-be-merged branch Message-ID: <20130320010803.79F5A1C13F4@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: scalar_get_set Changeset: r62533:281211b8e85a Date: 2013-03-19 17:50 -0700 http://bitbucket.org/pypy/pypy/changeset/281211b8e85a/ Log: close about-to-be-merged branch From noreply at buildbot.pypy.org Wed Mar 20 02:08:04 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 02:08:04 +0100 (CET) Subject: [pypy-commit] pypy default: merge scalar_get_set which adds get_, set_, imag, real for scalar arrays Message-ID: <20130320010804.B7CA41C14B0@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62534:f1b95506732f Date: 2013-03-19 17:52 -0700 http://bitbucket.org/pypy/pypy/changeset/f1b95506732f/ Log: merge scalar_get_set which adds get_, set_, imag, real for scalar arrays diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -82,6 +82,10 @@ return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) + def set_real(self, space, orig_array, w_value): + tmp = self.get_real(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -98,6 +102,10 @@ impl.fill(self.dtype.box(0)) return impl + def set_imag(self, space, orig_array, w_value): + tmp = self.get_imag(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + # -------------------- applevel get/setitem ----------------------- @jit.unroll_safe diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -1,6 +1,6 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.base import W_NDimArray, convert_to_array from pypy.module.micronumpy import support from pypy.interpreter.error import OperationError @@ -38,6 +38,9 @@ def get_strides(self): return [] + def get_backstrides(self): + return [] + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) @@ -58,6 +61,62 @@ def transpose(self, _): return self + def get_real(self, orig_array): + if self.dtype.is_complex_type(): + scalar = Scalar(self.dtype.float_type) + scalar.value = self.value.convert_real_to(scalar.dtype) + return scalar + return self + + def set_real(self, space, orig_array, w_val): + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type or self.dtype + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + if self.dtype.is_complex_type(): + #imag = dtype.itemtype.unbox(self.value.convert_imag_to(dtype)) + #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). + # convert_to(dtype)) + #self.value = self.dtype.box_complex(val, imag) + self.value = self.dtype.itemtype.composite(w_arr.get_scalar_value().convert_to(dtype), + self.value.convert_imag_to(dtype)) + else: + self.value = w_arr.get_scalar_value() + + def get_imag(self, orig_array): + if self.dtype.is_complex_type(): + scalar = Scalar(self.dtype.float_type) + scalar.value = self.value.convert_imag_to(scalar.dtype) + return scalar + scalar = Scalar(self.dtype) + if self.dtype.is_flexible_type(): + scalar.value = self.value + else: + scalar.value = scalar.dtype.itemtype.box(0) + return scalar + + def set_imag(self, space, orig_array, w_val): + #Only called on complex dtype + assert self.dtype.is_complex_type() + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + #real = dtype.itemtype.unbox(self.value.convert_real_to(dtype)) + #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). + # convert_to(dtype)) + #self.value = self.dtype.box_complex(real, val) + self.value = self.dtype.itemtype.composite( + self.value.convert_real_to(dtype), + w_arr.get_scalar_value(), + ) + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) 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 @@ -71,7 +71,6 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) - def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -272,16 +272,14 @@ def descr_set_real(self, space, w_value): # copy (broadcast) values into self - tmp = self.implementation.get_real(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_real(space, self, w_value) def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) - tmp = self.implementation.get_imag(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_imag(space, self, w_value) def descr_reshape(self, space, args_w): """reshape(...) 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 @@ -140,25 +140,25 @@ def test_fmax(self): from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') - a = array((complex(ninf, 10), complex(10, ninf), + a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), 5+5j, 5-5j, -5+5j, -5-5j, 0+5j, 0-5j, 5, -5, complex(nan, 0), complex(0, nan)), dtype = complex) b = [ninf]*a.size - res = [a[0 ], a[1 ], a[2 ], a[3 ], + res = [a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ], a[8 ], a[9 ], a[10], a[11], b[12], b[13]] assert (fmax(a, b) == res).all() b = [inf]*a.size - res = [b[0 ], b[1 ], a[2 ], b[3 ], + res = [b[0 ], b[1 ], a[2 ], b[3 ], b[4 ], b[5 ], b[6 ], b[7 ], b[8 ], b[9 ], b[10], b[11], b[12], b[13]] assert (fmax(a, b) == res).all() b = [0]*a.size - res = [b[0 ], a[1 ], a[2 ], a[3 ], + res = [b[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], b[6 ], b[7 ], a[8 ], b[9 ], a[10], b[11], b[12], b[13]] @@ -167,25 +167,25 @@ def test_fmin(self): from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') - a = array((complex(ninf, 10), complex(10, ninf), + a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), 5+5j, 5-5j, -5+5j, -5-5j, 0+5j, 0-5j, 5, -5, complex(nan, 0), complex(0, nan)), dtype = complex) b = [inf]*a.size - res = [a[0 ], a[1 ], b[2 ], a[3 ], + res = [a[0 ], a[1 ], b[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ], a[8 ], a[9 ], a[10], a[11], b[12], b[13]] assert (fmin(a, b) == res).all() b = [ninf]*a.size - res = [b[0 ], b[1 ], b[2 ], b[3 ], + res = [b[0 ], b[1 ], b[2 ], b[3 ], b[4 ], b[5 ], b[6 ], b[7 ], b[8 ], b[9 ], b[10], b[11], b[12], b[13]] assert (fmin(a, b) == res).all() b = [0]*a.size - res = [a[0 ], b[1 ], b[2 ], b[3 ], + res = [a[0 ], b[1 ], b[2 ], b[3 ], b[4 ], b[5 ], a[6 ], a[7 ], b[8 ], a[9 ], b[10], a[11], b[12], b[13]] @@ -205,17 +205,17 @@ pass # no longdouble yet inf = float('inf') nan = float('nan') - #complex - orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, - complex(inf, 3), complex(inf, -3), complex(inf, -inf), + #complex + orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, + complex(inf, 3), complex(inf, -3), complex(inf, -inf), complex(nan, 3), 0+0j, 0-0j] a2 = 2.**2 + 4.**2 r = 2. / a2 i = 4. / a2 cnan = complex(nan, nan) - expected = [complex(r, -i), complex(-r, -i), complex(r, i), - complex(-r, i), - -0j, 0j, cnan, + expected = [complex(r, -i), complex(-r, -i), complex(r, i), + complex(-r, i), + -0j, 0j, cnan, cnan, cnan, cnan] for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) @@ -225,7 +225,7 @@ def test_floorceiltrunc(self): from numpypy import array, floor, ceil, trunc - a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) + a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) @@ -270,11 +270,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res[0]) - t2 = float(b[i].real) + t1 = float(res[0]) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res[1]) - t2 = float(b[i].imag) + t1 = float(res[1]) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_expm1(self): @@ -310,11 +310,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): @@ -330,16 +330,16 @@ raises(TypeError, logaddexp, complex(1, 1), complex(3, 3)) raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3)) raises(TypeError, arctan2, complex(1, 1), complex(3, 3)) - raises (TypeError, fmod, complex(90,90), 3) + raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): from numpypy import isnan, isinf, array - assert (isnan(array([0.2+2j, complex(float('inf'),0), + assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ [False, False, False, True, True]).all() - assert (isinf(array([0.2+2j, complex(float('inf'),0), + assert (isinf(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ [False, True, True, False, False]).all() @@ -374,7 +374,7 @@ b = power(a, p) for i in range(len(a)): try: - r = self.c_pow((float(a[i].real), float(a[i].imag)), + r = self.c_pow((float(a[i].real), float(a[i].imag)), (float(p.real), float(p.imag))) except ZeroDivisionError: r = (nan, nan) @@ -384,10 +384,10 @@ r = (nan, nan) msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ (c,a[i], p, b[i], r) - t1 = float(r[0]) - t2 = float(b[i].real) + t1 = float(r[0]) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(r[1]) + t1 = float(r[1]) t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) @@ -445,11 +445,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7)): b = log1p(array(a,dtype=c)) @@ -465,11 +465,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): @@ -520,7 +520,26 @@ assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real + b[0] = 1024 + assert a[0].real == 1024 assert b.dtype == dtype(float) + a = array(complex(3.0, 4.0)) + b = a.real + assert b == array(3) + a.real = 1024 + assert a.real == 1024 + assert a.imag == array(4) + assert b.dtype == dtype(float) + a = array(4.0) + b = a.imag + assert b == 0 + assert b.dtype == dtype(float) + raises(TypeError, 'a.imag = 1024') + raises(ValueError, 'a.real = [1, 3]') + a = array('abc') + assert str(a.real) == 'abc' + # numpy imag for flexible types returns self + assert str(a.imag) == 'abc' for complex_ in complex_dtypes: O = complex(0, 0) @@ -547,12 +566,12 @@ assert add(c1, c2) == complex_(complex(4, 6)) assert add(c1, c2) == complex(4, 6) - + assert sub(c0, c0) == sub(c1, c1) == 0 assert sub(c1, c2) == complex(-2, -2) assert negative(complex(1,1)) == complex(-1, -1) assert negative(complex(0, 0)) == 0 - + assert multiply(1, c1) == c1 assert multiply(2, c2) == complex(6, 8) @@ -610,7 +629,7 @@ for complex_, abs_err, testcases in (\ (np.complex128, 5e-323, self.testcases128), - # (np.complex64, 5e-32, self.testcases64), + # (np.complex64, 5e-32, self.testcases64), ): for id, fn, ar, ai, er, ei, flags in testcases: arg = complex_(complex(ar, ai)) @@ -648,7 +667,7 @@ ) % (id, fn, complex_, ar, ai, expected[0], expected[1], actual[0], actual[1]) - + # since rAlmostEqual is a wrapped function, # convert arguments to avoid boxed values rAlmostEqual(float(expected[0]), float(actual[0]), 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 @@ -1150,6 +1150,14 @@ return rfloat.NAN, rfloat.NAN return rfloat.INFINITY, rfloat.INFINITY + @specialize.argtype(1) + def composite(self, v1, v2): + assert isinstance(v1, self.ComponentBoxType) + assert isinstance(v2, self.ComponentBoxType) + real = v1.value + imag = v2.value + return self.box_complex(real, imag) + @complex_unary_op def pos(self, v): return v From noreply at buildbot.pypy.org Wed Mar 20 02:08:06 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 02:08:06 +0100 (CET) Subject: [pypy-commit] pypy default: update whatsnew for merged branch Message-ID: <20130320010806.11A891C13F4@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62535:84f1205eb746 Date: 2013-03-19 17:53 -0700 http://bitbucket.org/pypy/pypy/changeset/84f1205eb746/ Log: update whatsnew for merged branch 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 @@ -48,6 +48,7 @@ .. branch: fix-version-tool .. branch: popen2-removal .. branch: pickle-dumps +.. branch: scalar_get_set .. branch: release-2.0-beta1 From noreply at buildbot.pypy.org Wed Mar 20 02:08:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 02:08:08 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130320010808.9408B1C13F4@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62536:2737da534798 Date: 2013-03-19 18:07 -0700 http://bitbucket.org/pypy/pypy/changeset/2737da534798/ Log: merge heads diff too long, truncating to 2000 out of 88607 lines diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/pypy/tool/jitlogparser/test/logtest2.log --- a/pypy/tool/jitlogparser/test/logtest2.log +++ b/pypy/tool/jitlogparser/test/logtest2.log @@ -1,121 +1,121 @@ -[3304d0bb187] {jit-backend-dump +[1cffd8feb691] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0ca602] jit-backend-dump} -[3304d0cfdf4] {jit-backend-dump +CODE_DUMP @7f5514b31000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd8ffaba6] jit-backend-dump} +[1cffd90012ee] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0d2b27] jit-backend-dump} -[3304d0d73d6] {jit-backend-dump +CODE_DUMP @7f5514b31085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd9003b76] jit-backend-dump} +[1cffd900719f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d512e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[3304d0d9073] jit-backend-dump} -[3304d0db1d8] {jit-backend-dump +CODE_DUMP @7f5514b3112e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1cffd9008c81] jit-backend-dump} +[1cffd900b384] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[3304d0dce9e] jit-backend-dump} -[3304d0dfc06] {jit-backend-dump +CODE_DUMP @7f5514b31191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[1cffd900cf18] jit-backend-dump} +[1cffd9010345] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d51fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C25C80219034C8B2425C002190348C70425C00219030000000048C70425C80219030000000041BBC069120141FFD3F20F10442418488B44240848891C25C80219034C892425C0021903488B5C24284C8B642430488D642438C3 -[3304d0e1a04] jit-backend-dump} -[3304d0e4ae5] {jit-backend-dump +CODE_DUMP @7f5514b311fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 +[1cffd9011f0b] jit-backend-dump} +[1cffd9015bd8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C25C802190348894D38488B1C25C002190348C70425C00219030000000048C70425C80219030000000041BB90E3E80041FFD34889C5488B4D3848C745380000000048890C25C802190348891C25C00219034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[3304d0e9130] jit-backend-dump} -[3304d0ea4a1] {jit-backend-dump +CODE_DUMP @7f5514b31275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[1cffd901a191] jit-backend-dump} +[1cffd901b3a6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0ecf16] jit-backend-dump} -[3304d0ee1ff] {jit-backend-dump +CODE_DUMP @7f5514b31491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd901dc46] jit-backend-dump} +[1cffd901ef79] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C25C802190348C70425C00219030000000048C70425C80219030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d0fca06] jit-backend-dump} -[3304d0fe4ac] {jit-backend-dump +CODE_DUMP @7f5514b31595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd902ce01] jit-backend-dump} +[1cffd902e819] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d56bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBC069120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[3304d1018ac] jit-backend-dump} -[3304d103089] {jit-backend-dump +CODE_DUMP @7f5514b316bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1cffd9031b79] jit-backend-dump} +[1cffd90331b0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d581e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BB006B120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[3304d1062c0] jit-backend-dump} -[3304d1072c1] {jit-backend-dump +CODE_DUMP @7f5514b3181e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[1cffd903629a] jit-backend-dump} +[1cffd903736b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5988 +0 488B0425C802190348C70425C00219030000000048C70425C8021903000000004889453848C745108064B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[3304d1089ec] jit-backend-dump} -[3304d11572c] {jit-backend-dump +CODE_DUMP @7f5514b31988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[1cffd9038a70] jit-backend-dump} +[1cffd903e2cd] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d59e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBF0ACE80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD517D6A477F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25C8EEB50148C7452000000000C34883C40849BB88597D6A477F000041FFE3 -[3304d120245] jit-backend-dump} -[3304d122916] {jit-backend-dump +CODE_DUMP @7f5514b319e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFD11B314557F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB8819B314557F000041FFE3 +[1cffd904265b] jit-backend-dump} +[1cffd90448f2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5bd6 +0 4889E74883EC0841BB9018210141FFD34883C408488B0425C00219034885C07501C34883C40849BB88597D6A477F000041FFE3 -[3304d1240c0] jit-backend-dump} -[3304d1246a0] {jit-backend-counts -[3304d124ab0] jit-backend-counts} -[3304d690a50] {jit-backend -[3304db64ec0] {jit-backend-dump +CODE_DUMP @7f5514b31bd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB8819B314557F000041FFE3 +[1cffd9045d15] jit-backend-dump} +[1cffd904647a] {jit-backend-counts +[1cffd9046851] jit-backend-counts} +[1cffd9636773] {jit-backend +[1cffd9afbdde] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBF0905D6D477F00004D8B3B4D8D770149BBF0905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08915D6D477F0000498B0B488D410149BB08915D6D477F00004989034983F8020F85000000004883FB017206813B680B00000F85000000004983FA000F850000000049BB20C0FC6A477F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425409519034983FC000F8C0000000049BB20915D6D477F00004D8B234D8D54240149BB20915D6D477F00004D89134883FB0A0F8D000000004C8D5301488B1C25409519034883FB000F8C000000004C89D3E9B9FFFFFF49BB2020FD6A477F0000415349BB405C7D6A477F0000415349BB00507D6A477F000041FFE349BB3806036B477F0000415349BB505C7D6A477F0000415349BB00507D6A477F000041FFE349BBC005036B477F0000415349BB605C7D6A477F0000415349BB00507D6A477F000041FFE349BB4805036B477F0000415349BB705C7D6A477F0000415349BB00507D6A477F000041FFE349BBD004036B477F0000415349BB805C7D6A477F0000415349BB00507D6A477F000041FFE349BB5804036B477F0000415349BB905C7D6A477F0000415349BB00507D6A477F000041FFE349BBE003036B477F0000415349BBA05C7D6A477F0000415349BB00507D6A477F000041FFE349BB6803036B477F0000415349BBB05C7D6A477F0000415349BB00507D6A477F000041FFE349BBF002036B477F0000415349BBC05C7D6A477F0000415349BB00507D6A477F000041FFE349BB7802036B477F0000415349BBD05C7D6A477F0000415349BB00507D6A477F000041FFE3 -[3304db7d5e4] jit-backend-dump} -[3304db7df74] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 0x7f476a7d5d30 to 0x7f476a7d5e80 (bootstrap 0x7f476a7d5ce0) -[3304db7f906] jit-backend-addr} -[3304db8036d] {jit-backend-dump +CODE_DUMP @7f5514b31ce0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD61BB314557F000041FFD349BBF0509317557F00004D8B3B4D8D770149BBF0509317557F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000048898D7801000049BB08519317557F0000498B0B488D410149BB08519317557F00004989034983F8020F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB20803215557F00004D39DC0F85000000004C8B63084983FC0A0F8D00000000498D5C24014C8B2425807816034983FC000F8C0000000049BB20519317557F00004D8B234D8D54240149BB20519317557F00004D89134883FB0A0F8D000000004C8D5301488B1C25807816034883FB000F8C000000004C89D3E9B9FFFFFF49BB20E03215557F0000415349BB401CB314557F0000415349BB0010B314557F000041FFE349BB38C63815557F0000415349BB501CB314557F0000415349BB0010B314557F000041FFE349BBC0C53815557F0000415349BB601CB314557F0000415349BB0010B314557F000041FFE349BB48C53815557F0000415349BB701CB314557F0000415349BB0010B314557F000041FFE349BBD0C43815557F0000415349BB801CB314557F0000415349BB0010B314557F000041FFE349BB58C43815557F0000415349BB901CB314557F0000415349BB0010B314557F000041FFE349BBE0C33815557F0000415349BBA01CB314557F0000415349BB0010B314557F000041FFE349BB68C33815557F0000415349BBB01CB314557F0000415349BB0010B314557F000041FFE349BBF0C23815557F0000415349BBC01CB314557F0000415349BB0010B314557F000041FFE349BB78C23815557F0000415349BBD01CB314557F0000415349BB0010B314557F000041FFE3 +[1cffd9b146d6] jit-backend-dump} +[1cffd9b14ff3] {jit-backend-addr +Loop 0 ( #9 LOAD_FAST) has address 0x7f5514b31d30 to 0x7f5514b31e80 (bootstrap 0x7f5514b31ce0) +[1cffd9b16753] jit-backend-addr} +[1cffd9b17245] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5de1 +0 9B000000 -[3304db81160] jit-backend-dump} -[3304db81772] {jit-backend-dump +CODE_DUMP @7f5514b31de1 +0 9B000000 +[1cffd9b18103] jit-backend-dump} +[1cffd9b18762] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5df3 +0 AE000000 -[3304db8217a] jit-backend-dump} -[3304db825e3] {jit-backend-dump +CODE_DUMP @7f5514b31df3 +0 AE000000 +[1cffd9b191ae] jit-backend-dump} +[1cffd9b1960b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5dfd +0 C9000000 -[3304db82ee8] jit-backend-dump} -[3304db83330] {jit-backend-dump +CODE_DUMP @7f5514b31dfd +0 C9000000 +[1cffd9b19f1f] jit-backend-dump} +[1cffd9b1a32f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e10 +0 DB000000 -[3304db83c9d] jit-backend-dump} -[3304db840c2] {jit-backend-dump +CODE_DUMP @7f5514b31e10 +0 DB000000 +[1cffd9b1ac8d] jit-backend-dump} +[1cffd9b1b091] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e1e +0 F2000000 -[3304db849f0] jit-backend-dump} -[3304db84f62] {jit-backend-dump +CODE_DUMP @7f5514b31e1e +0 F2000000 +[1cffd9b1ba54] jit-backend-dump} +[1cffd9b1bfec] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e35 +0 25010000 -[3304db8586f] jit-backend-dump} -[3304db85c9d] {jit-backend-dump +CODE_DUMP @7f5514b31e35 +0 25010000 +[1cffd9b1c8d3] jit-backend-dump} +[1cffd9b1ccfb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e5e +0 21010000 -[3304db86572] jit-backend-dump} -[3304db869e7] {jit-backend-dump +CODE_DUMP @7f5514b31e5e +0 21010000 +[1cffd9b1d5d6] jit-backend-dump} +[1cffd9b1da25] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d5e74 +0 55010000 -[3304db872e3] jit-backend-dump} -[3304db88112] jit-backend} -[3304db8ae6c] {jit-log-opt-loop +CODE_DUMP @7f5514b31e74 +0 55010000 +[1cffd9b1e3b8] jit-backend-dump} +[1cffd9b1f0b2] jit-backend} +[1cffd9b20d9f] {jit-log-opt-loop # Loop 0 ( #9 LOAD_FAST) : loop with 59 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -131,17 +131,17 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944714371104)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140003404595232)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] -+279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] ++251: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++261: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15, p17] ++279: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] ++289: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] debug_merge_point(0, 0, ' #15 COMPARE_OP') +308: i23 = getfield_gc_pure(p11, descr=) +312: i25 = int_lt(i23, 10) -guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] +guard_true(i25, descr=) [p1, p0, p11, p2, p3, p6, p13] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_CONST') debug_merge_point(0, 0, ' #24 STORE_FAST') @@ -151,17 +151,17 @@ +322: i27 = int_add(i23, 1) debug_merge_point(0, 0, ' #34 STORE_FAST') debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') -+327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] -+327: i29 = getfield_raw(52008256, descr=) ++327: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i27] ++327: i29 = getfield_raw(51804288, descr=) +335: i31 = int_lt(i29, 0) -guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] +guard_false(i31, descr=) [p1, p0, p2, p3, p6, i27] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(139944714371192)) ++345: label(p0, p1, p2, p3, p6, i27, descr=TargetToken(140003404595320)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +376: i32 = int_lt(i27, 10) -guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] +guard_true(i32, descr=) [p1, p0, p2, p3, p6, i27] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_CONST') debug_merge_point(0, 0, ' #24 STORE_FAST') @@ -171,95 +171,95 @@ +386: i33 = int_add(i27, 1) debug_merge_point(0, 0, ' #34 STORE_FAST') debug_merge_point(0, 0, ' #37 JUMP_ABSOLUTE') -+390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] -+390: i35 = getfield_raw(52008256, descr=) ++390: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i33, None] ++390: i35 = getfield_raw(51804288, descr=) +398: i36 = int_lt(i35, 0) -guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] +guard_false(i36, descr=) [p1, p0, p2, p3, p6, i33, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(139944714371192)) ++408: jump(p0, p1, p2, p3, p6, i33, descr=TargetToken(140003404595320)) +416: --end of the loop-- -[3304dc0f6eb] jit-log-opt-loop} -[3304ddc81da] {jit-backend -[3304dec8bed] {jit-backend-dump +[1cffd9ba83b9] jit-log-opt-loop} +[1cffd9d7af1e] {jit-backend +[1cffd9ea4873] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425709619034829E0483B042550B90403760D49BBD65B7D6A477F000041FFD349BBD8905D6D477F00004D8B3B4D8D770149BBD8905D6D477F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38915D6D477F0000498B0B488D590149BB38915D6D477F000049891B4983F8030F85000000008138704500000F85000000004C8B40104D85C00F8400000000488B5808498B48108139005305000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A909403000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB88607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C745200000000048833C25C0021903000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425409519034883F8000F8C00000000488B856801000049BB588C026B477F00004C39D80F850000000049BB50915D6D477F00004D8B13498D420149BB50915D6D477F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE8607D6A477F00004C895D2041BB0055730041FFD3F6450401740D49BBFD517D6A477F000041FFD348C74520000000004C8B958001000049895A0848833C25C0021903000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25409519034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0D6496D477F0000415349BB08607D6A477F0000415349BB00507D6A477F000041FFE349BB708A4D6D477F0000415349BB18607D6A477F0000415349BB00507D6A477F000041FFE349BBF8894D6D477F0000415349BB28607D6A477F0000415349BB00507D6A477F000041FFE349BB80894D6D477F0000415349BB38607D6A477F0000415349BB00507D6A477F000041FFE349BB08894D6D477F0000415349BB48607D6A477F0000415349BB00507D6A477F000041FFE349BB90884D6D477F0000415349BB58607D6A477F0000415349BB00507D6A477F000041FFE349BB18884D6D477F0000415349BB68607D6A477F0000415349BB00507D6A477F000041FFE349BBA0874D6D477F0000415349BB78607D6A477F0000415349BB00507D6A477F000041FFE349BB28874D6D477F0000415349BB98607D6A477F0000415349BB85507D6A477F000041FFE349BBB0864D6D477F0000415349BBA8607D6A477F0000415349BB00507D6A477F000041FFE349BB38864D6D477F0000415349BBB8607D6A477F0000415349BB00507D6A477F000041FFE349BBC0854D6D477F0000415349BBC8607D6A477F0000415349BB00507D6A477F000041FFE349BB48854D6D477F0000415349BBD8607D6A477F0000415349BB00507D6A477F000041FFE349BBD0844D6D477F0000415349BBF8607D6A477F0000415349BB85507D6A477F000041FFE349BB58844D6D477F0000415349BB08617D6A477F0000415349BB00507D6A477F000041FFE349BBE0834D6D477F0000415349BB18617D6A477F0000415349BB00507D6A477F000041FFE3 -[3304dedb0c9] jit-backend-dump} -[3304dedb9eb] {jit-backend-addr -Loop 1 ( #13 FOR_ITER) has address 0x7f476a7d6178 to 0x7f476a7d6470 (bootstrap 0x7f476a7d6128) -[3304dedcbfe] jit-backend-addr} -[3304dedd31e] {jit-backend-dump +CODE_DUMP @7f5514b32128 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD61BB314557F000041FFD349BBD8509317557F00004D8B3B4D8D770149BBD8509317557F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD6001000048899D6801000048898D7001000049BB38519317557F0000498B0B488D590149BB38519317557F000049891B4983F8030F85000000008138E82200000F85000000004C8B40104D85C00F8400000000488B5808498B48108139685505000F8500000000498B48084C8B4108488B79104C8B49184883FB000F8C000000004C39CB0F8D000000004889D9480FAFDF4D89C54901D8488D5901488958084983FA000F85000000004C8B521041813A089203000F85000000004C8B5208498B4A084C8D79014C8985600100004C89A56801000048898D700100004C898D78010000488985800100004C8995880100004889BD90010000488995980100004C89D74C89FE49BB8820B314557F00004C895D2041BBE060730041FFD3F6450401740D49BBFD11B314557F000041FFD348C745200000000048833C2500E61503000F8500000000488B9588010000488B7A104C8B9560010000488B85700100004C8954C710488B0425807816034883F8000F8C00000000488B856801000049BB584C3815557F00004C39D80F850000000049BB50519317557F00004D8B13498D420149BB50519317557F0000498903483B9D780100000F8D000000004889D8480FAF9D900100004D89EA4901DD488D5801488B4208488D780148899560010000488985680100004C8995700100004889FE4889D749BBE820B314557F00004C895D2041BBE060730041FFD3F6450401740D49BBFD11B314557F000041FFD348C74520000000004C8B958001000049895A0848833C2500E61503000F8500000000488B8560010000488B5010488BBD680100004C896CFA10488B3C25807816034883FF000F8C000000004C89AD600100004C8995800100004C8BAD700100004889C2E90BFFFFFF49BBA0967F17557F0000415349BB0820B314557F0000415349BB0010B314557F000041FFE349BB704A8317557F0000415349BB1820B314557F0000415349BB0010B314557F000041FFE349BBF8498317557F0000415349BB2820B314557F0000415349BB0010B314557F000041FFE349BB80498317557F0000415349BB3820B314557F0000415349BB0010B314557F000041FFE349BB08498317557F0000415349BB4820B314557F0000415349BB0010B314557F000041FFE349BB90488317557F0000415349BB5820B314557F0000415349BB0010B314557F000041FFE349BB18488317557F0000415349BB6820B314557F0000415349BB0010B314557F000041FFE349BBA0478317557F0000415349BB7820B314557F0000415349BB0010B314557F000041FFE349BB28478317557F0000415349BB9820B314557F0000415349BB8510B314557F000041FFE349BBB0468317557F0000415349BBA820B314557F0000415349BB0010B314557F000041FFE349BB38468317557F0000415349BBB820B314557F0000415349BB0010B314557F000041FFE349BBC0458317557F0000415349BBC820B314557F0000415349BB0010B314557F000041FFE349BB48458317557F0000415349BBD820B314557F0000415349BB0010B314557F000041FFE349BBD0448317557F0000415349BBF820B314557F0000415349BB8510B314557F000041FFE349BB58448317557F0000415349BB0821B314557F0000415349BB0010B314557F000041FFE349BBE0438317557F0000415349BB1821B314557F0000415349BB0010B314557F000041FFE3 +[1cffd9ebc29f] jit-backend-dump} +[1cffd9ebcab0] {jit-backend-addr +Loop 1 ( #13 FOR_ITER) has address 0x7f5514b32178 to 0x7f5514b32470 (bootstrap 0x7f5514b32128) +[1cffd9ebde77] jit-backend-addr} +[1cffd9ebe969] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6222 +0 4A020000 -[3304dede364] jit-backend-dump} -[3304dede8d3] {jit-backend-dump +CODE_DUMP @7f5514b32222 +0 4A020000 +[1cffd9ebfa23] jit-backend-dump} +[1cffd9ec0059] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d622e +0 63020000 -[3304dedf2ce] jit-backend-dump} -[3304dedf728] {jit-backend-dump +CODE_DUMP @7f5514b3222e +0 63020000 +[1cffd9ec0ae6] jit-backend-dump} +[1cffd9ec0f4f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d623b +0 7B020000 -[3304dedffef] jit-backend-dump} -[3304dee040e] {jit-backend-dump +CODE_DUMP @7f5514b3223b +0 7B020000 +[1cffd9ec18bc] jit-backend-dump} +[1cffd9ec1d28] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d624f +0 8C020000 -[3304dee0d4e] jit-backend-dump} -[3304dee115b] {jit-backend-dump +CODE_DUMP @7f5514b3224f +0 8C020000 +[1cffd9ec2689] jit-backend-dump} +[1cffd9ec2b07] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6269 +0 97020000 -[3304dee1a98] jit-backend-dump} -[3304dee1e9f] {jit-backend-dump +CODE_DUMP @7f5514b32269 +0 97020000 +[1cffd9ec3474] jit-backend-dump} +[1cffd9ec38bc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6272 +0 B3020000 -[3304dee2789] jit-backend-dump} -[3304dee2bb1] {jit-backend-dump +CODE_DUMP @7f5514b32272 +0 B3020000 +[1cffd9ec4220] jit-backend-dump} +[1cffd9ec4677] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6291 +0 B9020000 -[3304dee34bf] jit-backend-dump} -[3304dee38cc] {jit-backend-dump +CODE_DUMP @7f5514b32291 +0 B9020000 +[1cffd9ec5011] jit-backend-dump} +[1cffd9ec5459] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d62a2 +0 CD020000 -[3304dee41c5] jit-backend-dump} -[3304dee45e1] {jit-backend-dump +CODE_DUMP @7f5514b322a2 +0 CD020000 +[1cffd9ec5e1c] jit-backend-dump} +[1cffd9ec6279] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d632d +0 67020000 -[3304dee4ec5] jit-backend-dump} -[3304dee543c] {jit-backend-dump +CODE_DUMP @7f5514b3232d +0 67020000 +[1cffd9ec6bd7] jit-backend-dump} +[1cffd9ec77c9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d635d +0 81020000 -[3304dee5d03] jit-backend-dump} -[3304dee6139] {jit-backend-dump +CODE_DUMP @7f5514b3235d +0 81020000 +[1cffd9ec8142] jit-backend-dump} +[1cffd9ec85c0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6377 +0 8C020000 -[3304dee69fa] jit-backend-dump} -[3304dee6e10] {jit-backend-dump +CODE_DUMP @7f5514b32377 +0 8C020000 +[1cffd9ecbf8d] jit-backend-dump} +[1cffd9ecc51d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d63a2 +0 86020000 -[3304dee9db8] jit-backend-dump} -[3304deea2e6] {jit-backend-dump +CODE_DUMP @7f5514b323a2 +0 86020000 +[1cffd9eccee0] jit-backend-dump} +[1cffd9ecd33a] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d6426 +0 27020000 -[3304deeac17] jit-backend-dump} -[3304deeb092] {jit-backend-dump +CODE_DUMP @7f5514b32426 +0 27020000 +[1cffd9ecdc8f] jit-backend-dump} +[1cffd9ece160] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f476a7d644f +0 48020000 -[3304deeb97f] jit-backend-dump} -[3304deec304] jit-backend} -[3304deed1f1] {jit-log-opt-loop +CODE_DUMP @7f5514b3244f +0 48020000 +[1cffd9eceab8] jit-backend-dump} +[1cffd9ecf545] jit-backend} +[1cffd9ed0c35] {jit-log-opt-loop # Loop 1 ( #13 FOR_ITER) : loop with 82 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -275,53 +275,53 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139944753096184)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140003443320224)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+254: guard_class(p15, 25719440, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] ++244: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++254: guard_class(p15, 26177128, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17] +266: p21 = getfield_gc(p15, descr=) -+270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++270: guard_nonnull(p21, descr=) [p1, p0, p15, p21, p2, p3, p4, i5, p6, p11, p13, p17] +279: i22 = getfield_gc(p15, descr=) +283: p23 = getfield_gc(p21, descr=) -+287: guard_class(p23, 26050592, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] ++287: guard_class(p23, 26517736, descr=) [p1, p0, p15, i22, p23, p21, p2, p3, p4, i5, p6, p11, p13, p17] +299: p25 = getfield_gc(p21, descr=) +303: i26 = getfield_gc_pure(p25, descr=) +307: i27 = getfield_gc_pure(p25, descr=) +311: i28 = getfield_gc_pure(p25, descr=) +315: i30 = int_lt(i22, 0) -guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +guard_false(i30, descr=) [p1, p0, p15, i22, i28, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +325: i31 = int_ge(i22, i28) -guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +guard_false(i31, descr=) [p1, p0, p15, i22, i27, i26, p2, p3, p4, i5, p6, p11, p13, p17] +334: i32 = int_mul(i22, i27) +341: i33 = int_add(i26, i32) +347: i35 = int_add(i22, 1) +351: setfield_gc(p15, i35, descr=) -+355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] ++355: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, i33] debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_FAST') debug_merge_point(0, 0, ' #22 LIST_APPEND') +365: p37 = getfield_gc(p13, descr=) -+369: guard_class(p37, 25936304, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] ++369: guard_class(p37, 26402184, descr=) [p1, p0, p37, p13, p2, p3, p4, p6, p15, i33] +382: p39 = getfield_gc(p13, descr=) +386: i40 = getfield_gc(p39, descr=) +390: i42 = int_add(i40, 1) +394: p43 = getfield_gc(p39, descr=) +394: i44 = arraylen_gc(p43, descr=) -+394: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i42, descr=) -+506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] ++394: call(ConstClass(_ll_list_resize_ge_trampoline__v672___simple_call__function__), p39, i42, descr=) ++506: guard_no_exception(descr=) [p1, p0, i40, i33, p39, p2, p3, p4, p6, p13, p15, None] +521: p47 = getfield_gc(p39, descr=) +532: setarrayitem_gc(p47, i40, i33, descr=) debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') -+551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] -+551: i49 = getfield_raw(52008256, descr=) ++551: guard_not_invalidated(descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++551: i49 = getfield_raw(51804288, descr=) +559: i51 = int_lt(i49, 0) -guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] -+569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] +guard_false(i51, descr=) [p1, p0, p2, p3, p4, p6, p13, p15, i33] ++569: guard_value(p4, ConstPtr(ptr52), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, i33] debug_merge_point(0, 0, ' #13 FOR_ITER') -+595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++595: label(p0, p1, p2, p3, p6, i33, p13, p15, i35, i28, i27, i26, p39, descr=TargetToken(140003443320312)) debug_merge_point(0, 0, ' #13 FOR_ITER') +625: i53 = int_ge(i35, i28) -guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] +guard_false(i53, descr=) [p1, p0, p15, i35, i27, i26, p2, p3, p6, p13, i33] +638: i54 = int_mul(i35, i27) +649: i55 = int_add(i26, i54) +655: i56 = int_add(i35, 1) @@ -332,25 +332,25 @@ +663: i58 = int_add(i57, 1) +667: p59 = getfield_gc(p39, descr=) +667: i60 = arraylen_gc(p59, descr=) -+667: call(ConstClass(_ll_list_resize_ge_trampoline__v921___simple_call__function__), p39, i58, descr=) ++667: call(ConstClass(_ll_list_resize_ge_trampoline__v672___simple_call__function__), p39, i58, descr=) +744: setfield_gc(p15, i56, descr=) -+755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] ++755: guard_no_exception(descr=) [p1, p0, i57, i55, p39, p2, p3, p6, p13, p15, None] +770: p61 = getfield_gc(p39, descr=) +781: setarrayitem_gc(p61, i57, i55, descr=) debug_merge_point(0, 0, ' #25 JUMP_ABSOLUTE') -+793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] -+793: i62 = getfield_raw(52008256, descr=) ++793: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] ++793: i62 = getfield_raw(51804288, descr=) +801: i63 = int_lt(i62, 0) -guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] +guard_false(i63, descr=) [p1, p0, p2, p3, p6, p13, p15, i55, None] debug_merge_point(0, 0, ' #13 FOR_ITER') -+811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(139944753096272)) ++811: jump(p0, p1, p2, p3, p6, i55, p13, p15, i56, i28, i27, i26, p39, descr=TargetToken(140003443320312)) +840: --end of the loop-- -[3304df359fe] jit-log-opt-loop} -[3304df6aed1] {jit-backend-counts +[1cffd9f27224] jit-log-opt-loop} +[1cffd9f6f244] {jit-backend-counts entry 0:1 -TargetToken(139944714371104):1 -TargetToken(139944714371192):4 +TargetToken(140003404595232):1 +TargetToken(140003404595320):4 entry 1:1 -TargetToken(139944753096184):1 -TargetToken(139944753096272):4 -[3304df6da3a] jit-backend-counts} +TargetToken(140003443320224):1 +TargetToken(140003443320312):4 +[1cffd9f72430] jit-backend-counts} diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -14,7 +14,7 @@ ops = parse(''' [i7] i9 = int_lt(i7, 1003) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) ''').operations assert len(ops) == 3 @@ -137,7 +137,7 @@ ops = parse(""" [p6, p1] debug_merge_point(0, 0, ' #17 FOR_ITER') - guard_class(p6, 144264192, descr=) + guard_class(p6, 144264192, descr=) p12 = getfield_gc(p6, descr=) """ % locals()) res = Function.from_operations(ops.operations, LoopStorage()) @@ -146,7 +146,7 @@ def test_reassign_loops(): main = parse(''' [v0] - guard_false(v0, descr=) [] + guard_false(v0, descr=) [] ''') main.count = 10 bridge = parse(''' @@ -168,8 +168,8 @@ def test_adjust_bridges(): main = parse(''' [v0] - guard_false(v0, descr=) - guard_true(v0, descr=) + guard_false(v0, descr=) + guard_true(v0, descr=) ''') bridge = parse(''' # bridge out of Guard 0x1a @@ -198,7 +198,7 @@ [p0, p1, p2, p3, i4] debug_merge_point(0, 0, ' #15 COMPARE_OP') +166: i6 = int_lt(i4, 10000) - guard_true(i6, descr=) [p1, p0, p2, p3, i4] + guard_true(i6, descr=) [p1, p0, p2, p3, i4] debug_merge_point(0, 0, ' #27 INPLACE_ADD') +179: i8 = int_add(i4, 1) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') @@ -206,7 +206,7 @@ +191: i12 = int_sub(i10, 1) +195: setfield_raw(40564608, i12, descr=) +203: i14 = int_lt(i12, 0) - guard_false(i14, descr=) [p1, p0, p2, p3, i8, None] + guard_false(i14, descr=) [p1, p0, p2, p3, i8, None] debug_merge_point(0, ' #9 LOAD_FAST') +213: jump(p0, p1, p2, p3, i8, descr=) +218: --end of the loop--""", backend_dump=backend_dump, @@ -228,7 +228,7 @@ +88: label(i0, i1, p2, descr=TargetToken(1081858608)) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +116: i3 = int_lt(i0, i1) -guard_true(i3, descr=) [i1, i0, p2] +guard_true(i3, descr=) [i1, i0, p2] +124: p4 = getfield_gc(p2, descr=) +128: i5 = strgetitem(p4, i0) +136: i7 = int_eq(40, i5) @@ -241,13 +241,13 @@ +204: i18 = int_is_true(i17) +216: i19 = int_or(i10, i18) +220: i20 = int_is_true(i19) -guard_false(i20, descr=) [i1, i0, p2] +guard_false(i20, descr=) [i1, i0, p2] +228: i22 = int_add(i0, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +232: label(i22, i1, p2, p4, descr=TargetToken(1081858656)) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +264: i23 = int_lt(i22, i1) -guard_true(i23, descr=) [i1, i22, p2] +guard_true(i23, descr=) [i1, i22, p2] +272: i24 = strgetitem(p4, i22) +280: i25 = int_eq(40, i24) +296: i26 = int_eq(41, i24) @@ -259,7 +259,7 @@ +348: i32 = int_is_true(i31) +360: i33 = int_or(i27, i32) +364: i34 = int_is_true(i33) -guard_false(i34, descr=) [i1, i22, p2] +guard_false(i34, descr=) [i1, i22, p2] +372: i35 = int_add(i22, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +376: jump(i35, i1, p2, p4, descr=TargetToken(1081858656)) @@ -300,11 +300,11 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) - guard_true(i19, descr=) [] + guard_true(i19, descr=) [] i113 = getfield_raw(151937600, descr=) ''') loop.comment = 'Loop 0' @@ -321,11 +321,11 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) - guard_true(i19, descr=) [] + guard_true(i19, descr=) [] i113 = getfield_raw(151937600, descr=) ''') bridge = parse(''' diff --git a/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt b/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/CompositionExclusions-6.0.0.txt @@ -0,0 +1,206 @@ +# CompositionExclusions-6.0.0.txt +# Date: 2010-06-25, 14:34:00 PDT [KW] +# +# This file lists the characters for the Composition Exclusion Table +# defined in UAX #15, Unicode Normalization Forms. +# +# This file is a normative contributory data file in the +# Unicode Character Database. +# +# Copyright (c) 1991-2010 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# For more information, see +# http://www.unicode.org/unicode/reports/tr15/#Primary_Exclusion_List_Table +# +# For a full derivation of composition exclusions, see the derived property +# Full_Composition_Exclusion in DerivedNormalizationProps.txt +# + +# ================================================ +# (1) Script Specifics +# +# This list of characters cannot be derived from the UnicodeData.txt file. +# ================================================ + +0958 # DEVANAGARI LETTER QA +0959 # DEVANAGARI LETTER KHHA +095A # DEVANAGARI LETTER GHHA +095B # DEVANAGARI LETTER ZA +095C # DEVANAGARI LETTER DDDHA +095D # DEVANAGARI LETTER RHA +095E # DEVANAGARI LETTER FA +095F # DEVANAGARI LETTER YYA +09DC # BENGALI LETTER RRA +09DD # BENGALI LETTER RHA +09DF # BENGALI LETTER YYA +0A33 # GURMUKHI LETTER LLA +0A36 # GURMUKHI LETTER SHA +0A59 # GURMUKHI LETTER KHHA +0A5A # GURMUKHI LETTER GHHA +0A5B # GURMUKHI LETTER ZA +0A5E # GURMUKHI LETTER FA +0B5C # ORIYA LETTER RRA +0B5D # ORIYA LETTER RHA +0F43 # TIBETAN LETTER GHA +0F4D # TIBETAN LETTER DDHA +0F52 # TIBETAN LETTER DHA +0F57 # TIBETAN LETTER BHA +0F5C # TIBETAN LETTER DZHA +0F69 # TIBETAN LETTER KSSA +0F76 # TIBETAN VOWEL SIGN VOCALIC R +0F78 # TIBETAN VOWEL SIGN VOCALIC L +0F93 # TIBETAN SUBJOINED LETTER GHA +0F9D # TIBETAN SUBJOINED LETTER DDHA +0FA2 # TIBETAN SUBJOINED LETTER DHA +0FA7 # TIBETAN SUBJOINED LETTER BHA +0FAC # TIBETAN SUBJOINED LETTER DZHA +0FB9 # TIBETAN SUBJOINED LETTER KSSA +FB1D # HEBREW LETTER YOD WITH HIRIQ +FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH +FB2A # HEBREW LETTER SHIN WITH SHIN DOT +FB2B # HEBREW LETTER SHIN WITH SIN DOT +FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT +FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT +FB2E # HEBREW LETTER ALEF WITH PATAH +FB2F # HEBREW LETTER ALEF WITH QAMATS +FB30 # HEBREW LETTER ALEF WITH MAPIQ +FB31 # HEBREW LETTER BET WITH DAGESH +FB32 # HEBREW LETTER GIMEL WITH DAGESH +FB33 # HEBREW LETTER DALET WITH DAGESH +FB34 # HEBREW LETTER HE WITH MAPIQ +FB35 # HEBREW LETTER VAV WITH DAGESH +FB36 # HEBREW LETTER ZAYIN WITH DAGESH +FB38 # HEBREW LETTER TET WITH DAGESH +FB39 # HEBREW LETTER YOD WITH DAGESH +FB3A # HEBREW LETTER FINAL KAF WITH DAGESH +FB3B # HEBREW LETTER KAF WITH DAGESH +FB3C # HEBREW LETTER LAMED WITH DAGESH +FB3E # HEBREW LETTER MEM WITH DAGESH +FB40 # HEBREW LETTER NUN WITH DAGESH +FB41 # HEBREW LETTER SAMEKH WITH DAGESH +FB43 # HEBREW LETTER FINAL PE WITH DAGESH +FB44 # HEBREW LETTER PE WITH DAGESH +FB46 # HEBREW LETTER TSADI WITH DAGESH +FB47 # HEBREW LETTER QOF WITH DAGESH +FB48 # HEBREW LETTER RESH WITH DAGESH +FB49 # HEBREW LETTER SHIN WITH DAGESH +FB4A # HEBREW LETTER TAV WITH DAGESH +FB4B # HEBREW LETTER VAV WITH HOLAM +FB4C # HEBREW LETTER BET WITH RAFE +FB4D # HEBREW LETTER KAF WITH RAFE +FB4E # HEBREW LETTER PE WITH RAFE + +# Total code points: 67 + +# ================================================ +# (2) Post Composition Version precomposed characters +# +# These characters cannot be derived solely from the UnicodeData.txt file +# in this version of Unicode. +# +# Note that characters added to the standard after the +# Composition Version and which have canonical decomposition mappings +# are not automatically added to this list of Post Composition +# Version precomposed characters. +# ================================================ + +2ADC # FORKING +1D15E # MUSICAL SYMBOL HALF NOTE +1D15F # MUSICAL SYMBOL QUARTER NOTE +1D160 # MUSICAL SYMBOL EIGHTH NOTE +1D161 # MUSICAL SYMBOL SIXTEENTH NOTE +1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE +1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE +1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D1BB # MUSICAL SYMBOL MINIMA +1D1BC # MUSICAL SYMBOL MINIMA BLACK +1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE +1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK +1D1BF # MUSICAL SYMBOL FUSA WHITE +1D1C0 # MUSICAL SYMBOL FUSA BLACK + +# Total code points: 14 + +# ================================================ +# (3) Singleton Decompositions +# +# These characters can be derived from the UnicodeData.txt file +# by including all canonically decomposable characters whose +# canonical decomposition consists of a single character. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK +# 0343 COMBINING GREEK KORONIS +# 0374 GREEK NUMERAL SIGN +# 037E GREEK QUESTION MARK +# 0387 GREEK ANO TELEIA +# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA +# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA +# 1F75 GREEK SMALL LETTER ETA WITH OXIA +# 1F77 GREEK SMALL LETTER IOTA WITH OXIA +# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA +# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA +# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA +# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA +# 1FBE GREEK PROSGEGRAMMENI +# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA +# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA +# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA +# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA +# 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA +# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA +# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA +# 1FFD GREEK OXIA +# 2000..2001 [2] EN QUAD..EM QUAD +# 2126 OHM SIGN +# 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN +# 2329 LEFT-POINTING ANGLE BRACKET +# 232A RIGHT-POINTING ANGLE BRACKET +# F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D +# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10 +# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12 +# FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E +# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20 +# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22 +# FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26 +# FA2A..FA2D [4] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA2D +# FA30..FA6D [62] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6D +# FA70..FAD9 [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +# 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 1033 + +# ================================================ +# (4) Non-Starter Decompositions +# +# These characters can be derived from the UnicodeData file +# by including each expanding canonical decomposition +# (i.e., those which canonically decompose to a sequence +# of characters instead of a single character), such that: +# +# A. The character is not a Starter. +# +# OR (inclusive) +# +# B. The character's canonical decomposition begins +# with a character that is not a Starter. +# +# Note that a "Starter" is any character with a zero combining class. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0344 COMBINING GREEK DIALYTIKA TONOS +# 0F73 TIBETAN VOWEL SIGN II +# 0F75 TIBETAN VOWEL SIGN UU +# 0F81 TIBETAN VOWEL SIGN REVERSED II + +# Total code points: 4 + diff --git a/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt b/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/DerivedCoreProperties-6.0.0.txt @@ -0,0 +1,9482 @@ +# DerivedCoreProperties-6.0.0.txt +# Date: 2010-08-19, 00:48:05 GMT [MD] +# +# Unicode Character Database +# Copyright (c) 1991-2010 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# For documentation, see http://www.unicode.org/reports/tr44/ + +# ================================================ + +# Derived Property: Math +# Generated from: Sm + Other_Math + +002B ; Math # Sm PLUS SIGN +003C..003E ; Math # Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN +005E ; Math # Sk CIRCUMFLEX ACCENT +007C ; Math # Sm VERTICAL LINE +007E ; Math # Sm TILDE +00AC ; Math # Sm NOT SIGN +00B1 ; Math # Sm PLUS-MINUS SIGN +00D7 ; Math # Sm MULTIPLICATION SIGN +00F7 ; Math # Sm DIVISION SIGN +03D0..03D2 ; Math # L& [3] GREEK BETA SYMBOL..GREEK UPSILON WITH HOOK SYMBOL +03D5 ; Math # L& GREEK PHI SYMBOL +03F0..03F1 ; Math # L& [2] GREEK KAPPA SYMBOL..GREEK RHO SYMBOL +03F4..03F5 ; Math # L& [2] GREEK CAPITAL THETA SYMBOL..GREEK LUNATE EPSILON SYMBOL +03F6 ; Math # Sm GREEK REVERSED LUNATE EPSILON SYMBOL +0606..0608 ; Math # Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY +2016 ; Math # Po DOUBLE VERTICAL LINE +2032..2034 ; Math # Po [3] PRIME..TRIPLE PRIME +2040 ; Math # Pc CHARACTER TIE +2044 ; Math # Sm FRACTION SLASH +2052 ; Math # Sm COMMERCIAL MINUS SIGN +2061..2064 ; Math # Cf [4] FUNCTION APPLICATION..INVISIBLE PLUS +207A..207C ; Math # Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN +207D ; Math # Ps SUPERSCRIPT LEFT PARENTHESIS +207E ; Math # Pe SUPERSCRIPT RIGHT PARENTHESIS +208A..208C ; Math # Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN +208D ; Math # Ps SUBSCRIPT LEFT PARENTHESIS +208E ; Math # Pe SUBSCRIPT RIGHT PARENTHESIS +20D0..20DC ; Math # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE +20E1 ; Math # Mn COMBINING LEFT RIGHT ARROW ABOVE +20E5..20E6 ; Math # Mn [2] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING DOUBLE VERTICAL STROKE OVERLAY +20EB..20EF ; Math # Mn [5] COMBINING LONG DOUBLE SOLIDUS OVERLAY..COMBINING RIGHT ARROW BELOW +2102 ; Math # L& DOUBLE-STRUCK CAPITAL C +2107 ; Math # L& EULER CONSTANT +210A..2113 ; Math # L& [10] SCRIPT SMALL G..SCRIPT SMALL L +2115 ; Math # L& DOUBLE-STRUCK CAPITAL N +2118 ; Math # Sm SCRIPT CAPITAL P +2119..211D ; Math # L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +2124 ; Math # L& DOUBLE-STRUCK CAPITAL Z +2128 ; Math # L& BLACK-LETTER CAPITAL Z +2129 ; Math # So TURNED GREEK SMALL LETTER IOTA +212C..212D ; Math # L& [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C +212F..2131 ; Math # L& [3] SCRIPT SMALL E..SCRIPT CAPITAL F +2133..2134 ; Math # L& [2] SCRIPT CAPITAL M..SCRIPT SMALL O +2135..2138 ; Math # Lo [4] ALEF SYMBOL..DALET SYMBOL +213C..213F ; Math # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI +2140..2144 ; Math # Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y +2145..2149 ; Math # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J +214B ; Math # Sm TURNED AMPERSAND +2190..2194 ; Math # Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW +2195..2199 ; Math # So [5] UP DOWN ARROW..SOUTH WEST ARROW +219A..219B ; Math # Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE +219C..219F ; Math # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW +21A0 ; Math # Sm RIGHTWARDS TWO HEADED ARROW +21A1..21A2 ; Math # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL +21A3 ; Math # Sm RIGHTWARDS ARROW WITH TAIL +21A4..21A5 ; Math # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR +21A6 ; Math # Sm RIGHTWARDS ARROW FROM BAR +21A7 ; Math # So DOWNWARDS ARROW FROM BAR +21A9..21AD ; Math # So [5] LEFTWARDS ARROW WITH HOOK..LEFT RIGHT WAVE ARROW +21AE ; Math # Sm LEFT RIGHT ARROW WITH STROKE +21B0..21B1 ; Math # So [2] UPWARDS ARROW WITH TIP LEFTWARDS..UPWARDS ARROW WITH TIP RIGHTWARDS +21B6..21B7 ; Math # So [2] ANTICLOCKWISE TOP SEMICIRCLE ARROW..CLOCKWISE TOP SEMICIRCLE ARROW +21BC..21CD ; Math # So [18] LEFTWARDS HARPOON WITH BARB UPWARDS..LEFTWARDS DOUBLE ARROW WITH STROKE +21CE..21CF ; Math # Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE +21D0..21D1 ; Math # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW +21D2 ; Math # Sm RIGHTWARDS DOUBLE ARROW +21D3 ; Math # So DOWNWARDS DOUBLE ARROW +21D4 ; Math # Sm LEFT RIGHT DOUBLE ARROW +21D5..21DB ; Math # So [7] UP DOWN DOUBLE ARROW..RIGHTWARDS TRIPLE ARROW +21DD ; Math # So RIGHTWARDS SQUIGGLE ARROW +21E4..21E5 ; Math # So [2] LEFTWARDS ARROW TO BAR..RIGHTWARDS ARROW TO BAR +21F4..22FF ; Math # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP +2308..230B ; Math # Sm [4] LEFT CEILING..RIGHT FLOOR +2320..2321 ; Math # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL +237C ; Math # Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +239B..23B3 ; Math # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM +23B4..23B5 ; Math # So [2] TOP SQUARE BRACKET..BOTTOM SQUARE BRACKET +23B7 ; Math # So RADICAL SYMBOL BOTTOM +23D0 ; Math # So VERTICAL LINE EXTENSION +23DC..23E1 ; Math # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET +23E2 ; Math # So WHITE TRAPEZIUM +25A0..25A1 ; Math # So [2] BLACK SQUARE..WHITE SQUARE +25AE..25B6 ; Math # So [9] BLACK VERTICAL RECTANGLE..BLACK RIGHT-POINTING TRIANGLE +25B7 ; Math # Sm WHITE RIGHT-POINTING TRIANGLE +25BC..25C0 ; Math # So [5] BLACK DOWN-POINTING TRIANGLE..BLACK LEFT-POINTING TRIANGLE +25C1 ; Math # Sm WHITE LEFT-POINTING TRIANGLE +25C6..25C7 ; Math # So [2] BLACK DIAMOND..WHITE DIAMOND +25CA..25CB ; Math # So [2] LOZENGE..WHITE CIRCLE +25CF..25D3 ; Math # So [5] BLACK CIRCLE..CIRCLE WITH UPPER HALF BLACK +25E2 ; Math # So BLACK LOWER RIGHT TRIANGLE +25E4 ; Math # So BLACK UPPER LEFT TRIANGLE +25E7..25EC ; Math # So [6] SQUARE WITH LEFT HALF BLACK..WHITE UP-POINTING TRIANGLE WITH DOT +25F8..25FF ; Math # Sm [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE +2605..2606 ; Math # So [2] BLACK STAR..WHITE STAR +2640 ; Math # So FEMALE SIGN +2642 ; Math # So MALE SIGN +2660..2663 ; Math # So [4] BLACK SPADE SUIT..BLACK CLUB SUIT +266D..266E ; Math # So [2] MUSIC FLAT SIGN..MUSIC NATURAL SIGN +266F ; Math # Sm MUSIC SHARP SIGN +27C0..27C4 ; Math # Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET +27C5 ; Math # Ps LEFT S-SHAPED BAG DELIMITER +27C6 ; Math # Pe RIGHT S-SHAPED BAG DELIMITER +27C7..27CA ; Math # Sm [4] OR WITH DOT INSIDE..VERTICAL BAR WITH HORIZONTAL STROKE +27CC ; Math # Sm LONG DIVISION +27CE..27E5 ; Math # Sm [24] SQUARED LOGICAL AND..WHITE SQUARE WITH RIGHTWARDS TICK +27E6 ; Math # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E7 ; Math # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E8 ; Math # Ps MATHEMATICAL LEFT ANGLE BRACKET +27E9 ; Math # Pe MATHEMATICAL RIGHT ANGLE BRACKET +27EA ; Math # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EB ; Math # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27EC ; Math # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27ED ; Math # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EE ; Math # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS +27EF ; Math # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS +27F0..27FF ; Math # Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW +2900..2982 ; Math # Sm [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON +2983 ; Math # Ps LEFT WHITE CURLY BRACKET +2984 ; Math # Pe RIGHT WHITE CURLY BRACKET +2985 ; Math # Ps LEFT WHITE PARENTHESIS +2986 ; Math # Pe RIGHT WHITE PARENTHESIS +2987 ; Math # Ps Z NOTATION LEFT IMAGE BRACKET +2988 ; Math # Pe Z NOTATION RIGHT IMAGE BRACKET +2989 ; Math # Ps Z NOTATION LEFT BINDING BRACKET +298A ; Math # Pe Z NOTATION RIGHT BINDING BRACKET +298B ; Math # Ps LEFT SQUARE BRACKET WITH UNDERBAR +298C ; Math # Pe RIGHT SQUARE BRACKET WITH UNDERBAR +298D ; Math # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298E ; Math # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +298F ; Math # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990 ; Math # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2991 ; Math # Ps LEFT ANGLE BRACKET WITH DOT +2992 ; Math # Pe RIGHT ANGLE BRACKET WITH DOT +2993 ; Math # Ps LEFT ARC LESS-THAN BRACKET +2994 ; Math # Pe RIGHT ARC GREATER-THAN BRACKET +2995 ; Math # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET +2996 ; Math # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET +2997 ; Math # Ps LEFT BLACK TORTOISE SHELL BRACKET +2998 ; Math # Pe RIGHT BLACK TORTOISE SHELL BRACKET +2999..29D7 ; Math # Sm [63] DOTTED FENCE..BLACK HOURGLASS +29D8 ; Math # Ps LEFT WIGGLY FENCE +29D9 ; Math # Pe RIGHT WIGGLY FENCE +29DA ; Math # Ps LEFT DOUBLE WIGGLY FENCE +29DB ; Math # Pe RIGHT DOUBLE WIGGLY FENCE +29DC..29FB ; Math # Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS +29FC ; Math # Ps LEFT-POINTING CURVED ANGLE BRACKET +29FD ; Math # Pe RIGHT-POINTING CURVED ANGLE BRACKET +29FE..2AFF ; Math # Sm [258] TINY..N-ARY WHITE VERTICAL BAR +2B30..2B44 ; Math # Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET +2B47..2B4C ; Math # Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +FB29 ; Math # Sm HEBREW LETTER ALTERNATIVE PLUS SIGN +FE61 ; Math # Po SMALL ASTERISK +FE62 ; Math # Sm SMALL PLUS SIGN +FE63 ; Math # Pd SMALL HYPHEN-MINUS +FE64..FE66 ; Math # Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN +FE68 ; Math # Po SMALL REVERSE SOLIDUS +FF0B ; Math # Sm FULLWIDTH PLUS SIGN +FF1C..FF1E ; Math # Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN +FF3C ; Math # Po FULLWIDTH REVERSE SOLIDUS +FF3E ; Math # Sk FULLWIDTH CIRCUMFLEX ACCENT +FF5C ; Math # Sm FULLWIDTH VERTICAL LINE +FF5E ; Math # Sm FULLWIDTH TILDE +FFE2 ; Math # Sm FULLWIDTH NOT SIGN +FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW +1D400..1D454 ; Math # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G +1D456..1D49C ; Math # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2 ; Math # L& MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6 ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC ; Math # L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B9 ; Math # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Math # L& MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Math # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D505 ; Math # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A ; Math # L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514 ; Math # L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C ; Math # L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D51E..1D539 ; Math # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E ; Math # L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544 ; Math # L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 ; Math # L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550 ; Math # L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552..1D6A5 ; Math # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6A8..1D6C0 ; Math # L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6C1 ; Math # Sm MATHEMATICAL BOLD NABLA +1D6C2..1D6DA ; Math # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DB ; Math # Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6DC..1D6FA ; Math # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FB ; Math # Sm MATHEMATICAL ITALIC NABLA +1D6FC..1D714 ; Math # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D715 ; Math # Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D716..1D734 ; Math # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D735 ; Math # Sm MATHEMATICAL BOLD ITALIC NABLA +1D736..1D74E ; Math # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D74F ; Math # Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D750..1D76E ; Math # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D76F ; Math # Sm MATHEMATICAL SANS-SERIF BOLD NABLA +1D770..1D788 ; Math # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D789 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D78A..1D7A8 ; Math # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7A9 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7AA..1D7C2 ; Math # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C3 ; Math # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1D7C4..1D7CB ; Math # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1D7CE..1D7FF ; Math # Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + +# Total code points: 2165 + +# ================================================ + +# Derived Property: Alphabetic +# Generated from: Lu+Ll+Lt+Lm+Lo+Nl + Other_Alphabetic + +0041..005A ; Alphabetic # L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +0061..007A ; Alphabetic # L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00AA ; Alphabetic # L& FEMININE ORDINAL INDICATOR +00B5 ; Alphabetic # L& MICRO SIGN +00BA ; Alphabetic # L& MASCULINE ORDINAL INDICATOR +00C0..00D6 ; Alphabetic # L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS +00D8..00F6 ; Alphabetic # L& [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS +00F8..01BA ; Alphabetic # L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL +01BB ; Alphabetic # Lo LATIN LETTER TWO WITH STROKE +01BC..01BF ; Alphabetic # L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN +01C0..01C3 ; Alphabetic # Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK +01C4..0293 ; Alphabetic # L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL +0294 ; Alphabetic # Lo LATIN LETTER GLOTTAL STOP +0295..02AF ; Alphabetic # L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +02B0..02C1 ; Alphabetic # Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP +02C6..02D1 ; Alphabetic # Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON +02E0..02E4 ; Alphabetic # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +02EC ; Alphabetic # Lm MODIFIER LETTER VOICING +02EE ; Alphabetic # Lm MODIFIER LETTER DOUBLE APOSTROPHE +0345 ; Alphabetic # Mn COMBINING GREEK YPOGEGRAMMENI +0370..0373 ; Alphabetic # L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI +0374 ; Alphabetic # Lm GREEK NUMERAL SIGN +0376..0377 ; Alphabetic # L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037A ; Alphabetic # Lm GREEK YPOGEGRAMMENI +037B..037D ; Alphabetic # L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +0386 ; Alphabetic # L& GREEK CAPITAL LETTER ALPHA WITH TONOS +0388..038A ; Alphabetic # L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS +038C ; Alphabetic # L& GREEK CAPITAL LETTER OMICRON WITH TONOS +038E..03A1 ; Alphabetic # L& [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO +03A3..03F5 ; Alphabetic # L& [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL +03F7..0481 ; Alphabetic # L& [139] GREEK CAPITAL LETTER SHO..CYRILLIC SMALL LETTER KOPPA +048A..0527 ; Alphabetic # L& [158] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER SHHA WITH DESCENDER +0531..0556 ; Alphabetic # L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH +0559 ; Alphabetic # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING +0561..0587 ; Alphabetic # L& [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN +05B0..05BD ; Alphabetic # Mn [14] HEBREW POINT SHEVA..HEBREW POINT METEG +05BF ; Alphabetic # Mn HEBREW POINT RAFE +05C1..05C2 ; Alphabetic # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C4..05C5 ; Alphabetic # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT +05C7 ; Alphabetic # Mn HEBREW POINT QAMATS QATAN +05D0..05EA ; Alphabetic # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV +05F0..05F2 ; Alphabetic # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD +0610..061A ; Alphabetic # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA +0620..063F ; Alphabetic # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE +0640 ; Alphabetic # Lm ARABIC TATWEEL +0641..064A ; Alphabetic # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH +064B..0657 ; Alphabetic # Mn [13] ARABIC FATHATAN..ARABIC INVERTED DAMMA +0659..065F ; Alphabetic # Mn [7] ARABIC ZWARAKAY..ARABIC WAVY HAMZA BELOW +066E..066F ; Alphabetic # Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF +0670 ; Alphabetic # Mn ARABIC LETTER SUPERSCRIPT ALEF +0671..06D3 ; Alphabetic # Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +06D5 ; Alphabetic # Lo ARABIC LETTER AE +06D6..06DC ; Alphabetic # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN +06E1..06E4 ; Alphabetic # Mn [4] ARABIC SMALL HIGH DOTLESS HEAD OF KHAH..ARABIC SMALL HIGH MADDA +06E5..06E6 ; Alphabetic # Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH +06E7..06E8 ; Alphabetic # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +06ED ; Alphabetic # Mn ARABIC SMALL LOW MEEM +06EE..06EF ; Alphabetic # Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V +06FA..06FC ; Alphabetic # Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW +06FF ; Alphabetic # Lo ARABIC LETTER HEH WITH INVERTED V +0710 ; Alphabetic # Lo SYRIAC LETTER ALAPH +0711 ; Alphabetic # Mn SYRIAC LETTER SUPERSCRIPT ALAPH +0712..072F ; Alphabetic # Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH +0730..073F ; Alphabetic # Mn [16] SYRIAC PTHAHA ABOVE..SYRIAC RWAHA +074D..07A5 ; Alphabetic # Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU +07A6..07B0 ; Alphabetic # Mn [11] THAANA ABAFILI..THAANA SUKUN +07B1 ; Alphabetic # Lo THAANA LETTER NAA +07CA..07EA ; Alphabetic # Lo [33] NKO LETTER A..NKO LETTER JONA RA +07F4..07F5 ; Alphabetic # Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE +07FA ; Alphabetic # Lm NKO LAJANYALAN +0800..0815 ; Alphabetic # Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF +0816..0817 ; Alphabetic # Mn [2] SAMARITAN MARK IN..SAMARITAN MARK IN-ALAF +081A ; Alphabetic # Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT +081B..0823 ; Alphabetic # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A +0824 ; Alphabetic # Lm SAMARITAN MODIFIER LETTER SHORT A +0825..0827 ; Alphabetic # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U +0828 ; Alphabetic # Lm SAMARITAN MODIFIER LETTER I +0829..082C ; Alphabetic # Mn [4] SAMARITAN VOWEL SIGN LONG I..SAMARITAN VOWEL SIGN SUKUN +0840..0858 ; Alphabetic # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN +0900..0902 ; Alphabetic # Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA +0903 ; Alphabetic # Mc DEVANAGARI SIGN VISARGA +0904..0939 ; Alphabetic # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA +093A ; Alphabetic # Mn DEVANAGARI VOWEL SIGN OE +093B ; Alphabetic # Mc DEVANAGARI VOWEL SIGN OOE +093D ; Alphabetic # Lo DEVANAGARI SIGN AVAGRAHA +093E..0940 ; Alphabetic # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II +0941..0948 ; Alphabetic # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI +0949..094C ; Alphabetic # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU +094E..094F ; Alphabetic # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW +0950 ; Alphabetic # Lo DEVANAGARI OM +0955..0957 ; Alphabetic # Mn [3] DEVANAGARI VOWEL SIGN CANDRA LONG E..DEVANAGARI VOWEL SIGN UUE +0958..0961 ; Alphabetic # Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL +0962..0963 ; Alphabetic # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0971 ; Alphabetic # Lm DEVANAGARI SIGN HIGH SPACING DOT +0972..0977 ; Alphabetic # Lo [6] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER UUE +0979..097F ; Alphabetic # Lo [7] DEVANAGARI LETTER ZHA..DEVANAGARI LETTER BBA +0981 ; Alphabetic # Mn BENGALI SIGN CANDRABINDU +0982..0983 ; Alphabetic # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA +0985..098C ; Alphabetic # Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L +098F..0990 ; Alphabetic # Lo [2] BENGALI LETTER E..BENGALI LETTER AI +0993..09A8 ; Alphabetic # Lo [22] BENGALI LETTER O..BENGALI LETTER NA +09AA..09B0 ; Alphabetic # Lo [7] BENGALI LETTER PA..BENGALI LETTER RA +09B2 ; Alphabetic # Lo BENGALI LETTER LA +09B6..09B9 ; Alphabetic # Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA +09BD ; Alphabetic # Lo BENGALI SIGN AVAGRAHA +09BE..09C0 ; Alphabetic # Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II +09C1..09C4 ; Alphabetic # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR +09C7..09C8 ; Alphabetic # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CC ; Alphabetic # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU +09CE ; Alphabetic # Lo BENGALI LETTER KHANDA TA +09D7 ; Alphabetic # Mc BENGALI AU LENGTH MARK +09DC..09DD ; Alphabetic # Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA +09DF..09E1 ; Alphabetic # Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL +09E2..09E3 ; Alphabetic # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL +09F0..09F1 ; Alphabetic # Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL +0A01..0A02 ; Alphabetic # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI +0A03 ; Alphabetic # Mc GURMUKHI SIGN VISARGA +0A05..0A0A ; Alphabetic # Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU +0A0F..0A10 ; Alphabetic # Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI +0A13..0A28 ; Alphabetic # Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA +0A2A..0A30 ; Alphabetic # Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA +0A32..0A33 ; Alphabetic # Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA +0A35..0A36 ; Alphabetic # Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA +0A38..0A39 ; Alphabetic # Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA +0A3E..0A40 ; Alphabetic # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II +0A41..0A42 ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4C ; Alphabetic # Mn [2] GURMUKHI VOWEL SIGN OO..GURMUKHI VOWEL SIGN AU +0A51 ; Alphabetic # Mn GURMUKHI SIGN UDAAT +0A59..0A5C ; Alphabetic # Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA +0A5E ; Alphabetic # Lo GURMUKHI LETTER FA +0A70..0A71 ; Alphabetic # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK +0A72..0A74 ; Alphabetic # Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR +0A75 ; Alphabetic # Mn GURMUKHI SIGN YAKASH +0A81..0A82 ; Alphabetic # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA +0A83 ; Alphabetic # Mc GUJARATI SIGN VISARGA +0A85..0A8D ; Alphabetic # Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E +0A8F..0A91 ; Alphabetic # Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O +0A93..0AA8 ; Alphabetic # Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA +0AAA..0AB0 ; Alphabetic # Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA +0AB2..0AB3 ; Alphabetic # Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA +0AB5..0AB9 ; Alphabetic # Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA +0ABD ; Alphabetic # Lo GUJARATI SIGN AVAGRAHA +0ABE..0AC0 ; Alphabetic # Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II +0AC1..0AC5 ; Alphabetic # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC8 ; Alphabetic # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI +0AC9 ; Alphabetic # Mc GUJARATI VOWEL SIGN CANDRA O +0ACB..0ACC ; Alphabetic # Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU +0AD0 ; Alphabetic # Lo GUJARATI OM +0AE0..0AE1 ; Alphabetic # Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL +0AE2..0AE3 ; Alphabetic # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL +0B01 ; Alphabetic # Mn ORIYA SIGN CANDRABINDU +0B02..0B03 ; Alphabetic # Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA +0B05..0B0C ; Alphabetic # Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L +0B0F..0B10 ; Alphabetic # Lo [2] ORIYA LETTER E..ORIYA LETTER AI +0B13..0B28 ; Alphabetic # Lo [22] ORIYA LETTER O..ORIYA LETTER NA +0B2A..0B30 ; Alphabetic # Lo [7] ORIYA LETTER PA..ORIYA LETTER RA +0B32..0B33 ; Alphabetic # Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA +0B35..0B39 ; Alphabetic # Lo [5] ORIYA LETTER VA..ORIYA LETTER HA +0B3D ; Alphabetic # Lo ORIYA SIGN AVAGRAHA +0B3E ; Alphabetic # Mc ORIYA VOWEL SIGN AA +0B3F ; Alphabetic # Mn ORIYA VOWEL SIGN I +0B40 ; Alphabetic # Mc ORIYA VOWEL SIGN II +0B41..0B44 ; Alphabetic # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR +0B47..0B48 ; Alphabetic # Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI +0B4B..0B4C ; Alphabetic # Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU +0B56 ; Alphabetic # Mn ORIYA AI LENGTH MARK +0B57 ; Alphabetic # Mc ORIYA AU LENGTH MARK +0B5C..0B5D ; Alphabetic # Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA +0B5F..0B61 ; Alphabetic # Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL +0B62..0B63 ; Alphabetic # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL +0B71 ; Alphabetic # Lo ORIYA LETTER WA +0B82 ; Alphabetic # Mn TAMIL SIGN ANUSVARA +0B83 ; Alphabetic # Lo TAMIL SIGN VISARGA +0B85..0B8A ; Alphabetic # Lo [6] TAMIL LETTER A..TAMIL LETTER UU +0B8E..0B90 ; Alphabetic # Lo [3] TAMIL LETTER E..TAMIL LETTER AI +0B92..0B95 ; Alphabetic # Lo [4] TAMIL LETTER O..TAMIL LETTER KA +0B99..0B9A ; Alphabetic # Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA +0B9C ; Alphabetic # Lo TAMIL LETTER JA +0B9E..0B9F ; Alphabetic # Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA +0BA3..0BA4 ; Alphabetic # Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA +0BA8..0BAA ; Alphabetic # Lo [3] TAMIL LETTER NA..TAMIL LETTER PA +0BAE..0BB9 ; Alphabetic # Lo [12] TAMIL LETTER MA..TAMIL LETTER HA +0BBE..0BBF ; Alphabetic # Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I +0BC0 ; Alphabetic # Mn TAMIL VOWEL SIGN II +0BC1..0BC2 ; Alphabetic # Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU +0BC6..0BC8 ; Alphabetic # Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI +0BCA..0BCC ; Alphabetic # Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU +0BD0 ; Alphabetic # Lo TAMIL OM +0BD7 ; Alphabetic # Mc TAMIL AU LENGTH MARK +0C01..0C03 ; Alphabetic # Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA +0C05..0C0C ; Alphabetic # Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L +0C0E..0C10 ; Alphabetic # Lo [3] TELUGU LETTER E..TELUGU LETTER AI +0C12..0C28 ; Alphabetic # Lo [23] TELUGU LETTER O..TELUGU LETTER NA +0C2A..0C33 ; Alphabetic # Lo [10] TELUGU LETTER PA..TELUGU LETTER LLA +0C35..0C39 ; Alphabetic # Lo [5] TELUGU LETTER VA..TELUGU LETTER HA +0C3D ; Alphabetic # Lo TELUGU SIGN AVAGRAHA +0C3E..0C40 ; Alphabetic # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II +0C41..0C44 ; Alphabetic # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR +0C46..0C48 ; Alphabetic # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4C ; Alphabetic # Mn [3] TELUGU VOWEL SIGN O..TELUGU VOWEL SIGN AU +0C55..0C56 ; Alphabetic # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C58..0C59 ; Alphabetic # Lo [2] TELUGU LETTER TSA..TELUGU LETTER DZA +0C60..0C61 ; Alphabetic # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL +0C62..0C63 ; Alphabetic # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL +0C82..0C83 ; Alphabetic # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA +0C85..0C8C ; Alphabetic # Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L +0C8E..0C90 ; Alphabetic # Lo [3] KANNADA LETTER E..KANNADA LETTER AI +0C92..0CA8 ; Alphabetic # Lo [23] KANNADA LETTER O..KANNADA LETTER NA +0CAA..0CB3 ; Alphabetic # Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA +0CB5..0CB9 ; Alphabetic # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA +0CBD ; Alphabetic # Lo KANNADA SIGN AVAGRAHA +0CBE ; Alphabetic # Mc KANNADA VOWEL SIGN AA +0CBF ; Alphabetic # Mn KANNADA VOWEL SIGN I +0CC0..0CC4 ; Alphabetic # Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR +0CC6 ; Alphabetic # Mn KANNADA VOWEL SIGN E +0CC7..0CC8 ; Alphabetic # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; Alphabetic # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO +0CCC ; Alphabetic # Mn KANNADA VOWEL SIGN AU +0CD5..0CD6 ; Alphabetic # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0CDE ; Alphabetic # Lo KANNADA LETTER FA +0CE0..0CE1 ; Alphabetic # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL +0CE2..0CE3 ; Alphabetic # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL +0CF1..0CF2 ; Alphabetic # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA +0D02..0D03 ; Alphabetic # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA +0D05..0D0C ; Alphabetic # Lo [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L +0D0E..0D10 ; Alphabetic # Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI +0D12..0D3A ; Alphabetic # Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA +0D3D ; Alphabetic # Lo MALAYALAM SIGN AVAGRAHA +0D3E..0D40 ; Alphabetic # Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II +0D41..0D44 ; Alphabetic # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR +0D46..0D48 ; Alphabetic # Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI +0D4A..0D4C ; Alphabetic # Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU +0D4E ; Alphabetic # Lo MALAYALAM LETTER DOT REPH +0D57 ; Alphabetic # Mc MALAYALAM AU LENGTH MARK +0D60..0D61 ; Alphabetic # Lo [2] MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL +0D62..0D63 ; Alphabetic # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL +0D7A..0D7F ; Alphabetic # Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K +0D82..0D83 ; Alphabetic # Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA +0D85..0D96 ; Alphabetic # Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA +0D9A..0DB1 ; Alphabetic # Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA +0DB3..0DBB ; Alphabetic # Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA +0DBD ; Alphabetic # Lo SINHALA LETTER DANTAJA LAYANNA +0DC0..0DC6 ; Alphabetic # Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA +0DCF..0DD1 ; Alphabetic # Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA +0DD2..0DD4 ; Alphabetic # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; Alphabetic # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA +0DD8..0DDF ; Alphabetic # Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA +0DF2..0DF3 ; Alphabetic # Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA +0E01..0E30 ; Alphabetic # Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A +0E31 ; Alphabetic # Mn THAI CHARACTER MAI HAN-AKAT +0E32..0E33 ; Alphabetic # Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM +0E34..0E3A ; Alphabetic # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E40..0E45 ; Alphabetic # Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO +0E46 ; Alphabetic # Lm THAI CHARACTER MAIYAMOK +0E4D ; Alphabetic # Mn THAI CHARACTER NIKHAHIT +0E81..0E82 ; Alphabetic # Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG +0E84 ; Alphabetic # Lo LAO LETTER KHO TAM +0E87..0E88 ; Alphabetic # Lo [2] LAO LETTER NGO..LAO LETTER CO +0E8A ; Alphabetic # Lo LAO LETTER SO TAM +0E8D ; Alphabetic # Lo LAO LETTER NYO +0E94..0E97 ; Alphabetic # Lo [4] LAO LETTER DO..LAO LETTER THO TAM +0E99..0E9F ; Alphabetic # Lo [7] LAO LETTER NO..LAO LETTER FO SUNG +0EA1..0EA3 ; Alphabetic # Lo [3] LAO LETTER MO..LAO LETTER LO LING +0EA5 ; Alphabetic # Lo LAO LETTER LO LOOT +0EA7 ; Alphabetic # Lo LAO LETTER WO +0EAA..0EAB ; Alphabetic # Lo [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG +0EAD..0EB0 ; Alphabetic # Lo [4] LAO LETTER O..LAO VOWEL SIGN A +0EB1 ; Alphabetic # Mn LAO VOWEL SIGN MAI KAN +0EB2..0EB3 ; Alphabetic # Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM +0EB4..0EB9 ; Alphabetic # Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU +0EBB..0EBC ; Alphabetic # Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO +0EBD ; Alphabetic # Lo LAO SEMIVOWEL SIGN NYO +0EC0..0EC4 ; Alphabetic # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI +0EC6 ; Alphabetic # Lm LAO KO LA +0ECD ; Alphabetic # Mn LAO NIGGAHITA +0EDC..0EDD ; Alphabetic # Lo [2] LAO HO NO..LAO HO MO +0F00 ; Alphabetic # Lo TIBETAN SYLLABLE OM +0F40..0F47 ; Alphabetic # Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA +0F49..0F6C ; Alphabetic # Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA +0F71..0F7E ; Alphabetic # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO +0F7F ; Alphabetic # Mc TIBETAN SIGN RNAM BCAD +0F80..0F81 ; Alphabetic # Mn [2] TIBETAN VOWEL SIGN REVERSED I..TIBETAN VOWEL SIGN REVERSED II +0F88..0F8C ; Alphabetic # Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN +0F8D..0F97 ; Alphabetic # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA +0F99..0FBC ; Alphabetic # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA +1000..102A ; Alphabetic # Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU +102B..102C ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA +102D..1030 ; Alphabetic # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU +1031 ; Alphabetic # Mc MYANMAR VOWEL SIGN E +1032..1036 ; Alphabetic # Mn [5] MYANMAR VOWEL SIGN AI..MYANMAR SIGN ANUSVARA +1038 ; Alphabetic # Mc MYANMAR SIGN VISARGA +103B..103C ; Alphabetic # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA +103D..103E ; Alphabetic # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA +103F ; Alphabetic # Lo MYANMAR LETTER GREAT SA +1050..1055 ; Alphabetic # Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL +1056..1057 ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR +1058..1059 ; Alphabetic # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL +105A..105D ; Alphabetic # Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE +105E..1060 ; Alphabetic # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA +1061 ; Alphabetic # Lo MYANMAR LETTER SGAW KAREN SHA +1062 ; Alphabetic # Mc MYANMAR VOWEL SIGN SGAW KAREN EU +1065..1066 ; Alphabetic # Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA +1067..1068 ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR VOWEL SIGN WESTERN PWO KAREN UE +106E..1070 ; Alphabetic # Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA +1071..1074 ; Alphabetic # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE +1075..1081 ; Alphabetic # Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA +1082 ; Alphabetic # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA +1083..1084 ; Alphabetic # Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E +1085..1086 ; Alphabetic # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y +108E ; Alphabetic # Lo MYANMAR LETTER RUMAI PALAUNG FA +109C ; Alphabetic # Mc MYANMAR VOWEL SIGN AITON A +109D ; Alphabetic # Mn MYANMAR VOWEL SIGN AITON AI +10A0..10C5 ; Alphabetic # L& [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE +10D0..10FA ; Alphabetic # Lo [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN +10FC ; Alphabetic # Lm MODIFIER LETTER GEORGIAN NAR +1100..1248 ; Alphabetic # Lo [329] HANGUL CHOSEONG KIYEOK..ETHIOPIC SYLLABLE QWA +124A..124D ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE +1250..1256 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO +1258 ; Alphabetic # Lo ETHIOPIC SYLLABLE QHWA +125A..125D ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE +1260..1288 ; Alphabetic # Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA +128A..128D ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE +1290..12B0 ; Alphabetic # Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA +12B2..12B5 ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE +12B8..12BE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO +12C0 ; Alphabetic # Lo ETHIOPIC SYLLABLE KXWA +12C2..12C5 ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE +12C8..12D6 ; Alphabetic # Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O +12D8..1310 ; Alphabetic # Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA +1312..1315 ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE +1318..135A ; Alphabetic # Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA +135F ; Alphabetic # Mn ETHIOPIC COMBINING GEMINATION MARK +1380..138F ; Alphabetic # Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE +13A0..13F4 ; Alphabetic # Lo [85] CHEROKEE LETTER A..CHEROKEE LETTER YV +1401..166C ; Alphabetic # Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA +166F..167F ; Alphabetic # Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W +1681..169A ; Alphabetic # Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH +16A0..16EA ; Alphabetic # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X +16EE..16F0 ; Alphabetic # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL +1700..170C ; Alphabetic # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA +170E..1711 ; Alphabetic # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1712..1713 ; Alphabetic # Mn [2] TAGALOG VOWEL SIGN I..TAGALOG VOWEL SIGN U +1720..1731 ; Alphabetic # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA +1732..1733 ; Alphabetic # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1740..1751 ; Alphabetic # Lo [18] BUHID LETTER A..BUHID LETTER HA +1752..1753 ; Alphabetic # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U +1760..176C ; Alphabetic # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA +176E..1770 ; Alphabetic # Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA +1772..1773 ; Alphabetic # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U +1780..17B3 ; Alphabetic # Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU +17B6 ; Alphabetic # Mc KHMER VOWEL SIGN AA +17B7..17BD ; Alphabetic # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA +17BE..17C5 ; Alphabetic # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU +17C6 ; Alphabetic # Mn KHMER SIGN NIKAHIT +17C7..17C8 ; Alphabetic # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU +17D7 ; Alphabetic # Lm KHMER SIGN LEK TOO +17DC ; Alphabetic # Lo KHMER SIGN AVAKRAHASANYA +1820..1842 ; Alphabetic # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI +1843 ; Alphabetic # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN +1844..1877 ; Alphabetic # Lo [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA +1880..18A8 ; Alphabetic # Lo [41] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER MANCHU ALI GALI BHA +18A9 ; Alphabetic # Mn MONGOLIAN LETTER ALI GALI DAGALGA +18AA ; Alphabetic # Lo MONGOLIAN LETTER MANCHU ALI GALI LHA +18B0..18F5 ; Alphabetic # Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S +1900..191C ; Alphabetic # Lo [29] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER HA +1920..1922 ; Alphabetic # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U +1923..1926 ; Alphabetic # Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU +1927..1928 ; Alphabetic # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O +1929..192B ; Alphabetic # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA +1930..1931 ; Alphabetic # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA +1932 ; Alphabetic # Mn LIMBU SMALL LETTER ANUSVARA +1933..1938 ; Alphabetic # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA +1950..196D ; Alphabetic # Lo [30] TAI LE LETTER KA..TAI LE LETTER AI +1970..1974 ; Alphabetic # Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 +1980..19AB ; Alphabetic # Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA +19B0..19C0 ; Alphabetic # Mc [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY +19C1..19C7 ; Alphabetic # Lo [7] NEW TAI LUE LETTER FINAL V..NEW TAI LUE LETTER FINAL B +19C8..19C9 ; Alphabetic # Mc [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2 +1A00..1A16 ; Alphabetic # Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA +1A17..1A18 ; Alphabetic # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U +1A19..1A1B ; Alphabetic # Mc [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE +1A20..1A54 ; Alphabetic # Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA +1A55 ; Alphabetic # Mc TAI THAM CONSONANT SIGN MEDIAL RA +1A56 ; Alphabetic # Mn TAI THAM CONSONANT SIGN MEDIAL LA +1A57 ; Alphabetic # Mc TAI THAM CONSONANT SIGN LA TANG LAI +1A58..1A5E ; Alphabetic # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA +1A61 ; Alphabetic # Mc TAI THAM VOWEL SIGN A +1A62 ; Alphabetic # Mn TAI THAM VOWEL SIGN MAI SAT +1A63..1A64 ; Alphabetic # Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA +1A65..1A6C ; Alphabetic # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW +1A6D..1A72 ; Alphabetic # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI +1A73..1A74 ; Alphabetic # Mn [2] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN MAI KANG +1AA7 ; Alphabetic # Lm TAI THAM SIGN MAI YAMOK +1B00..1B03 ; Alphabetic # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG +1B04 ; Alphabetic # Mc BALINESE SIGN BISAH +1B05..1B33 ; Alphabetic # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA +1B35 ; Alphabetic # Mc BALINESE VOWEL SIGN TEDUNG +1B36..1B3A ; Alphabetic # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3B ; Alphabetic # Mc BALINESE VOWEL SIGN RA REPA TEDUNG +1B3C ; Alphabetic # Mn BALINESE VOWEL SIGN LA LENGA +1B3D..1B41 ; Alphabetic # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG +1B42 ; Alphabetic # Mn BALINESE VOWEL SIGN PEPET +1B43 ; Alphabetic # Mc BALINESE VOWEL SIGN PEPET TEDUNG +1B45..1B4B ; Alphabetic # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B80..1B81 ; Alphabetic # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR +1B82 ; Alphabetic # Mc SUNDANESE SIGN PANGWISAD +1B83..1BA0 ; Alphabetic # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA +1BA1 ; Alphabetic # Mc SUNDANESE CONSONANT SIGN PAMINGKAL +1BA2..1BA5 ; Alphabetic # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU +1BA6..1BA7 ; Alphabetic # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG +1BA8..1BA9 ; Alphabetic # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAE..1BAF ; Alphabetic # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA +1BC0..1BE5 ; Alphabetic # Lo [38] BATAK LETTER A..BATAK LETTER U +1BE7 ; Alphabetic # Mc BATAK VOWEL SIGN E +1BE8..1BE9 ; Alphabetic # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE +1BEA..1BEC ; Alphabetic # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O +1BED ; Alphabetic # Mn BATAK VOWEL SIGN KARO O +1BEE ; Alphabetic # Mc BATAK VOWEL SIGN U +1BEF..1BF1 ; Alphabetic # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1C00..1C23 ; Alphabetic # Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A +1C24..1C2B ; Alphabetic # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU +1C2C..1C33 ; Alphabetic # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T +1C34..1C35 ; Alphabetic # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG +1C4D..1C4F ; Alphabetic # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA +1C5A..1C77 ; Alphabetic # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH +1C78..1C7D ; Alphabetic # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD +1CE9..1CEC ; Alphabetic # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL +1CEE..1CF1 ; Alphabetic # Lo [4] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ANUSVARA UBHAYATO MUKHA +1CF2 ; Alphabetic # Mc VEDIC SIGN ARDHAVISARGA +1D00..1D2B ; Alphabetic # L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL +1D2C..1D61 ; Alphabetic # Lm [54] MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL CHI +1D62..1D77 ; Alphabetic # L& [22] LATIN SUBSCRIPT SMALL LETTER I..LATIN SMALL LETTER TURNED G +1D78 ; Alphabetic # Lm MODIFIER LETTER CYRILLIC EN +1D79..1D9A ; Alphabetic # L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK +1D9B..1DBF ; Alphabetic # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA +1E00..1F15 ; Alphabetic # L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F18..1F1D ; Alphabetic # L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F20..1F45 ; Alphabetic # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F48..1F4D ; Alphabetic # L& [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50..1F57 ; Alphabetic # L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F59 ; Alphabetic # L& GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B ; Alphabetic # L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D ; Alphabetic # L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F..1F7D ; Alphabetic # L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA +1F80..1FB4 ; Alphabetic # L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6..1FBC ; Alphabetic # L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBE ; Alphabetic # L& GREEK PROSGEGRAMMENI +1FC2..1FC4 ; Alphabetic # L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6..1FCC ; Alphabetic # L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FD0..1FD3 ; Alphabetic # L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6..1FDB ; Alphabetic # L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA +1FE0..1FEC ; Alphabetic # L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA +1FF2..1FF4 ; Alphabetic # L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6..1FFC ; Alphabetic # L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +2071 ; Alphabetic # Lm SUPERSCRIPT LATIN SMALL LETTER I +207F ; Alphabetic # Lm SUPERSCRIPT LATIN SMALL LETTER N +2090..209C ; Alphabetic # Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T +2102 ; Alphabetic # L& DOUBLE-STRUCK CAPITAL C +2107 ; Alphabetic # L& EULER CONSTANT +210A..2113 ; Alphabetic # L& [10] SCRIPT SMALL G..SCRIPT SMALL L +2115 ; Alphabetic # L& DOUBLE-STRUCK CAPITAL N +2119..211D ; Alphabetic # L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +2124 ; Alphabetic # L& DOUBLE-STRUCK CAPITAL Z +2126 ; Alphabetic # L& OHM SIGN +2128 ; Alphabetic # L& BLACK-LETTER CAPITAL Z +212A..212D ; Alphabetic # L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C +212F..2134 ; Alphabetic # L& [6] SCRIPT SMALL E..SCRIPT SMALL O +2135..2138 ; Alphabetic # Lo [4] ALEF SYMBOL..DALET SYMBOL +2139 ; Alphabetic # L& INFORMATION SOURCE +213C..213F ; Alphabetic # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI +2145..2149 ; Alphabetic # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J +214E ; Alphabetic # L& TURNED SMALL F +2160..2182 ; Alphabetic # Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND +2183..2184 ; Alphabetic # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C +2185..2188 ; Alphabetic # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND +24B6..24E9 ; Alphabetic # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z +2C00..2C2E ; Alphabetic # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C30..2C5E ; Alphabetic # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C60..2C7C ; Alphabetic # L& [29] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN SUBSCRIPT SMALL LETTER J +2C7D ; Alphabetic # Lm MODIFIER LETTER CAPITAL V +2C7E..2CE4 ; Alphabetic # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI +2CEB..2CEE ; Alphabetic # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +2D00..2D25 ; Alphabetic # L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE +2D30..2D65 ; Alphabetic # Lo [54] TIFINAGH LETTER YA..TIFINAGH LETTER YAZZ +2D6F ; Alphabetic # Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK +2D80..2D96 ; Alphabetic # Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE +2DA0..2DA6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO +2DA8..2DAE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO +2DB0..2DB6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO +2DB8..2DBE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO +2DC0..2DC6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO +2DC8..2DCE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO +2DD0..2DD6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO +2DD8..2DDE ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO +2DE0..2DFF ; Alphabetic # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS +2E2F ; Alphabetic # Lm VERTICAL TILDE +3005 ; Alphabetic # Lm IDEOGRAPHIC ITERATION MARK +3006 ; Alphabetic # Lo IDEOGRAPHIC CLOSING MARK +3007 ; Alphabetic # Nl IDEOGRAPHIC NUMBER ZERO +3021..3029 ; Alphabetic # Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE +3031..3035 ; Alphabetic # Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF +3038..303A ; Alphabetic # Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY +303B ; Alphabetic # Lm VERTICAL IDEOGRAPHIC ITERATION MARK +303C ; Alphabetic # Lo MASU MARK +3041..3096 ; Alphabetic # Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE +309D..309E ; Alphabetic # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK +309F ; Alphabetic # Lo HIRAGANA DIGRAPH YORI +30A1..30FA ; Alphabetic # Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO +30FC..30FE ; Alphabetic # Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK +30FF ; Alphabetic # Lo KATAKANA DIGRAPH KOTO +3105..312D ; Alphabetic # Lo [41] BOPOMOFO LETTER B..BOPOMOFO LETTER IH +3131..318E ; Alphabetic # Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE +31A0..31BA ; Alphabetic # Lo [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY +31F0..31FF ; Alphabetic # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO +3400..4DB5 ; Alphabetic # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5 +4E00..9FCB ; Alphabetic # Lo [20940] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FCB +A000..A014 ; Alphabetic # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +A015 ; Alphabetic # Lm YI SYLLABLE WU +A016..A48C ; Alphabetic # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR +A4D0..A4F7 ; Alphabetic # Lo [40] LISU LETTER BA..LISU LETTER OE +A4F8..A4FD ; Alphabetic # Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU +A500..A60B ; Alphabetic # Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG +A60C ; Alphabetic # Lm VAI SYLLABLE LENGTHENER +A610..A61F ; Alphabetic # Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG +A62A..A62B ; Alphabetic # Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO +A640..A66D ; Alphabetic # L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +A66E ; Alphabetic # Lo CYRILLIC LETTER MULTIOCULAR O +A67F ; Alphabetic # Lm CYRILLIC PAYEROK +A680..A697 ; Alphabetic # L& [24] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER SHWE +A6A0..A6E5 ; Alphabetic # Lo [70] BAMUM LETTER A..BAMUM LETTER KI +A6E6..A6EF ; Alphabetic # Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM +A717..A71F ; Alphabetic # Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK +A722..A76F ; Alphabetic # L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON +A770 ; Alphabetic # Lm MODIFIER LETTER US +A771..A787 ; Alphabetic # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T +A788 ; Alphabetic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT +A78B..A78E ; Alphabetic # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT +A790..A791 ; Alphabetic # L& [2] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER N WITH DESCENDER +A7A0..A7A9 ; Alphabetic # L& [10] LATIN CAPITAL LETTER G WITH OBLIQUE STROKE..LATIN SMALL LETTER S WITH OBLIQUE STROKE +A7FA ; Alphabetic # L& LATIN LETTER SMALL CAPITAL TURNED M +A7FB..A801 ; Alphabetic # Lo [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I +A803..A805 ; Alphabetic # Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O +A807..A80A ; Alphabetic # Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO +A80C..A822 ; Alphabetic # Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO +A823..A824 ; Alphabetic # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I +A825..A826 ; Alphabetic # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E +A827 ; Alphabetic # Mc SYLOTI NAGRI VOWEL SIGN OO +A840..A873 ; Alphabetic # Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU +A880..A881 ; Alphabetic # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA +A882..A8B3 ; Alphabetic # Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA +A8B4..A8C3 ; Alphabetic # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU +A8F2..A8F7 ; Alphabetic # Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA +A8FB ; Alphabetic # Lo DEVANAGARI HEADSTROKE +A90A..A925 ; Alphabetic # Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO +A926..A92A ; Alphabetic # Mn [5] KAYAH LI VOWEL UE..KAYAH LI VOWEL O +A930..A946 ; Alphabetic # Lo [23] REJANG LETTER KA..REJANG LETTER A +A947..A951 ; Alphabetic # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A952 ; Alphabetic # Mc REJANG CONSONANT SIGN H +A960..A97C ; Alphabetic # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH +A980..A982 ; Alphabetic # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR +A983 ; Alphabetic # Mc JAVANESE SIGN WIGNYAN +A984..A9B2 ; Alphabetic # Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA +A9B4..A9B5 ; Alphabetic # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG +A9B6..A9B9 ; Alphabetic # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT +A9BA..A9BB ; Alphabetic # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE +A9BC ; Alphabetic # Mn JAVANESE VOWEL SIGN PEPET +A9BD..A9BF ; Alphabetic # Mc [3] JAVANESE CONSONANT SIGN KERET..JAVANESE CONSONANT SIGN CAKRA +A9CF ; Alphabetic # Lm JAVANESE PANGRANGKEP +AA00..AA28 ; Alphabetic # Lo [41] CHAM LETTER A..CHAM LETTER HA +AA29..AA2E ; Alphabetic # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE +AA2F..AA30 ; Alphabetic # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI +AA31..AA32 ; Alphabetic # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE +AA33..AA34 ; Alphabetic # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA +AA35..AA36 ; Alphabetic # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA +AA40..AA42 ; Alphabetic # Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG +AA43 ; Alphabetic # Mn CHAM CONSONANT SIGN FINAL NG +AA44..AA4B ; Alphabetic # Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS +AA4C ; Alphabetic # Mn CHAM CONSONANT SIGN FINAL M +AA4D ; Alphabetic # Mc CHAM CONSONANT SIGN FINAL H +AA60..AA6F ; Alphabetic # Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA +AA70 ; Alphabetic # Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION +AA71..AA76 ; Alphabetic # Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM +AA7A ; Alphabetic # Lo MYANMAR LETTER AITON RA +AA80..AAAF ; Alphabetic # Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O +AAB0 ; Alphabetic # Mn TAI VIET MAI KANG +AAB1 ; Alphabetic # Lo TAI VIET VOWEL AA +AAB2..AAB4 ; Alphabetic # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U +AAB5..AAB6 ; Alphabetic # Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O +AAB7..AAB8 ; Alphabetic # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA +AAB9..AABD ; Alphabetic # Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN +AABE ; Alphabetic # Mn TAI VIET VOWEL AM +AAC0 ; Alphabetic # Lo TAI VIET TONE MAI NUENG +AAC2 ; Alphabetic # Lo TAI VIET TONE MAI SONG +AADB..AADC ; Alphabetic # Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG +AADD ; Alphabetic # Lm TAI VIET SYMBOL SAM +AB01..AB06 ; Alphabetic # Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO +AB09..AB0E ; Alphabetic # Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO +AB11..AB16 ; Alphabetic # Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO +AB20..AB26 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO +AB28..AB2E ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO +ABC0..ABE2 ; Alphabetic # Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM +ABE3..ABE4 ; Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP +ABE5 ; Alphabetic # Mn MEETEI MAYEK VOWEL SIGN ANAP +ABE6..ABE7 ; Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP +ABE8 ; Alphabetic # Mn MEETEI MAYEK VOWEL SIGN UNAP +ABE9..ABEA ; Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG +AC00..D7A3 ; Alphabetic # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH +D7B0..D7C6 ; Alphabetic # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E +D7CB..D7FB ; Alphabetic # Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH +F900..FA2D ; Alphabetic # Lo [302] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA2D +FA30..FA6D ; Alphabetic # Lo [62] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6D +FA70..FAD9 ; Alphabetic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +FB00..FB06 ; Alphabetic # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST +FB13..FB17 ; Alphabetic # L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH +FB1D ; Alphabetic # Lo HEBREW LETTER YOD WITH HIRIQ +FB1E ; Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA +FB1F..FB28 ; Alphabetic # Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV +FB2A..FB36 ; Alphabetic # Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH +FB38..FB3C ; Alphabetic # Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH +FB3E ; Alphabetic # Lo HEBREW LETTER MEM WITH DAGESH +FB40..FB41 ; Alphabetic # Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH +FB43..FB44 ; Alphabetic # Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH +FB46..FBB1 ; Alphabetic # Lo [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM +FBD3..FD3D ; Alphabetic # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM +FD50..FD8F ; Alphabetic # Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM +FD92..FDC7 ; Alphabetic # Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM +FDF0..FDFB ; Alphabetic # Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU +FE70..FE74 ; Alphabetic # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM +FE76..FEFC ; Alphabetic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM +FF21..FF3A ; Alphabetic # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z +FF41..FF5A ; Alphabetic # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z +FF66..FF6F ; Alphabetic # Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU +FF70 ; Alphabetic # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK +FF71..FF9D ; Alphabetic # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N +FF9E..FF9F ; Alphabetic # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +FFA0..FFBE ; Alphabetic # Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH +FFC2..FFC7 ; Alphabetic # Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E +FFCA..FFCF ; Alphabetic # Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE +FFD2..FFD7 ; Alphabetic # Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU +FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I +10000..1000B ; Alphabetic # Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE +1000D..10026 ; Alphabetic # Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO +10028..1003A ; Alphabetic # Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO +1003C..1003D ; Alphabetic # Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE +1003F..1004D ; Alphabetic # Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO +10050..1005D ; Alphabetic # Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 +10080..100FA ; Alphabetic # Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 +10140..10174 ; Alphabetic # Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS +10280..1029C ; Alphabetic # Lo [29] LYCIAN LETTER A..LYCIAN LETTER X +102A0..102D0 ; Alphabetic # Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 +10300..1031E ; Alphabetic # Lo [31] OLD ITALIC LETTER A..OLD ITALIC LETTER UU +10330..10340 ; Alphabetic # Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA +10341 ; Alphabetic # Nl GOTHIC LETTER NINETY +10342..10349 ; Alphabetic # Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL +1034A ; Alphabetic # Nl GOTHIC LETTER NINE HUNDRED +10380..1039D ; Alphabetic # Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU +103A0..103C3 ; Alphabetic # Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA +103C8..103CF ; Alphabetic # Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH +103D1..103D5 ; Alphabetic # Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED +10400..1044F ; Alphabetic # L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW +10450..1049D ; Alphabetic # Lo [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO +10800..10805 ; Alphabetic # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA +10808 ; Alphabetic # Lo CYPRIOT SYLLABLE JO +1080A..10835 ; Alphabetic # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO +10837..10838 ; Alphabetic # Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE +1083C ; Alphabetic # Lo CYPRIOT SYLLABLE ZA +1083F..10855 ; Alphabetic # Lo [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW +10900..10915 ; Alphabetic # Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU +10920..10939 ; Alphabetic # Lo [26] LYDIAN LETTER A..LYDIAN LETTER C +10A00 ; Alphabetic # Lo KHAROSHTHI LETTER A +10A01..10A03 ; Alphabetic # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R +10A05..10A06 ; Alphabetic # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O +10A0C..10A0F ; Alphabetic # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA +10A10..10A13 ; Alphabetic # Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA +10A15..10A17 ; Alphabetic # Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA +10A19..10A33 ; Alphabetic # Lo [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA +10A60..10A7C ; Alphabetic # Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH +10B00..10B35 ; Alphabetic # Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE +10B40..10B55 ; Alphabetic # Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW +10B60..10B72 ; Alphabetic # Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW +10C00..10C48 ; Alphabetic # Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH +11000 ; Alphabetic # Mc BRAHMI SIGN CANDRABINDU +11001 ; Alphabetic # Mn BRAHMI SIGN ANUSVARA +11002 ; Alphabetic # Mc BRAHMI SIGN VISARGA +11003..11037 ; Alphabetic # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA +11038..11045 ; Alphabetic # Mn [14] BRAHMI VOWEL SIGN AA..BRAHMI VOWEL SIGN AU +11082 ; Alphabetic # Mc KAITHI SIGN VISARGA +11083..110AF ; Alphabetic # Lo [45] KAITHI LETTER A..KAITHI LETTER HA +110B0..110B2 ; Alphabetic # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II +110B3..110B6 ; Alphabetic # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI +110B7..110B8 ; Alphabetic # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU +12000..1236E ; Alphabetic # Lo [879] CUNEIFORM SIGN A..CUNEIFORM SIGN ZUM +12400..12462 ; Alphabetic # Nl [99] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER +13000..1342E ; Alphabetic # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 +16800..16A38 ; Alphabetic # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ +1B000..1B001 ; Alphabetic # Lo [2] KATAKANA LETTER ARCHAIC E..HIRAGANA LETTER ARCHAIC YE +1D400..1D454 ; Alphabetic # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G +1D456..1D49C ; Alphabetic # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F ; Alphabetic # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2 ; Alphabetic # L& MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6 ; Alphabetic # L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC ; Alphabetic # L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B9 ; Alphabetic # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Alphabetic # L& MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Alphabetic # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D505 ; Alphabetic # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A ; Alphabetic # L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514 ; Alphabetic # L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C ; Alphabetic # L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D51E..1D539 ; Alphabetic # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E ; Alphabetic # L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544 ; Alphabetic # L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 ; Alphabetic # L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550 ; Alphabetic # L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552..1D6A5 ; Alphabetic # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6A8..1D6C0 ; Alphabetic # L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6C2..1D6DA ; Alphabetic # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DC..1D6FA ; Alphabetic # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FC..1D714 ; Alphabetic # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D716..1D734 ; Alphabetic # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D736..1D74E ; Alphabetic # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D750..1D76E ; Alphabetic # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D770..1D788 ; Alphabetic # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D78A..1D7A8 ; Alphabetic # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7AA..1D7C2 ; Alphabetic # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C4..1D7CB ; Alphabetic # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +20000..2A6D6 ; Alphabetic # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6 +2A700..2B734 ; Alphabetic # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +2B740..2B81D ; Alphabetic # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D +2F800..2FA1D ; Alphabetic # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 101539 + +# ================================================ + +# Derived Property: Lowercase +# Generated from: Ll + Other_Lowercase + +0061..007A ; Lowercase # L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00AA ; Lowercase # L& FEMININE ORDINAL INDICATOR +00B5 ; Lowercase # L& MICRO SIGN +00BA ; Lowercase # L& MASCULINE ORDINAL INDICATOR +00DF..00F6 ; Lowercase # L& [24] LATIN SMALL LETTER SHARP S..LATIN SMALL LETTER O WITH DIAERESIS +00F8..00FF ; Lowercase # L& [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS +0101 ; Lowercase # L& LATIN SMALL LETTER A WITH MACRON +0103 ; Lowercase # L& LATIN SMALL LETTER A WITH BREVE +0105 ; Lowercase # L& LATIN SMALL LETTER A WITH OGONEK +0107 ; Lowercase # L& LATIN SMALL LETTER C WITH ACUTE +0109 ; Lowercase # L& LATIN SMALL LETTER C WITH CIRCUMFLEX +010B ; Lowercase # L& LATIN SMALL LETTER C WITH DOT ABOVE +010D ; Lowercase # L& LATIN SMALL LETTER C WITH CARON +010F ; Lowercase # L& LATIN SMALL LETTER D WITH CARON +0111 ; Lowercase # L& LATIN SMALL LETTER D WITH STROKE +0113 ; Lowercase # L& LATIN SMALL LETTER E WITH MACRON +0115 ; Lowercase # L& LATIN SMALL LETTER E WITH BREVE +0117 ; Lowercase # L& LATIN SMALL LETTER E WITH DOT ABOVE +0119 ; Lowercase # L& LATIN SMALL LETTER E WITH OGONEK +011B ; Lowercase # L& LATIN SMALL LETTER E WITH CARON +011D ; Lowercase # L& LATIN SMALL LETTER G WITH CIRCUMFLEX +011F ; Lowercase # L& LATIN SMALL LETTER G WITH BREVE +0121 ; Lowercase # L& LATIN SMALL LETTER G WITH DOT ABOVE +0123 ; Lowercase # L& LATIN SMALL LETTER G WITH CEDILLA +0125 ; Lowercase # L& LATIN SMALL LETTER H WITH CIRCUMFLEX +0127 ; Lowercase # L& LATIN SMALL LETTER H WITH STROKE +0129 ; Lowercase # L& LATIN SMALL LETTER I WITH TILDE +012B ; Lowercase # L& LATIN SMALL LETTER I WITH MACRON +012D ; Lowercase # L& LATIN SMALL LETTER I WITH BREVE +012F ; Lowercase # L& LATIN SMALL LETTER I WITH OGONEK +0131 ; Lowercase # L& LATIN SMALL LETTER DOTLESS I +0133 ; Lowercase # L& LATIN SMALL LIGATURE IJ +0135 ; Lowercase # L& LATIN SMALL LETTER J WITH CIRCUMFLEX +0137..0138 ; Lowercase # L& [2] LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA +013A ; Lowercase # L& LATIN SMALL LETTER L WITH ACUTE +013C ; Lowercase # L& LATIN SMALL LETTER L WITH CEDILLA +013E ; Lowercase # L& LATIN SMALL LETTER L WITH CARON +0140 ; Lowercase # L& LATIN SMALL LETTER L WITH MIDDLE DOT +0142 ; Lowercase # L& LATIN SMALL LETTER L WITH STROKE +0144 ; Lowercase # L& LATIN SMALL LETTER N WITH ACUTE +0146 ; Lowercase # L& LATIN SMALL LETTER N WITH CEDILLA +0148..0149 ; Lowercase # L& [2] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014B ; Lowercase # L& LATIN SMALL LETTER ENG +014D ; Lowercase # L& LATIN SMALL LETTER O WITH MACRON +014F ; Lowercase # L& LATIN SMALL LETTER O WITH BREVE +0151 ; Lowercase # L& LATIN SMALL LETTER O WITH DOUBLE ACUTE +0153 ; Lowercase # L& LATIN SMALL LIGATURE OE +0155 ; Lowercase # L& LATIN SMALL LETTER R WITH ACUTE +0157 ; Lowercase # L& LATIN SMALL LETTER R WITH CEDILLA +0159 ; Lowercase # L& LATIN SMALL LETTER R WITH CARON +015B ; Lowercase # L& LATIN SMALL LETTER S WITH ACUTE +015D ; Lowercase # L& LATIN SMALL LETTER S WITH CIRCUMFLEX +015F ; Lowercase # L& LATIN SMALL LETTER S WITH CEDILLA +0161 ; Lowercase # L& LATIN SMALL LETTER S WITH CARON +0163 ; Lowercase # L& LATIN SMALL LETTER T WITH CEDILLA +0165 ; Lowercase # L& LATIN SMALL LETTER T WITH CARON +0167 ; Lowercase # L& LATIN SMALL LETTER T WITH STROKE +0169 ; Lowercase # L& LATIN SMALL LETTER U WITH TILDE +016B ; Lowercase # L& LATIN SMALL LETTER U WITH MACRON +016D ; Lowercase # L& LATIN SMALL LETTER U WITH BREVE +016F ; Lowercase # L& LATIN SMALL LETTER U WITH RING ABOVE +0171 ; Lowercase # L& LATIN SMALL LETTER U WITH DOUBLE ACUTE +0173 ; Lowercase # L& LATIN SMALL LETTER U WITH OGONEK +0175 ; Lowercase # L& LATIN SMALL LETTER W WITH CIRCUMFLEX +0177 ; Lowercase # L& LATIN SMALL LETTER Y WITH CIRCUMFLEX +017A ; Lowercase # L& LATIN SMALL LETTER Z WITH ACUTE +017C ; Lowercase # L& LATIN SMALL LETTER Z WITH DOT ABOVE +017E..0180 ; Lowercase # L& [3] LATIN SMALL LETTER Z WITH CARON..LATIN SMALL LETTER B WITH STROKE +0183 ; Lowercase # L& LATIN SMALL LETTER B WITH TOPBAR +0185 ; Lowercase # L& LATIN SMALL LETTER TONE SIX +0188 ; Lowercase # L& LATIN SMALL LETTER C WITH HOOK +018C..018D ; Lowercase # L& [2] LATIN SMALL LETTER D WITH TOPBAR..LATIN SMALL LETTER TURNED DELTA +0192 ; Lowercase # L& LATIN SMALL LETTER F WITH HOOK +0195 ; Lowercase # L& LATIN SMALL LETTER HV +0199..019B ; Lowercase # L& [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE +019E ; Lowercase # L& LATIN SMALL LETTER N WITH LONG RIGHT LEG +01A1 ; Lowercase # L& LATIN SMALL LETTER O WITH HORN +01A3 ; Lowercase # L& LATIN SMALL LETTER OI +01A5 ; Lowercase # L& LATIN SMALL LETTER P WITH HOOK +01A8 ; Lowercase # L& LATIN SMALL LETTER TONE TWO +01AA..01AB ; Lowercase # L& [2] LATIN LETTER REVERSED ESH LOOP..LATIN SMALL LETTER T WITH PALATAL HOOK +01AD ; Lowercase # L& LATIN SMALL LETTER T WITH HOOK +01B0 ; Lowercase # L& LATIN SMALL LETTER U WITH HORN +01B4 ; Lowercase # L& LATIN SMALL LETTER Y WITH HOOK +01B6 ; Lowercase # L& LATIN SMALL LETTER Z WITH STROKE +01B9..01BA ; Lowercase # L& [2] LATIN SMALL LETTER EZH REVERSED..LATIN SMALL LETTER EZH WITH TAIL +01BD..01BF ; Lowercase # L& [3] LATIN SMALL LETTER TONE FIVE..LATIN LETTER WYNN +01C6 ; Lowercase # L& LATIN SMALL LETTER DZ WITH CARON +01C9 ; Lowercase # L& LATIN SMALL LETTER LJ +01CC ; Lowercase # L& LATIN SMALL LETTER NJ +01CE ; Lowercase # L& LATIN SMALL LETTER A WITH CARON +01D0 ; Lowercase # L& LATIN SMALL LETTER I WITH CARON +01D2 ; Lowercase # L& LATIN SMALL LETTER O WITH CARON +01D4 ; Lowercase # L& LATIN SMALL LETTER U WITH CARON +01D6 ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +01D8 ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +01DA ; Lowercase # L& LATIN SMALL LETTER U WITH DIAERESIS AND CARON +01DC..01DD ; Lowercase # L& [2] LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E +01DF ; Lowercase # L& LATIN SMALL LETTER A WITH DIAERESIS AND MACRON +01E1 ; Lowercase # L& LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON +01E3 ; Lowercase # L& LATIN SMALL LETTER AE WITH MACRON +01E5 ; Lowercase # L& LATIN SMALL LETTER G WITH STROKE +01E7 ; Lowercase # L& LATIN SMALL LETTER G WITH CARON +01E9 ; Lowercase # L& LATIN SMALL LETTER K WITH CARON +01EB ; Lowercase # L& LATIN SMALL LETTER O WITH OGONEK +01ED ; Lowercase # L& LATIN SMALL LETTER O WITH OGONEK AND MACRON +01EF..01F0 ; Lowercase # L& [2] LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON +01F3 ; Lowercase # L& LATIN SMALL LETTER DZ +01F5 ; Lowercase # L& LATIN SMALL LETTER G WITH ACUTE +01F9 ; Lowercase # L& LATIN SMALL LETTER N WITH GRAVE +01FB ; Lowercase # L& LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +01FD ; Lowercase # L& LATIN SMALL LETTER AE WITH ACUTE +01FF ; Lowercase # L& LATIN SMALL LETTER O WITH STROKE AND ACUTE +0201 ; Lowercase # L& LATIN SMALL LETTER A WITH DOUBLE GRAVE +0203 ; Lowercase # L& LATIN SMALL LETTER A WITH INVERTED BREVE +0205 ; Lowercase # L& LATIN SMALL LETTER E WITH DOUBLE GRAVE +0207 ; Lowercase # L& LATIN SMALL LETTER E WITH INVERTED BREVE +0209 ; Lowercase # L& LATIN SMALL LETTER I WITH DOUBLE GRAVE +020B ; Lowercase # L& LATIN SMALL LETTER I WITH INVERTED BREVE +020D ; Lowercase # L& LATIN SMALL LETTER O WITH DOUBLE GRAVE +020F ; Lowercase # L& LATIN SMALL LETTER O WITH INVERTED BREVE +0211 ; Lowercase # L& LATIN SMALL LETTER R WITH DOUBLE GRAVE +0213 ; Lowercase # L& LATIN SMALL LETTER R WITH INVERTED BREVE +0215 ; Lowercase # L& LATIN SMALL LETTER U WITH DOUBLE GRAVE +0217 ; Lowercase # L& LATIN SMALL LETTER U WITH INVERTED BREVE +0219 ; Lowercase # L& LATIN SMALL LETTER S WITH COMMA BELOW +021B ; Lowercase # L& LATIN SMALL LETTER T WITH COMMA BELOW +021D ; Lowercase # L& LATIN SMALL LETTER YOGH +021F ; Lowercase # L& LATIN SMALL LETTER H WITH CARON +0221 ; Lowercase # L& LATIN SMALL LETTER D WITH CURL +0223 ; Lowercase # L& LATIN SMALL LETTER OU +0225 ; Lowercase # L& LATIN SMALL LETTER Z WITH HOOK +0227 ; Lowercase # L& LATIN SMALL LETTER A WITH DOT ABOVE +0229 ; Lowercase # L& LATIN SMALL LETTER E WITH CEDILLA +022B ; Lowercase # L& LATIN SMALL LETTER O WITH DIAERESIS AND MACRON +022D ; Lowercase # L& LATIN SMALL LETTER O WITH TILDE AND MACRON +022F ; Lowercase # L& LATIN SMALL LETTER O WITH DOT ABOVE +0231 ; Lowercase # L& LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON +0233..0239 ; Lowercase # L& [7] LATIN SMALL LETTER Y WITH MACRON..LATIN SMALL LETTER QP DIGRAPH +023C ; Lowercase # L& LATIN SMALL LETTER C WITH STROKE +023F..0240 ; Lowercase # L& [2] LATIN SMALL LETTER S WITH SWASH TAIL..LATIN SMALL LETTER Z WITH SWASH TAIL +0242 ; Lowercase # L& LATIN SMALL LETTER GLOTTAL STOP +0247 ; Lowercase # L& LATIN SMALL LETTER E WITH STROKE +0249 ; Lowercase # L& LATIN SMALL LETTER J WITH STROKE +024B ; Lowercase # L& LATIN SMALL LETTER Q WITH HOOK TAIL +024D ; Lowercase # L& LATIN SMALL LETTER R WITH STROKE +024F..0293 ; Lowercase # L& [69] LATIN SMALL LETTER Y WITH STROKE..LATIN SMALL LETTER EZH WITH CURL +0295..02AF ; Lowercase # L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +02B0..02B8 ; Lowercase # Lm [9] MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y +02C0..02C1 ; Lowercase # Lm [2] MODIFIER LETTER GLOTTAL STOP..MODIFIER LETTER REVERSED GLOTTAL STOP +02E0..02E4 ; Lowercase # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +0345 ; Lowercase # Mn COMBINING GREEK YPOGEGRAMMENI +0371 ; Lowercase # L& GREEK SMALL LETTER HETA +0373 ; Lowercase # L& GREEK SMALL LETTER ARCHAIC SAMPI +0377 ; Lowercase # L& GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037A ; Lowercase # Lm GREEK YPOGEGRAMMENI +037B..037D ; Lowercase # L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +0390 ; Lowercase # L& GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +03AC..03CE ; Lowercase # L& [35] GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER OMEGA WITH TONOS +03D0..03D1 ; Lowercase # L& [2] GREEK BETA SYMBOL..GREEK THETA SYMBOL +03D5..03D7 ; Lowercase # L& [3] GREEK PHI SYMBOL..GREEK KAI SYMBOL +03D9 ; Lowercase # L& GREEK SMALL LETTER ARCHAIC KOPPA +03DB ; Lowercase # L& GREEK SMALL LETTER STIGMA +03DD ; Lowercase # L& GREEK SMALL LETTER DIGAMMA +03DF ; Lowercase # L& GREEK SMALL LETTER KOPPA +03E1 ; Lowercase # L& GREEK SMALL LETTER SAMPI +03E3 ; Lowercase # L& COPTIC SMALL LETTER SHEI +03E5 ; Lowercase # L& COPTIC SMALL LETTER FEI +03E7 ; Lowercase # L& COPTIC SMALL LETTER KHEI +03E9 ; Lowercase # L& COPTIC SMALL LETTER HORI +03EB ; Lowercase # L& COPTIC SMALL LETTER GANGIA +03ED ; Lowercase # L& COPTIC SMALL LETTER SHIMA +03EF..03F3 ; Lowercase # L& [5] COPTIC SMALL LETTER DEI..GREEK LETTER YOT +03F5 ; Lowercase # L& GREEK LUNATE EPSILON SYMBOL +03F8 ; Lowercase # L& GREEK SMALL LETTER SHO +03FB..03FC ; Lowercase # L& [2] GREEK SMALL LETTER SAN..GREEK RHO WITH STROKE SYMBOL +0430..045F ; Lowercase # L& [48] CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE +0461 ; Lowercase # L& CYRILLIC SMALL LETTER OMEGA +0463 ; Lowercase # L& CYRILLIC SMALL LETTER YAT +0465 ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED E +0467 ; Lowercase # L& CYRILLIC SMALL LETTER LITTLE YUS +0469 ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS +046B ; Lowercase # L& CYRILLIC SMALL LETTER BIG YUS +046D ; Lowercase # L& CYRILLIC SMALL LETTER IOTIFIED BIG YUS +046F ; Lowercase # L& CYRILLIC SMALL LETTER KSI +0471 ; Lowercase # L& CYRILLIC SMALL LETTER PSI +0473 ; Lowercase # L& CYRILLIC SMALL LETTER FITA +0475 ; Lowercase # L& CYRILLIC SMALL LETTER IZHITSA +0477 ; Lowercase # L& CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0479 ; Lowercase # L& CYRILLIC SMALL LETTER UK From noreply at buildbot.pypy.org Wed Mar 20 02:49:30 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Wed, 20 Mar 2013 02:49:30 +0100 (CET) Subject: [pypy-commit] pypy default: Skip a couple of tests when no Mercurial repo present Message-ID: <20130320014930.810F51C03A7@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62537:9560ecb7c7e5 Date: 2013-03-19 17:57 -0700 http://bitbucket.org/pypy/pypy/changeset/9560ecb7c7e5/ Log: Skip a couple of tests when no Mercurial repo present diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py --- a/pypy/doc/test/test_whatsnew.py +++ b/pypy/doc/test/test_whatsnew.py @@ -1,6 +1,6 @@ import py import pypy -from commands import getoutput +from commands import getoutput, getstatusoutput ROOT = py.path.local(pypy.__file__).dirpath().dirpath() @@ -20,6 +20,9 @@ return startrev, branches def get_merged_branches(path, startrev, endrev): + if getstatusoutput('hg root')[0]: + py.test.skip('no Mercurial repo') + # X = take all the merges which are descendants of startrev and are on default # revset = all the parents of X which are not on default # ===> From noreply at buildbot.pypy.org Wed Mar 20 02:49:31 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Wed, 20 Mar 2013 02:49:31 +0100 (CET) Subject: [pypy-commit] pypy default: Split up x86 test_ztranslation for better parallelism Message-ID: <20130320014931.CC5581C03A7@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62538:3d0ceb85dc14 Date: 2013-03-19 18:45 -0700 http://bitbucket.org/pypy/pypy/changeset/3d0ceb85dc14/ Log: Split up x86 test_ztranslation for better parallelism This is by far the longest-running test file. diff --git a/rpython/jit/backend/x86/test/test_ztranslation.py b/rpython/jit/backend/x86/test/test_ztranslation.py --- a/rpython/jit/backend/x86/test/test_ztranslation.py +++ b/rpython/jit/backend/x86/test/test_ztranslation.py @@ -22,155 +22,6 @@ assert '-msse2' in cbuilder.eci.compile_extra assert '-mfpmath=sse' in cbuilder.eci.compile_extra - def test_stuff_translates(self): - # this is a basic test that tries to hit a number of features and their - # translation: - # - jitting of loops and bridges - # - virtualizables - # - set_param interface - # - profiler - # - full optimizer - # - floats neg and abs - - class Frame(object): - _virtualizable2_ = ['i'] - - def __init__(self, i): - self.i = i - - @dont_look_inside - def myabs(x): - return abs(x) - - jitdriver = JitDriver(greens = [], - reds = ['total', 'frame', 'j'], - virtualizables = ['frame']) - def f(i, j): - for param, _ in unroll_parameters: - defl = PARAMETERS[param] - set_param(jitdriver, param, defl) - set_param(jitdriver, "threshold", 3) - set_param(jitdriver, "trace_eagerness", 2) - total = 0 - frame = Frame(i) - j = float(j) - while frame.i > 3: - jitdriver.can_enter_jit(frame=frame, total=total, j=j) - jitdriver.jit_merge_point(frame=frame, total=total, j=j) - total += frame.i - if frame.i >= 20: - frame.i -= 2 - frame.i -= 1 - j *= -0.712 - if j + (-j): raise ValueError - k = myabs(j) - if k - abs(j): raise ValueError - if k - abs(-j): raise ValueError - return chr(total % 253) - # - from rpython.rtyper.lltypesystem import lltype, rffi - from rpython.rlib.libffi import types, CDLL, ArgChain - from rpython.rlib.test.test_clibffi import get_libm_name - libm_name = get_libm_name(sys.platform) - jitdriver2 = JitDriver(greens=[], reds = ['i', 'func', 'res', 'x']) - def libffi_stuff(i, j): - lib = CDLL(libm_name) - func = lib.getpointer('fabs', [types.double], types.double) - res = 0.0 - x = float(j) - while i > 0: - jitdriver2.jit_merge_point(i=i, res=res, func=func, x=x) - promote(func) - argchain = ArgChain() - argchain.arg(x) - res = func.call(argchain, rffi.DOUBLE) - i -= 1 - return res - # - def main(i, j): - a_char = f(i, j) - a_float = libffi_stuff(i, j) - return ord(a_char) * 10 + int(a_float) - expected = main(40, -49) - res = self.meta_interp(main, [40, -49]) - assert res == expected - - def test_direct_assembler_call_translates(self): - """Test CALL_ASSEMBLER and the recursion limit""" - from rpython.rlib.rstackovf import StackOverflow - - class Thing(object): - def __init__(self, val): - self.val = val - - class Frame(object): - _virtualizable2_ = ['thing'] - - driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], - virtualizables = ['frame'], - get_printable_location = lambda codeno: str(codeno)) - class SomewhereElse(object): - pass - - somewhere_else = SomewhereElse() - - def change(newthing): - somewhere_else.frame.thing = newthing - - def main(codeno): - frame = Frame() - somewhere_else.frame = frame - frame.thing = Thing(0) - portal(codeno, frame) - return frame.thing.val - - def portal(codeno, frame): - i = 0 - while i < 10: - driver.can_enter_jit(frame=frame, codeno=codeno, i=i) - driver.jit_merge_point(frame=frame, codeno=codeno, i=i) - nextval = frame.thing.val - if codeno == 0: - subframe = Frame() - subframe.thing = Thing(nextval) - nextval = portal(1, subframe) - elif frame.thing.val > 40: - change(Thing(13)) - nextval = 13 - frame.thing = Thing(nextval + 1) - i += 1 - return frame.thing.val - - driver2 = JitDriver(greens = [], reds = ['n']) - - def main2(bound): - try: - while portal2(bound) == -bound+1: - bound *= 2 - except StackOverflow: - pass - return bound - - def portal2(n): - while True: - driver2.jit_merge_point(n=n) - n -= 1 - if n <= 0: - return n - n = portal2(n) - assert portal2(10) == -9 - - def mainall(codeno, bound): - return main(codeno) + main2(bound) - - res = self.meta_interp(mainall, [0, 1], inline=True, - policy=StopAtXPolicy(change)) - print hex(res) - assert res & 255 == main(0) - bound = res & ~255 - assert 1024 <= bound <= 131072 - assert bound & (bound-1) == 0 # a power of two - def test_jit_get_stats(self): driver = JitDriver(greens = [], reds = ['i']) @@ -189,87 +40,3 @@ res = self.meta_interp(main, []) assert res == 3 # one for loop, one for entry point and one for the prologue - -class TestTranslationRemoveTypePtrX86(CCompiledMixin): - CPUClass = getcpuclass() - - def _get_TranslationContext(self): - t = TranslationContext() - t.config.translation.gc = DEFL_GC # 'hybrid' or 'minimark' - t.config.translation.gcrootfinder = 'asmgcc' - t.config.translation.list_comprehension_operations = True - t.config.translation.gcremovetypeptr = True - return t - - def test_external_exception_handling_translates(self): - jitdriver = JitDriver(greens = [], reds = ['n', 'total']) - - class ImDone(Exception): - def __init__(self, resvalue): - self.resvalue = resvalue - - @dont_look_inside - def f(x, total): - if x <= 30: - raise ImDone(total * 10) - if x > 200: - return 2 - raise ValueError - @dont_look_inside - def g(x): - if x > 150: - raise ValueError - return 2 - class Base: - def meth(self): - return 2 - class Sub(Base): - def meth(self): - return 1 - @dont_look_inside - def h(x): - if x < 20000: - return Sub() - else: - return Base() - def myportal(i): - set_param(jitdriver, "threshold", 3) - set_param(jitdriver, "trace_eagerness", 2) - total = 0 - n = i - while True: - jitdriver.can_enter_jit(n=n, total=total) - jitdriver.jit_merge_point(n=n, total=total) - try: - total += f(n, total) - except ValueError: - total += 1 - try: - total += g(n) - except ValueError: - total -= 1 - n -= h(n).meth() # this is to force a GUARD_CLASS - def main(i): - try: - myportal(i) - except ImDone, e: - return e.resvalue - - # XXX custom fishing, depends on the exact env var and format - logfile = udir.join('test_ztranslation.log') - os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,) - try: - res = self.meta_interp(main, [400]) - assert res == main(400) - finally: - del os.environ['PYPYLOG'] - - guard_class = 0 - for line in open(str(logfile)): - if 'guard_class' in line: - guard_class += 1 - # if we get many more guard_classes, it means that we generate - # guards that always fail (the following assert's original purpose - # is to catch the following case: each GUARD_CLASS is misgenerated - # and always fails with "gcremovetypeptr") - assert 0 < guard_class < 10 diff --git a/rpython/jit/backend/x86/test/test_ztranslation_basic.py b/rpython/jit/backend/x86/test/test_ztranslation_basic.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/x86/test/test_ztranslation_basic.py @@ -0,0 +1,96 @@ +import py, os, sys +from rpython.tool.udir import udir +from rpython.rlib.jit import JitDriver, unroll_parameters, set_param +from rpython.rlib.jit import PARAMETERS, dont_look_inside +from rpython.rlib.jit import promote +from rpython.rlib import jit_hooks +from rpython.jit.metainterp.jitprof import Profiler +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.backend.test.support import CCompiledMixin +from rpython.jit.codewriter.policy import StopAtXPolicy +from rpython.translator.translator import TranslationContext +from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 +from rpython.config.translationoption import DEFL_GC +from rpython.rlib import rgc + +class TestTranslationX86(CCompiledMixin): + CPUClass = getcpuclass() + + def _check_cbuilder(self, cbuilder): + # We assume here that we have sse2. If not, the CPUClass + # needs to be changed to CPU386_NO_SSE2, but well. + assert '-msse2' in cbuilder.eci.compile_extra + assert '-mfpmath=sse' in cbuilder.eci.compile_extra + + def test_stuff_translates(self): + # this is a basic test that tries to hit a number of features and their + # translation: + # - jitting of loops and bridges + # - virtualizables + # - set_param interface + # - profiler + # - full optimizer + # - floats neg and abs + + class Frame(object): + _virtualizable2_ = ['i'] + + def __init__(self, i): + self.i = i + + @dont_look_inside + def myabs(x): + return abs(x) + + jitdriver = JitDriver(greens = [], + reds = ['total', 'frame', 'j'], + virtualizables = ['frame']) + def f(i, j): + for param, _ in unroll_parameters: + defl = PARAMETERS[param] + set_param(jitdriver, param, defl) + set_param(jitdriver, "threshold", 3) + set_param(jitdriver, "trace_eagerness", 2) + total = 0 + frame = Frame(i) + j = float(j) + while frame.i > 3: + jitdriver.can_enter_jit(frame=frame, total=total, j=j) + jitdriver.jit_merge_point(frame=frame, total=total, j=j) + total += frame.i + if frame.i >= 20: + frame.i -= 2 + frame.i -= 1 + j *= -0.712 + if j + (-j): raise ValueError + k = myabs(j) + if k - abs(j): raise ValueError + if k - abs(-j): raise ValueError + return chr(total % 253) + # + from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.libffi import types, CDLL, ArgChain + from rpython.rlib.test.test_clibffi import get_libm_name + libm_name = get_libm_name(sys.platform) + jitdriver2 = JitDriver(greens=[], reds = ['i', 'func', 'res', 'x']) + def libffi_stuff(i, j): + lib = CDLL(libm_name) + func = lib.getpointer('fabs', [types.double], types.double) + res = 0.0 + x = float(j) + while i > 0: + jitdriver2.jit_merge_point(i=i, res=res, func=func, x=x) + promote(func) + argchain = ArgChain() + argchain.arg(x) + res = func.call(argchain, rffi.DOUBLE) + i -= 1 + return res + # + def main(i, j): + a_char = f(i, j) + a_float = libffi_stuff(i, j) + return ord(a_char) * 10 + int(a_float) + expected = main(40, -49) + res = self.meta_interp(main, [40, -49]) + assert res == expected diff --git a/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py b/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py @@ -0,0 +1,99 @@ +import py, os, sys +from rpython.tool.udir import udir +from rpython.rlib.jit import JitDriver, unroll_parameters, set_param +from rpython.rlib.jit import PARAMETERS, dont_look_inside +from rpython.rlib.jit import promote +from rpython.rlib import jit_hooks +from rpython.jit.metainterp.jitprof import Profiler +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.backend.test.support import CCompiledMixin +from rpython.jit.codewriter.policy import StopAtXPolicy +from rpython.translator.translator import TranslationContext +from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 +from rpython.config.translationoption import DEFL_GC +from rpython.rlib import rgc + +class TestTranslationX86(CCompiledMixin): + CPUClass = getcpuclass() + + def _check_cbuilder(self, cbuilder): + # We assume here that we have sse2. If not, the CPUClass + # needs to be changed to CPU386_NO_SSE2, but well. + assert '-msse2' in cbuilder.eci.compile_extra + assert '-mfpmath=sse' in cbuilder.eci.compile_extra + + def test_direct_assembler_call_translates(self): + """Test CALL_ASSEMBLER and the recursion limit""" + from rpython.rlib.rstackovf import StackOverflow + + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], + virtualizables = ['frame'], + get_printable_location = lambda codeno: str(codeno)) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing): + somewhere_else.frame.thing = newthing + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + change(Thing(13)) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + driver2 = JitDriver(greens = [], reds = ['n']) + + def main2(bound): + try: + while portal2(bound) == -bound+1: + bound *= 2 + except StackOverflow: + pass + return bound + + def portal2(n): + while True: + driver2.jit_merge_point(n=n) + n -= 1 + if n <= 0: + return n + n = portal2(n) + assert portal2(10) == -9 + + def mainall(codeno, bound): + return main(codeno) + main2(bound) + + res = self.meta_interp(mainall, [0, 1], inline=True, + policy=StopAtXPolicy(change)) + print hex(res) + assert res & 255 == main(0) + bound = res & ~255 + assert 1024 <= bound <= 131072 + assert bound & (bound-1) == 0 # a power of two diff --git a/rpython/jit/backend/x86/test/test_ztranslation_external_exception.py b/rpython/jit/backend/x86/test/test_ztranslation_external_exception.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/x86/test/test_ztranslation_external_exception.py @@ -0,0 +1,99 @@ +import py, os, sys +from rpython.tool.udir import udir +from rpython.rlib.jit import JitDriver, unroll_parameters, set_param +from rpython.rlib.jit import PARAMETERS, dont_look_inside +from rpython.rlib.jit import promote +from rpython.rlib import jit_hooks +from rpython.jit.metainterp.jitprof import Profiler +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.backend.test.support import CCompiledMixin +from rpython.jit.codewriter.policy import StopAtXPolicy +from rpython.translator.translator import TranslationContext +from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 +from rpython.config.translationoption import DEFL_GC +from rpython.rlib import rgc + + +class TestTranslationRemoveTypePtrX86(CCompiledMixin): + CPUClass = getcpuclass() + + def _get_TranslationContext(self): + t = TranslationContext() + t.config.translation.gc = DEFL_GC # 'hybrid' or 'minimark' + t.config.translation.gcrootfinder = 'asmgcc' + t.config.translation.list_comprehension_operations = True + t.config.translation.gcremovetypeptr = True + return t + + def test_external_exception_handling_translates(self): + jitdriver = JitDriver(greens = [], reds = ['n', 'total']) + + class ImDone(Exception): + def __init__(self, resvalue): + self.resvalue = resvalue + + @dont_look_inside + def f(x, total): + if x <= 30: + raise ImDone(total * 10) + if x > 200: + return 2 + raise ValueError + @dont_look_inside + def g(x): + if x > 150: + raise ValueError + return 2 + class Base: + def meth(self): + return 2 + class Sub(Base): + def meth(self): + return 1 + @dont_look_inside + def h(x): + if x < 20000: + return Sub() + else: + return Base() + def myportal(i): + set_param(jitdriver, "threshold", 3) + set_param(jitdriver, "trace_eagerness", 2) + total = 0 + n = i + while True: + jitdriver.can_enter_jit(n=n, total=total) + jitdriver.jit_merge_point(n=n, total=total) + try: + total += f(n, total) + except ValueError: + total += 1 + try: + total += g(n) + except ValueError: + total -= 1 + n -= h(n).meth() # this is to force a GUARD_CLASS + def main(i): + try: + myportal(i) + except ImDone, e: + return e.resvalue + + # XXX custom fishing, depends on the exact env var and format + logfile = udir.join('test_ztranslation.log') + os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,) + try: + res = self.meta_interp(main, [400]) + assert res == main(400) + finally: + del os.environ['PYPYLOG'] + + guard_class = 0 + for line in open(str(logfile)): + if 'guard_class' in line: + guard_class += 1 + # if we get many more guard_classes, it means that we generate + # guards that always fail (the following assert's original purpose + # is to catch the following case: each GUARD_CLASS is misgenerated + # and always fails with "gcremovetypeptr") + assert 0 < guard_class < 10 From noreply at buildbot.pypy.org Wed Mar 20 03:51:25 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Wed, 20 Mar 2013 03:51:25 +0100 (CET) Subject: [pypy-commit] pypy default: rmmap: Add partial unmap Message-ID: <20130320025125.9B72A1C1016@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62539:5adf8d0c5c56 Date: 2013-03-19 19:38 -0700 http://bitbucket.org/pypy/pypy/changeset/5adf8d0c5c56/ Log: rmmap: Add partial unmap diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -287,6 +287,15 @@ self.data = data self.size = size + def unmap_range(self, offset, size): + """Unmap (a portion of) the mapped range. POSIX only. + + Per munmap(1), the offset must be a multiple of the page size, + and the size will be rounded up to a multiple of the page size. + """ + assert _POSIX + return c_munmap_safe(self.getptr(offset), size) + def close(self): if _MS_WINDOWS: if self.size > 0: @@ -307,7 +316,7 @@ os.close(self.fd) self.fd = -1 if self.size > 0: - c_munmap_safe(self.getptr(0), self.size) + self.unmap_range(0, self.size) self.setdata(NODATA, 0) def __del__(self): @@ -677,6 +686,11 @@ m.setdata(res, map_size) return m + def alloc_hinted(hintp, map_size): + flags = MAP_PRIVATE | MAP_ANONYMOUS + prot = PROT_EXEC | PROT_READ | PROT_WRITE + return c_mmap_safe(hintp, map_size, prot, flags, -1, 0) + # XXX is this really necessary? class Hint: pos = -0x4fff0000 # for reproducible results @@ -695,15 +709,11 @@ if res == rffi.cast(PTR, 0): raise MemoryError return res - flags = MAP_PRIVATE | MAP_ANONYMOUS - prot = PROT_EXEC | PROT_READ | PROT_WRITE - hintp = rffi.cast(PTR, hint.pos) - res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0) + res = alloc_hinted(rffi.cast(PTR, hint.pos), map_size) if res == rffi.cast(PTR, -1): # some systems (some versions of OS/X?) complain if they # are passed a non-zero address. Try again. - hintp = rffi.cast(PTR, 0) - res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0) + res = alloc_hinted(rffi.cast(PTR, 0), map_size) if res == rffi.cast(PTR, -1): raise MemoryError else: diff --git a/rpython/rlib/test/test_rmmap.py b/rpython/rlib/test/test_rmmap.py --- a/rpython/rlib/test/test_rmmap.py +++ b/rpython/rlib/test/test_rmmap.py @@ -1,6 +1,7 @@ from rpython.tool.udir import udir import os, sys, py from rpython.rtyper.test.test_llinterp import interpret +from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib.rarithmetic import intmask from rpython.rlib import rmmap as mmap from rpython.rlib.rmmap import RTypeError, RValueError, alloc, free @@ -64,6 +65,29 @@ f.close() + def test_unmap(self): + f = open(self.tmpname + "-unmap", "w+") + left, right, size = 100, 200, 500 # in pages + + f.write(size*4096*"c") + f.flush() + + def func(no): + m = mmap.mmap(no, size*4096) + m.unmap_range(left*4096, (right-left)*4096) + m.read(1) + m.seek(right*4096) + m.read(1) + + def in_map(m, offset): + return rffi.ptradd(m.data, offset) + def as_num(ptr): + return rffi.cast(lltype.Unsigned, ptr) + res = mmap.alloc_hinted(in_map(m, (left+right)/2 * 4096), 4096) + assert as_num(in_map(m, left*4096)) <= as_num(res) < as_num(in_map(m, right*4096)) + interpret(func, [f.fileno()]) + f.close() + def test_close(self): f = open(self.tmpname + "c", "w+") @@ -80,6 +104,7 @@ else: raise Exception("Did not raise") interpret(func, [f.fileno()]) + f.close() def test_read_byte(self): f = open(self.tmpname + "d", "w+") From noreply at buildbot.pypy.org Wed Mar 20 03:51:26 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Wed, 20 Mar 2013 03:51:26 +0100 (CET) Subject: [pypy-commit] pypy default: ll2ctypes: Avoid keeping 20G all allocated in far_regions Message-ID: <20130320025126.CEB0E1C13F4@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62540:f442d5262c40 Date: 2013-03-19 19:46 -0700 http://bitbucket.org/pypy/pypy/changeset/f442d5262c40/ Log: ll2ctypes: Avoid keeping 20G all allocated in far_regions This helps avoid scaring Linux about how much memory is committed, as we don't actually use close to all this memory. diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -84,12 +84,16 @@ if not far_regions: from rpython.rlib import rmmap if _64BIT: - PIECESIZE = 0x80000000 + PIECE_STRIDE = 0x80000000 else: if _POSIX: - PIECESIZE = 0x10000000 + PIECE_STRIDE = 0x10000000 else: - PIECESIZE = 0x08000000 + PIECE_STRIDE = 0x08000000 + if _POSIX: + PIECE_SIZE = 0x04000000 + else: + PIECE_SIZE = PIECE_STRIDE PIECES = 10 flags = (0,) if _POSIX: @@ -100,12 +104,16 @@ # XXX seems not to work else: assert False # should always generate flags - m = rmmap.mmap(-1, PIECES * PIECESIZE, *flags) + + m = rmmap.mmap(-1, PIECES * PIECE_STRIDE, *flags) m.close = lambda : None # leak instead of giving a spurious # error at CPython's shutdown m._ll2ctypes_pieces = [] for i in range(PIECES): - m._ll2ctypes_pieces.append((i * PIECESIZE, (i+1) * PIECESIZE)) + start = i * PIECE_STRIDE + m._ll2ctypes_pieces.append((start, start + PIECE_SIZE)) + if _POSIX: + m.unmap_range(start + PIECE_SIZE, PIECE_STRIDE - PIECE_SIZE) far_regions = m # ____________________________________________________________ From noreply at buildbot.pypy.org Wed Mar 20 03:51:28 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Wed, 20 Mar 2013 03:51:28 +0100 (CET) Subject: [pypy-commit] pypy default: ll2ctypes: Get unmap from ctypes before it's too late Message-ID: <20130320025128.0D1EC1C1016@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62541:3a60f1ff6d07 Date: 2013-03-19 19:47 -0700 http://bitbucket.org/pypy/pypy/changeset/3a60f1ff6d07/ Log: ll2ctypes: Get unmap from ctypes before it's too late diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -105,6 +105,12 @@ else: assert False # should always generate flags + # Map and unmap something just to exercise unmap so that we (lazily) + # build the ctypes callable. Otherwise, when we reach unmap below + # we may already have a giant map and be unable to fork, as for the + # /sbin/ldconfig call inside ctypes.util.find_library(). + rmmap.mmap(-1, 4096, *flags).close() + m = rmmap.mmap(-1, PIECES * PIECE_STRIDE, *flags) m.close = lambda : None # leak instead of giving a spurious # error at CPython's shutdown From noreply at buildbot.pypy.org Wed Mar 20 03:53:36 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 20 Mar 2013 03:53:36 +0100 (CET) Subject: [pypy-commit] buildbot default: cleanup/simplify nightly builds Message-ID: <20130320025336.BF1831C1016@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r741:a1031d3f1833 Date: 2013-03-19 22:49 -0400 http://bitbucket.org/pypy/buildbot/changeset/a1031d3f1833/ Log: cleanup/simplify nightly builds diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -17,10 +17,10 @@ # translations in parallel, but then the actual benchmarks are run in # sequence. -# there are 8 logical CPUs, but only 4 physical ones -TannitCPU = locks.MasterLock('tannit_cpu', maxCount=6) +# there are 8 logical CPUs, but only 4 physical ones, and only enough memory for 2 translations +TannitCPU = locks.MasterLock('tannit_cpu', maxCount=2) SpeedPythonCPU = locks.MasterLock('speed_python_cpu', maxCount=24) -WinLockCPU = locks.MasterLock('win_cpu', maxCount=1) +#WinLockCPU = locks.MasterLock('win_cpu', maxCount=1) # The cross translation machine can accomodate 2 jobs at the same time ARMCrossLock = locks.SlaveLock('arm_cpu', maxCount=2) diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -48,7 +48,7 @@ pypybuilds = load('pypybuildbot.builds') TannitCPU = pypybuilds.TannitCPU -WinLockCPU = pypybuilds.WinLockCPU +#WinLockCPU = pypybuilds.WinLockCPU ARMCrossLock = pypybuilds.ARMCrossLock ARMBoardLock = pypybuilds.ARMBoardLock ARMXdistLock = pypybuilds.ARMXdistLock @@ -280,7 +280,13 @@ #JITBENCH64_2, # on speed.python.org, uses 1 core (in part exclusively) #CPYTHON_64, # on speed.python.org, uses 1 core (in part exclusively) # linux tests - LINUX32, # on allegro32, uses 20 (twenty!) core + LINUX32, # on tannit32, uses all cores + LINUX64, # on allegro64, uses all cores + JITLINUX32, # on tannit32, uses 1 core + JITLINUX64, # on allegro64, uses 1 core + APPLVLLINUX32, # on tannit32, uses 1 core + APPLVLLINUX64, # on allegro64, uses 1 core + OJITLINUX32, # on tannit32, uses 1 core # other platforms MACOSX32, # on minime JITWIN32, # on aurora @@ -289,46 +295,31 @@ JITMACOSX64, # on mvt's machine ], branch=None, hour=0, minute=0), - Nightly("nightly-0-45", [ - LINUX64, # on allegro64, uses 20 (twenty!) cores - ], branch=None, hour=0, minute=45), - - Nightly("nightly-2-15-py3k", [ - LINUX64, # on allegro64, uses 20 (twenty!) cores - ], branch="py3k", hour=2, minute=15), - - Nightly("nightly-3-00", [ - JITLINUX32, # on allegro32, uses 1 core - JITLINUX64, # on allegro64, uses 1 core - OJITLINUX32, # on allegro32, uses 1 core - APPLVLLINUX32, # on allegro32, uses 1 core - APPLVLLINUX64, # on allegro64, uses 1 core - ], branch=None, hour=3, minute=0), - - Nightly("nightly-3-30", [ + Nightly("nightly-2-00", [ JITBENCH, # on tannit32, uses 1 core (in part exclusively) JITBENCH64, # on tannit64, uses 1 core (in part exclusively) - ], branch=None, hour=3, minute=30), + ], branch=None, hour=2, minute=0), - Nightly("nightly-4-00-py3k", [ - #APPLVLLINUX32, # on allegro32, uses 1 core + Nightly("nightly-2-00-py3k", [ + LINUX64, # on allegro64, uses all cores + #APPLVLLINUX32, # on tannit32, uses 1 core APPLVLLINUX64, # on allegro64, uses 1 core - ], branch="py3k", hour=4, minute=0), + ], branch="py3k", hour=2, minute=0), - # Nightly("nighly-ppc", [ JITONLYLINUXPPC64, # on gcc1 ], branch='ppc-jit-backend', hour=1, minute=0), - # + Nightly("nighly-arm-0-00", [ BUILDLINUXARM, # on hhu-cross-armel, uses 1 core BUILDJITLINUXARM, # on hhu-cross-armel, uses 1 core JITBACKENDONLYLINUXARMEL, # on hhu-beagleboard or hhu-imx.53 ], branch=None, hour=0, minute=0), - # + Triggerable("APPLVLLINUXARM_scheduler", [ APPLVLLINUXARM, # triggered by BUILDLINUXARM, on hhu-beagleboard or hhu-imx.53 - ]), + ]), + Triggerable("JITLINUXARM_scheduler", [ JITLINUXARM, # triggered by BUILDJITLINUXARM, on hhu-beagleboard or hhu-imx.53 ]), @@ -374,7 +365,7 @@ }, {"name": LIBPYTHON_LINUX32, "slavenames": ["tannit32"], -# "slavenames": ["allegro32"], + #"slavenames": ["allegro32"], "builddir": LIBPYTHON_LINUX32, "factory": pypyTranslatedLibPythonTestFactory, 'category': 'linux32', @@ -474,7 +465,7 @@ 'builddir' : JITWIN32, 'factory' : pypyJITTranslatedTestFactoryWin, 'category' : 'win32', - "locks": [WinLockCPU.access('exclusive')], + "locks": [TannitCPU.access('counting')], }, {"name" : JITWIN64, "slavenames": ["snakepit64"], From noreply at buildbot.pypy.org Wed Mar 20 06:48:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 20 Mar 2013 06:48:16 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup unmap/unmapview/unmap_range, skip unmap_range test on non-posix Message-ID: <20130320054816.BAC411C14B7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62542:16d366c59499 Date: 2013-03-20 01:42 -0400 http://bitbucket.org/pypy/pypy/changeset/16d366c59499/ Log: cleanup unmap/unmapview/unmap_range, skip unmap_range test on non- posix diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -287,20 +287,26 @@ self.data = data self.size = size - def unmap_range(self, offset, size): - """Unmap (a portion of) the mapped range. POSIX only. + def unmap(self): + if _MS_WINDOWS: + UnmapViewOfFile(self.getptr(0)) + elif _POSIX: + self.unmap_range(0, self.size) - Per munmap(1), the offset must be a multiple of the page size, - and the size will be rounded up to a multiple of the page size. - """ - assert _POSIX - return c_munmap_safe(self.getptr(offset), size) + if _POSIX: + def unmap_range(self, offset, size): + """Unmap (a portion of) the mapped range. + + Per munmap(1), the offset must be a multiple of the page size, + and the size will be rounded up to a multiple of the page size. + """ + c_munmap_safe(self.getptr(offset), size) def close(self): + if self.size > 0: + self.unmap() + self.setdata(NODATA, 0) if _MS_WINDOWS: - if self.size > 0: - self.unmapview() - self.setdata(NODATA, 0) if self.map_handle != INVALID_HANDLE: rwin32.CloseHandle(self.map_handle) self.map_handle = INVALID_HANDLE @@ -315,16 +321,10 @@ # underlaying close error code os.close(self.fd) self.fd = -1 - if self.size > 0: - self.unmap_range(0, self.size) - self.setdata(NODATA, 0) def __del__(self): self.close() - def unmapview(self): - UnmapViewOfFile(self.getptr(0)) - def read_byte(self): self.check_valid() @@ -536,7 +536,7 @@ self.setdata(newdata, newsize) elif _MS_WINDOWS: # disconnect the mapping - self.unmapview() + self.unmap() rwin32.CloseHandle(self.map_handle) # move to the desired EOF position diff --git a/rpython/rlib/test/test_rmmap.py b/rpython/rlib/test/test_rmmap.py --- a/rpython/rlib/test/test_rmmap.py +++ b/rpython/rlib/test/test_rmmap.py @@ -65,8 +65,9 @@ f.close() - def test_unmap(self): - f = open(self.tmpname + "-unmap", "w+") + @py.test.mark.skipif("os.name != 'posix'") + def test_unmap_range(self): + f = open(self.tmpname + "-unmap-range", "w+") left, right, size = 100, 200, 500 # in pages f.write(size*4096*"c") From noreply at buildbot.pypy.org Wed Mar 20 09:02:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 20 Mar 2013 09:02:10 +0100 (CET) Subject: [pypy-commit] pypy default: undo this cleanup from last commit, doesn't match cpython Message-ID: <20130320080210.8E6281C14B0@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62543:9f087c4339f8 Date: 2013-03-20 04:01 -0400 http://bitbucket.org/pypy/pypy/changeset/9f087c4339f8/ Log: undo this cleanup from last commit, doesn't match cpython diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -303,10 +303,10 @@ c_munmap_safe(self.getptr(offset), size) def close(self): - if self.size > 0: - self.unmap() - self.setdata(NODATA, 0) if _MS_WINDOWS: + if self.size > 0: + self.unmap() + self.setdata(NODATA, 0) if self.map_handle != INVALID_HANDLE: rwin32.CloseHandle(self.map_handle) self.map_handle = INVALID_HANDLE @@ -321,6 +321,9 @@ # underlaying close error code os.close(self.fd) self.fd = -1 + if self.size > 0: + self.unmap() + self.setdata(NODATA, 0) def __del__(self): self.close() From noreply at buildbot.pypy.org Wed Mar 20 11:44:30 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 11:44:30 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: fix test Message-ID: <20130320104430.896261C04AB@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: remove-list-smm Changeset: r62544:a21cd56a8f5b Date: 2013-03-20 11:42 +0100 http://bitbucket.org/pypy/pypy/changeset/a21cd56a8f5b/ Log: fix test diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -566,7 +566,7 @@ space = self.space w_l = W_ListObject(space, [space.wrap(1), space.wrap(2), space.wrap(3)]) w_l.pop = None - w_res = listobject.list_pop__List_ANY(space, w_l, space.w_None) # does not crash + w_res = w_l.descr_pop(space) assert space.unwrap(w_res) == 3 def test_create_list_from_set(self): From noreply at buildbot.pypy.org Wed Mar 20 12:06:53 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 12:06:53 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: share code between find, contains and remove Message-ID: <20130320110653.ED0F61C13F4@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: remove-list-smm Changeset: r62545:7806a754f7d9 Date: 2013-03-20 12:06 +0100 http://bitbucket.org/pypy/pypy/changeset/7806a754f7d9/ Log: share code between find, contains and remove 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 @@ -209,10 +209,10 @@ strategy and storage according to the other W_List""" self.strategy.copy_into(self, other) - def contains(self, w_obj): - """Returns unwrapped boolean, saying wether w_obj exists - in the list.""" - return self.strategy.contains(self, w_obj) + + def find(self, w_item, start=0, end=maxint): + """Find w_item in list[start:end]. If not found, raise ValueError""" + return self.strategy.find(self, w_item, start, end) def append(self, w_item): 'L.append(object) -- append object to end' @@ -378,15 +378,14 @@ def descr_remove(self, space, w_value): 'L.remove(value) -- remove first occurrence of value' # needs to be safe against eq_w() mutating the w_list behind our back - i = 0 - while i < self.length(): - if space.eq_w(self.getitem(i), w_value): - if i < self.length(): # if this is wrong the list was changed - self.pop(i) - return space.w_None - i += 1 - raise OperationError(space.w_ValueError, - space.wrap("list.remove(x): x not in list")) + try: + i = self.find(w_value, 0, maxint) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("list.remove(x): x not in list")) + if i < self.length(): # otherwise list was mutated + self.pop(i) + return space.w_None @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(maxint)) def descr_index(self, space, w_value, w_start, w_stop): @@ -396,12 +395,12 @@ size = self.length() i, stop = slicetype.unwrap_start_stop( space, size, w_start, w_stop, True) - while i < stop and i < self.length(): - if space.eq_w(self.getitem(i), w_value): - return space.wrap(i) - i += 1 - raise OperationError(space.w_ValueError, - space.wrap("list.index(x): x not in list")) + try: + i = self.find(w_value, i, stop) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("list.index(x): x not in list")) + return space.wrap(i) @unwrap_spec(reverse=bool) def descr_sort(self, space, w_cmp=None, w_key=None, reverse=False): @@ -498,14 +497,15 @@ def _resize_hint(self, w_list, hint): raise NotImplementedError - def contains(self, w_list, w_obj): - # needs to be safe against eq_w() mutating the w_list behind our back - i = 0 - while i < w_list.length(): # intentionally always calling len! - if self.space.eq_w(w_list.getitem(i), w_obj): - return True + def find(self, w_list, w_item, start, stop): + space = self.space + i = start + # needs to be safe against eq_w mutating stuff + while i < stop and i < w_list.length(): + if space.eq_w(w_list.getitem(i), w_item): + return i i += 1 - return False + raise ValueError def length(self, w_list): raise NotImplementedError @@ -631,8 +631,8 @@ if hint: w_list.strategy = SizeListStrategy(self.space, hint) - def contains(self, w_list, w_obj): - return False + def find(self, w_list, w_item, start, stop): + raise ValueError def length(self, w_list): return 0 @@ -786,17 +786,19 @@ w_other.strategy = self w_other.lstorage = w_list.lstorage - def contains(self, w_list, w_obj): + def find(self, w_list, w_obj, startindex, stopindex): if is_W_IntObject(w_obj): + obj = self.unwrap(w_obj) start, step, length = self.unerase(w_list.lstorage) - obj = self.unwrap(w_obj) - if step > 0 and start <= obj <= start + (length - 1) * step and (start - obj) % step == 0: - return True - elif step < 0 and start + (length - 1) * step <= obj <= start and (start - obj) % step == 0: - return True + if ((step > 0 and start <= obj <= start + (length - 1) * step and (start - obj) % step == 0) or + (step < 0 and start + (length - 1) * step <= obj <= start and (start - obj) % step == 0)): + index = (obj - start) // step else: - return False - return ListStrategy.contains(self, w_list, w_obj) + raise ValueError + if startindex <= index < stopindex: + return index + raise ValueError + return ListStrategy.find(self, w_list, w_obj, startindex, stopindex) def length(self, w_list): return self.unerase(w_list.lstorage)[2] @@ -972,17 +974,18 @@ items = self.unerase(w_list.lstorage)[:] w_other.lstorage = self.erase(items) - def contains(self, w_list, w_obj): + def find(self, w_list, w_obj, start, stop): if self.is_correct_type(w_obj): - return self._safe_contains(w_list, self.unwrap(w_obj)) - return ListStrategy.contains(self, w_list, w_obj) + return self._safe_find(w_list, self.unwrap(w_obj), start, stop) + return ListStrategy.find(self, w_list, w_obj, start, stop) - def _safe_contains(self, w_list, obj): + def _safe_find(self, w_list, obj, start, stop): l = self.unerase(w_list.lstorage) - for i in l: - if i == obj: - return True - return False + for i in range(start, min(stop, len(l))): + val = l[i] + if val == obj: + return i + raise ValueError def length(self, w_list): return len(self.unerase(w_list.lstorage)) @@ -1224,8 +1227,8 @@ def clear(self, w_list): w_list.lstorage = self.erase([]) - def contains(self, w_list, w_obj): - return ListStrategy.contains(self, w_list, w_obj) + def find(self, w_list, w_obj, start, stop): + return ListStrategy.find(self, w_list, w_obj, start, stop) def getitems(self, w_list): return self.unerase(w_list.lstorage) @@ -1408,7 +1411,11 @@ w_list.deleteslice(start, 1, stop-start) def contains__List_ANY(space, w_list, w_obj): - return space.wrap(w_list.contains(w_obj)) + try: + w_list.find(w_obj) + return space.w_True + except ValueError: + return space.w_False def iter__List(space, w_list): from pypy.objspace.std import iterobject diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1,4 +1,5 @@ # coding: iso-8859-15 +import py import random from pypy.objspace.std.listobject import W_ListObject, SizeListStrategy,\ IntegerListStrategy, ObjectListStrategy @@ -406,6 +407,19 @@ assert isinstance(w_lst.strategy, SizeListStrategy) assert w_lst.strategy.sizehint == 13 + def test_find_fast_on_intlist(self, monkeypatch): + monkeypatch.setattr(self.space, "eq_w", None) + w = self.space.wrap + intlist = W_ListObject(self.space, [w(1),w(2),w(3),w(4),w(5),w(6),w(7)]) + res = intlist.find(w(4), 0, 7) + assert res == 3 + res = intlist.find(w(4), 0, 100) + assert res == 3 + with py.test.raises(ValueError): + intlist.find(w(4), 4, 7) + with py.test.raises(ValueError): + intlist.find(w(4), 0, 2) + class AppTestW_ListObject(object): def setup_class(cls): import sys From noreply at buildbot.pypy.org Wed Mar 20 14:18:40 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 14:18:40 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: spent some time trying to find out why stuff doesn't translate Message-ID: <20130320131840.EC8961C019F@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: remove-list-smm Changeset: r62546:85e644c3af16 Date: 2013-03-20 14:17 +0100 http://bitbucket.org/pypy/pypy/changeset/85e644c3af16/ Log: spent some time trying to find out why stuff doesn't translate 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 @@ -1666,6 +1666,9 @@ list(sequence) -> new list initialized from sequence's items""", __new__ = interp2app(descr_new), __hash__ = None, + # XXX this cannot work, within the methods the annotation of 'self' is W_Root + # the reason why it works in modules is that there all classes inherit from Wrappable + # see gateway.UnwrapSpec_EmitRun.visit__Wrappable vs visit__W_Root sort = interp2app(W_ListObject.descr_sort), index = interp2app(W_ListObject.descr_index), append = interp2app(W_ListObject.append), From noreply at buildbot.pypy.org Wed Mar 20 14:23:52 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 14:23:52 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: this test is also broken due to the comment of the previous commit Message-ID: <20130320132352.83C221C03A7@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: remove-list-smm Changeset: r62547:872b9628821a Date: 2013-03-20 14:23 +0100 http://bitbucket.org/pypy/pypy/changeset/872b9628821a/ Log: this test is also broken due to the comment of the previous commit diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1290,6 +1290,9 @@ l1[:] = l2 assert len(l1) == 0 + def test_use_method_for_wrong_object(self): + raises(TypeError, list.append.im_func, 1, 2) + class AppTestForRangeLists(AppTestW_ListObject): spaceconfig = {"objspace.std.withrangelist": True} From noreply at buildbot.pypy.org Wed Mar 20 14:44:24 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Mar 2013 14:44:24 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: changed perform to not suffer from StackOverflow Errors Message-ID: <20130320134424.160D21C03A7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r223:967479e64bc4 Date: 2013-03-20 14:20 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/967479e64bc4/ Log: changed perform to not suffer from StackOverflow Errors fixed the bootstrapped-tests fixed a flaky test among the shadow tests changed the starting method lookup class for DNU diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -69,6 +69,7 @@ while s_new_context is not nlr.s_target_context: s_new_context.mark_returned() s_new_context = s_sender + self.remaining_stack_depth = self.max_stack_depth s_new_context.push(nlr.value) except ProcessSwitch, p: self.remaining_stack_depth = self.max_stack_depth @@ -121,24 +122,17 @@ else: w_selector = selector - w_method = model.W_CompiledMethod() - w_method.setbytes([chr(124)]) #returnTopFromMethod + w_method = model.W_CompiledMethod(header=512) + w_method.literalatput0(self.space, 1, w_selector) + assert len(arguments_w) <= 7 + w_method.setbytes([chr(131), chr(len(arguments_w) << 5 + 0), chr(124)]) #returnTopFromMethod s_method = w_method.as_compiledmethod_get_shadow(self.space) s_frame = MethodContextShadow.make_context( self.space, s_method, w_receiver, [], None) s_frame.push(w_receiver) s_frame.push_all(list(arguments_w)) try: - try: - s_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self) - except Return, nlr: - s_new_frame = nlr.s_target_context - nlr.s_target_context.push(nlr.value) - if s_new_frame is None: - # which means that we tried to call a primitive method - return s_frame.pop() - else: - self.loop(s_new_frame.w_self()) + self.loop(s_frame.w_self()) except ReturnFromTopLevel, e: return e.object @@ -296,7 +290,7 @@ w_message.store(self.space, 0, w_selector) w_message.store(self.space, 1, self.space.wrap_list(arguments)) try: - s_method = receiverclassshadow.lookup(self.space.objtable["w_doesNotUnderstand"]) + s_method = receiver.shadow_of_my_class(self.space).lookup(self.space.objtable["w_doesNotUnderstand"]) except MethodNotFound: print "Missing doesDoesNotUnderstand in hierarchy of %s" % receiverclassshadow.getname() raise diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -633,7 +633,9 @@ whileTrue: [self at: index put: (replacement at: repOff + index)]""" if (start < 0 or start - 1 > stop or repStart < 0): raise PrimitiveFailedError() - if w_rcvr.getclass(interp.space) is not w_replacement.getclass(interp.space): + # This test deliberately test for equal W_Object class. The Smalltalk classes + # might be different (e.g. Symbol and ByteString) + if w_rcvr.__class__ is not w_replacement.__class__: raise PrimitiveFailedError() if (w_rcvr.size() <= stop or w_replacement.size() < repStart + (stop - start)): diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -43,6 +43,7 @@ ifTrue: [ ^ sym ] ]. ^ (Symbol basicNew: self size) initFrom: self""" w_result = perform(w("someString"), "asSymbol") + assert w_result.as_string() == "someString" w_anotherSymbol = perform(w("someString"), "asSymbol") assert w_result is w_anotherSymbol diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -241,8 +241,8 @@ i = 0 key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) while key is space.w_nil: + i = i + 1 key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) - i = i + 1 assert (s_class.lookup(key) is foo.as_compiledmethod_get_shadow(space) or s_class.lookup(key) is bar.as_compiledmethod_get_shadow(space)) From noreply at buildbot.pypy.org Wed Mar 20 14:53:29 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Mar 2013 14:53:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Removed the second link of W_PointersObject s to their class. Only s_class is maintained. Message-ID: <20130320135329.E59BC1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r225:87d8824f17f5 Date: 2013-03-19 18:20 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/87d8824f17f5/ Log: Removed the second link of W_PointersObject s to their class. Only s_class is maintained. diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -154,7 +154,7 @@ class W_Float(W_Object): """Boxed float value.""" - _attrs_ = ['value'] + _attrs_ = ['value', 'space'] _immutable_fields_ = ['space'] def fillin_fromwords(self, space, high, low): @@ -258,21 +258,18 @@ class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash): """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" - _attrs_ = ['w_class', 's_class'] + _attrs_ = ['s_class', 'space'] _immutable_fields_ = ['space'] s_class = None def __init__(self, space, w_class): - if w_class is not None: # it's None only for testing and space generation + self.space = space + if w_class is not None:# it's None only for testing and space generation assert isinstance(w_class, W_PointersObject) - if w_class.has_shadow(): - self.s_class = w_class.as_class_get_shadow(w_class._shadow.space) - self.w_class = w_class - self.space = space + self.s_class = w_class.as_class_get_shadow(space) def getclass(self, space): - assert self.w_class is not None - return self.w_class + return self.s_class.w_self() def __repr__(self): return "<%s %s>" % (self.__class__.__name__, self) @@ -282,25 +279,25 @@ return self._shadow.getname() else: name = None - if self.w_class.has_shadow(): - name = self.w_class._shadow.name + if self.s_class is not None: + name = self.s_class.name return "a %s" % (name or '?',) def invariant(self): + from spyvm.shadow import ClassShadow return (W_AbstractObjectWithIdentityHash.invariant(self) and - isinstance(self.w_class, W_PointersObject)) + isinstance(self.s_class.w_self(), W_PointersObject) and + isinstance(self.s_class, ClassShadow)) def _become(self, w_other): - self.w_class, w_other.w_class = w_other.w_class, self.w_class self.s_class, w_other.s_class = w_other.s_class, self.s_class W_AbstractObjectWithIdentityHash._become(self, w_other) def has_class(self): - return self.w_class is not None + return self.s_class is not None def shadow_of_my_class(self, space): - if self.s_class is None: - self.s_class = self.w_class.as_class_get_shadow(space) + assert self.s_class is not None return self.s_class class W_PointersObject(W_AbstractObjectWithClassReference): @@ -393,6 +390,12 @@ from spyvm.shadow import ClassShadow return jit.promote(self.as_special_get_shadow(space, ClassShadow)) + def as_class_get_uninitialized_shadow(self, space): + from spyvm.shadow import ClassShadow + if self._shadow is None: + self.attach_shadow_of_class(space, ClassShadow) + return jit.promote(self._shadow) + def as_blockcontext_get_shadow(self, space): from spyvm.shadow import BlockContextShadow return self.as_special_get_shadow(space, BlockContextShadow) @@ -438,7 +441,8 @@ return True def clone(self, space): - w_result = W_PointersObject(self.space, self.w_class, len(self._vars)) + w_result = W_PointersObject(self.space, self.s_class.w_self(), + len(self._vars)) w_result._vars = [self.fetch(space, i) for i in range(len(self._vars))] return w_result @@ -490,7 +494,8 @@ return self.bytes == other.bytes def clone(self, space): - w_result = W_BytesObject(self.space, self.w_class, len(self.bytes)) + w_result = W_BytesObject(self.space, self.s_class.w_self(), + len(self.bytes)) w_result.bytes = list(self.bytes) return w_result @@ -523,7 +528,8 @@ isinstance(self.words, list)) def clone(self, space): - w_result = W_WordsObject(self.space, self.space, self.w_class, len(self.words)) + w_result = W_WordsObject(self.space, self.s_class.w_self(), + len(self.words)) w_result.words = list(self.words) return w_result diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -58,8 +58,8 @@ # at this point, all classes that still lack a w_class are themselves # metaclasses for nm, w_cls_obj in self.classtable.items(): - if w_cls_obj.w_class is None: - w_cls_obj.w_class = w_Metaclass + if w_cls_obj.s_class is None: + w_cls_obj.s_class = w_Metaclass.as_class_get_shadow(self) def define_cls(cls_nm, supercls_nm, instvarsize=0, format=shadow.POINTERS, varsized=False): @@ -134,7 +134,7 @@ # initialize their fields to nil, we have to create it in the model # package, and then patch up its fields here: w_nil = self.w_nil = model.w_nil - w_nil.w_class = self.classtable['w_UndefinedObject'] + w_nil.s_class = self.classtable['w_UndefinedObject'].as_class_get_shadow(self) w_true = self.classtable['w_True'].as_class_get_shadow(self).new() self.w_true = w_true diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -647,7 +647,6 @@ if w_arg_class.instsize() != w_rcvr_class.instsize(): raise PrimitiveFailedError() - w_rcvr.w_class = w_arg.w_class w_rcvr.s_class = w_arg.s_class # ___________________________________________________________________________ diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -45,12 +45,15 @@ def attach_shadow(self): self.w_self().store_shadow(self) - self.update() def update(self): """This should get called whenever the base Smalltalk object changes.""" - self.sync_cache() + w_self = self.w_self() + if isinstance(w_self, model.W_PointersObject): + if w_self.size() == 0: + return + return self.sync_cache() def sync_cache(self): raise NotImplementedError() @@ -102,8 +105,6 @@ "Update the ClassShadow with data from the w_self class." w_self = self.w_self() - if w_self.size() == 0: - return # read and painfully decode the format try: @@ -350,8 +351,6 @@ self.invalid = True def sync_cache(self): - if self.w_self().size() == 0: - return w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX) assert isinstance(w_values, model.W_PointersObject) s_values = w_values.as_observed_get_shadow(self.space) diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -305,6 +305,8 @@ for chunk in self.chunks.itervalues(): casted = chunk.g_object.w_object if isinstance(casted, model.W_PointersObject) and casted.has_shadow(): + assert hasattr(casted, '_vars') + assert casted.size() != 0 casted._shadow.update() def init_compactclassesarray(self): @@ -533,8 +535,7 @@ w_pointersobject._vars = [g_object.w_object for g_object in self.pointers] w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) - w_pointersobject.w_class = w_class - w_pointersobject.s_class = None + w_pointersobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space) w_pointersobject.hash = self.chunk.hash12 def fillin_floatobject(self, w_floatobject): @@ -551,13 +552,13 @@ w_wordsobject.words = [r_uint(x) for x in self.chunk.data] w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) - w_wordsobject.w_class = w_class + w_wordsobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space) w_wordsobject.hash = self.chunk.hash12 # XXX check this def fillin_bytesobject(self, w_bytesobject): w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) - w_bytesobject.w_class = w_class + w_bytesobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space) w_bytesobject.bytes = self.get_bytes() w_bytesobject.hash = self.chunk.hash12 # XXX check this diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py --- a/spyvm/test/test_objectspace.py +++ b/spyvm/test/test_objectspace.py @@ -8,11 +8,11 @@ # Heuristic to detect if this is a metaclass. Don't use apart # from in this test file, because classtable['w_Metaclass'] is # bogus after loading an image. - return w_cls.w_class is space.classtable['w_Metaclass'] + return w_cls.s_class.w_self() is space.classtable['w_Metaclass'] def test_every_class_is_an_instance_of_a_metaclass(): for (nm, w_cls) in space.classtable.items(): - assert ismetaclass(w_cls) or ismetaclass(w_cls.w_class) + assert ismetaclass(w_cls) or ismetaclass(w_cls.s_class.w_self()) def test_every_metaclass_inherits_from_class_and_behavior(): s_Class = space.classtable['w_Class'].as_class_get_shadow(space) @@ -25,7 +25,7 @@ def test_metaclass_of_metaclass_is_an_instance_of_metaclass(): w_Metaclass = space.classtable['w_Metaclass'] - assert w_Metaclass.w_class.w_class is w_Metaclass + assert w_Metaclass.s_class.w_self().s_class.w_self() is w_Metaclass def test_ruint(): """ diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -19,7 +19,7 @@ s_self.reset_stack() s_self.push_all(stack) s_self.store_expected_argument_count(0) - self.w_class = space.w_MethodContext + self.s_class = space.w_MethodContext.as_class_get_shadow(space) def as_blockcontext_get_shadow(self): self._shadow = shadow.BlockContextShadow(space, self) diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -32,7 +32,7 @@ w_classofclass=None, methods={}): if w_classofclass is None: w_classofclass = build_smalltalk_class(None, 0x94, - w_superclass.w_class, + w_superclass.s_class.w_self(), w_Metaclass) w_methoddict = build_methoddict(methods) size = constants.CLASS_NAME_INDEX + 1 From noreply at buildbot.pypy.org Wed Mar 20 14:53:28 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Mar 2013 14:53:28 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added the space a w_object is created for to that object Message-ID: <20130320135328.A18B91C03A7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r224:256cc8aa5d3f Date: 2013-03-14 00:13 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/256cc8aa5d3f/ Log: added the space a w_object is created for to that object the only exception is W_SmallInteger diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -121,7 +121,7 @@ else: w_selector = selector - w_method = model.W_CompiledMethod() + w_method = model.W_CompiledMethod(self.space) w_method.setbytes([chr(124)]) #returnTopFromMethod s_method = w_method.as_compiledmethod_get_shadow(self.space) s_frame = MethodContextShadow.make_context( diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -155,6 +155,7 @@ class W_Float(W_Object): """Boxed float value.""" _attrs_ = ['value'] + _immutable_fields_ = ['space'] def fillin_fromwords(self, space, high, low): from rpython.rlib.rstruct.ieee import float_unpack @@ -162,7 +163,8 @@ r = (r_ulonglong(high) << 32) | low self.value = float_unpack(r, 8) - def __init__(self, value): + def __init__(self, space, value): + self.space = space self.value = value def getclass(self, space): @@ -257,14 +259,16 @@ """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or Float).""" _attrs_ = ['w_class', 's_class'] + _immutable_fields_ = ['space'] s_class = None - def __init__(self, w_class): + def __init__(self, space, w_class): if w_class is not None: # it's None only for testing and space generation assert isinstance(w_class, W_PointersObject) if w_class.has_shadow(): self.s_class = w_class.as_class_get_shadow(w_class._shadow.space) self.w_class = w_class + self.space = space def getclass(self, space): assert self.w_class is not None @@ -306,9 +310,9 @@ _shadow = None # Default value @jit.unroll_safe - def __init__(self, w_class, size): + def __init__(self, space, w_class, size): """Create new object with size = fixed + variable size.""" - W_AbstractObjectWithClassReference.__init__(self, w_class) + W_AbstractObjectWithClassReference.__init__(self, space, w_class) vars = self._vars = [None] * size for i in range(size): # do it by hand for the JIT's sake vars[i] = w_nil @@ -434,15 +438,15 @@ return True def clone(self, space): - w_result = W_PointersObject(self.w_class, len(self._vars)) + w_result = W_PointersObject(self.space, self.w_class, len(self._vars)) w_result._vars = [self.fetch(space, i) for i in range(len(self._vars))] return w_result class W_BytesObject(W_AbstractObjectWithClassReference): _attrs_ = ['bytes'] - def __init__(self, w_class, size): - W_AbstractObjectWithClassReference.__init__(self, w_class) + def __init__(self, space, w_class, size): + W_AbstractObjectWithClassReference.__init__(self, space, w_class) assert isinstance(size, int) self.bytes = ['\x00'] * size @@ -486,15 +490,15 @@ return self.bytes == other.bytes def clone(self, space): - w_result = W_BytesObject(self.w_class, len(self.bytes)) + w_result = W_BytesObject(self.space, self.w_class, len(self.bytes)) w_result.bytes = list(self.bytes) return w_result class W_WordsObject(W_AbstractObjectWithClassReference): _attrs_ = ['words'] - def __init__(self, w_class, size): - W_AbstractObjectWithClassReference.__init__(self, w_class) + def __init__(self, space, w_class, size): + W_AbstractObjectWithClassReference.__init__(self, space, w_class) self.words = [r_uint(0)] * size def at0(self, space, index0): @@ -519,7 +523,7 @@ isinstance(self.words, list)) def clone(self, space): - w_result = W_WordsObject(self.w_class, len(self.words)) + w_result = W_WordsObject(self.space, self.space, self.w_class, len(self.words)) w_result.words = list(self.words) return w_result @@ -549,7 +553,7 @@ _shadow = None # Default value _likely_methodname = "" - def __init__(self, bytecount=0, header=0): + def __init__(self, space, bytecount=0, header=0): self._shadow = None self.setheader(header) self.bytes = ["\x00"] * bytecount diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -123,7 +123,7 @@ w_cinst.store(self, constants.CHARACTER_VALUE_INDEX, model.W_SmallInteger(i)) return w_cinst - w_charactertable = model.W_PointersObject( + w_charactertable = model.W_PointersObject(self, self.classtable['w_Array'], 256) self.w_charactertable = w_charactertable for i in range(256): @@ -144,7 +144,7 @@ self.w_zero = model.W_SmallInteger(0) self.w_one = model.W_SmallInteger(1) self.w_two = model.W_SmallInteger(2) - w_special_selectors = model.W_PointersObject( + w_special_selectors = model.W_PointersObject(self, self.classtable['w_Array'], len(constants.SPECIAL_SELECTORS) * 2) self.w_special_selectors = w_special_selectors @@ -182,13 +182,13 @@ import math bytes_len = int(math.log(val) / math.log(0xff)) + 1 bytes_len = 4 if 4 > bytes_len else bytes_len - w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len) + w_result = model.W_BytesObject(self, self.classtable['w_LargePositiveInteger'], bytes_len) for i in range(bytes_len): w_result.setchar(i, chr(intmask((val >> i*8) & 255))) return w_result def wrap_float(self, i): - return model.W_Float(i) + return model.W_Float(self, i) def wrap_string(self, string): w_inst = self.w_String.as_class_get_shadow(self).new(len(string)) @@ -288,7 +288,7 @@ def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): from spyvm import model - w_class = model.W_PointersObject(w_metaclass, 0) + w_class = model.W_PointersObject(space, w_metaclass, 0) # a dummy placeholder for testing # XXX s = instantiate(shadow.ClassShadow) diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -511,7 +511,7 @@ @expose_primitive(NEW_METHOD, unwrap_spec=[object, int, int]) def func(interp, s_frame, w_class, bytecount, header): # We ignore w_class because W_CompiledMethod is special - w_method = model.W_CompiledMethod(bytecount, header) + w_method = model.W_CompiledMethod(interp.space, bytecount, header) return w_method # ___________________________________________________________________________ diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -194,13 +194,13 @@ def new(self, extrasize=0): w_cls = self.w_self() if self.instance_kind == POINTERS: - w_new = model.W_PointersObject(w_cls, self.instsize()+extrasize) + w_new = model.W_PointersObject(self.space, w_cls, self.instsize()+extrasize) elif self.instance_kind == WORDS: - w_new = model.W_WordsObject(w_cls, extrasize) + w_new = model.W_WordsObject(self.space, w_cls, extrasize) elif self.instance_kind == BYTES: - w_new = model.W_BytesObject(w_cls, extrasize) + w_new = model.W_BytesObject(self.space, w_cls, extrasize) elif self.instance_kind == COMPILED_METHOD: - w_new = model.W_CompiledMethod(extrasize) + w_new = model.W_CompiledMethod(self.space, extrasize) else: raise NotImplementedError(self.instance_kind) return w_new @@ -307,8 +307,8 @@ def initialize_methoddict(self): "NOT_RPYTHON" # this is only for testing. if self._s_methoddict is None: - w_methoddict = model.W_PointersObject(None, 2) - w_methoddict._store(1, model.W_PointersObject(None, 0)) + w_methoddict = model.W_PointersObject(self.space, None, 2) + w_methoddict._store(1, model.W_PointersObject(self.space, None, 0)) self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space) self.s_methoddict().sync_cache() self.s_methoddict().invalid = False @@ -696,7 +696,7 @@ # into the right places in the W_PointersObject # XXX could hack some more to never have to create the _vars of w_result contextsize = w_home.as_methodcontext_get_shadow(space).myblocksize() - w_result = model.W_PointersObject(space.w_BlockContext, contextsize) + w_result = model.W_PointersObject(space, space.w_BlockContext, contextsize) s_result = BlockContextShadow(space, w_result) s_result_non_fresh = s_result # XXX: find a better solution to translation err s_result = jit.hint(s_result, access_directly=True, fresh_virtualizable=True) diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -506,6 +506,7 @@ self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" + self.w_object.space = self.space return self.w_object def fillin_w_object(self): diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -40,7 +40,7 @@ # Install faked compiled methods that just invoke the primitive: for (w_class, primnum, argsize, methname) in methods: s_class = w_class.as_class_get_shadow(space) - prim_meth = model.W_CompiledMethod(0) + prim_meth = model.W_CompiledMethod(space, 0) prim_meth.primitive = primnum prim_meth.argsize = argsize symbol = fakesymbol(methname) @@ -89,17 +89,17 @@ def new_frame(bytes, receiver=space.w_nil, space=space): assert isinstance(bytes, str) - w_method = model.W_CompiledMethod(len(bytes)) + w_method = model.W_CompiledMethod(space, len(bytes)) w_method.islarge = 1 w_method.bytes = bytes w_method.argsize=2 w_method.tempsize=8 - w_method.setliterals([model.W_PointersObject(None, 2)]) + w_method.setliterals([model.W_PointersObject(space, None, 2)]) s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, receiver, ["foo", "bar"]) return s_frame.w_self(), s_frame def test_create_frame(): - w_method = model.W_CompiledMethod(len("hello")) + w_method = model.W_CompiledMethod(space, len("hello")) w_method.bytes="hello" w_method.islarge = 1 w_method.argsize=2 @@ -415,7 +415,7 @@ (returnNil, space.w_nil), (returnTopFromMethod, space.w_one) ]: shadow = w_class.as_class_get_shadow(space) - w_method = model.W_CompiledMethod(2) + w_method = model.W_CompiledMethod(space, 2) w_method.bytes = pushConstantOneBytecode + bytecode literals = fakeliterals(space, "foo") w_foo = literals[0] @@ -444,7 +444,7 @@ def test_fibWithArgument(): bytecode = ''.join(map(chr, [ 16, 119, 178, 154, 118, 164, 11, 112, 16, 118, 177, 224, 112, 16, 119, 177, 224, 176, 124 ])) shadow = mockclass(space, 0).as_class_get_shadow(space) - method = model.W_CompiledMethod(len(bytecode)) + method = model.W_CompiledMethod(space, len(bytecode)) method.literalsize = 1 method.bytes = bytecode method.argsize = 1 @@ -585,7 +585,7 @@ def test_callPrimitiveAndPush_fallback(): w_frame, s_frame = new_frame(bytecodePrimAdd) shadow = mockclass(space, 0).as_class_get_shadow(space) - w_method = model.W_CompiledMethod(0) + w_method = model.W_CompiledMethod(space, 0) w_method.argsize = 1 w_method.tempsize = 1 w_method.literalsize = 1 @@ -632,18 +632,18 @@ # first call method installed in w_class bytecodes = singleExtendedSendBytecode + chr(0) # which does a call to its super - meth1 = model.W_CompiledMethod(2) + meth1 = model.W_CompiledMethod(space, 2) meth1.bytes = pushReceiverBytecode + bytecode literals = fakeliterals(space, "foo") foo = literals[0] meth1.setliterals(literals) w_class.as_class_get_shadow(space).installmethod(foo, meth1) # and that one again to its super - meth2 = model.W_CompiledMethod(2) + meth2 = model.W_CompiledMethod(space, 2) meth2.bytes = pushReceiverBytecode + bytecode meth2.setliterals(fakeliterals(space, foo)) w_super.as_class_get_shadow(space).installmethod(foo, meth2) - meth3 = model.W_CompiledMethod(0) + meth3 = model.W_CompiledMethod(space, 0) w_supersuper.as_class_get_shadow(space).installmethod(foo, meth3) w_frame, s_frame = new_frame(bytecodes) s_frame.w_method().setliterals(literals) @@ -834,7 +834,7 @@ # ^ self objectAt: 2. yields the first literal (22) # ^ self objectAt: 2 put: 3. changes the first literal to 3 # ^ self objectAt: 2. yields the new first literal (3) - prim_meth = model.W_CompiledMethod(header=1024) + prim_meth = model.W_CompiledMethod(space, header=1024) prim_meth.setliterals(fakeliterals(space, 22)) oal = fakeliterals(space, "objectAt:") oalp = fakeliterals(space, "objectAt:put:", 3) @@ -975,7 +975,7 @@ 0x00, 0x11, 0x10, 0x75, 0xb6, 0x9a, 0x75, 0xa4, 0x09, 0x8c, 0x00, 0x01, 0x10, 0x76, 0xb1, 0xca, 0x10, 0xb0, 0x7d, 0x8e, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x20, 0xca, 0x7c])) - w_method = model.W_CompiledMethod(len(bytes)) + w_method = model.W_CompiledMethod(space, len(bytes)) w_method.islarge = 1 w_method.bytes = bytes w_method.argsize=0 @@ -1023,7 +1023,7 @@ 0x10, 0x76, 0xb1, 0xca, 0x10, 0xb0, 0x7d, 0x8e, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x20, 0xca, 0x7c])) - w_method = model.W_CompiledMethod(len(bytes)) + w_method = model.W_CompiledMethod(space, len(bytes)) w_method.islarge = 1 w_method.bytes = bytes w_method.argsize=0 diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -86,13 +86,13 @@ w_super = mockclass(space, 0) w_class = mockclass(space, 0, w_superclass=w_super) supershadow = w_super.as_class_get_shadow(space) - supershadow.installmethod(w_foo, model.W_CompiledMethod(0)) + supershadow.installmethod(w_foo, model.W_CompiledMethod(space, 0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() assert classshadow.lookup(w_foo).w_compiledin is w_super def test_compiledmethod_setchar(): - w_method = model.W_CompiledMethod(3) + w_method = model.W_CompiledMethod(space, 3) w_method.setchar(0, "c") assert w_method.bytes == list("c\x00\x00") @@ -108,7 +108,7 @@ assert h1 == w_inst.hash def test_compiledmethod_at0(): - w_method = model.W_CompiledMethod() + w_method = model.W_CompiledMethod(space) w_method.bytes = list("abc") w_method.header = 100 w_method.setliterals(['lit1', 'lit2']) @@ -121,7 +121,7 @@ assert space.unwrap_int(w_method.at0(space, 14)) == ord('c') def test_compiledmethod_atput0(): - w_method = model.W_CompiledMethod(3) + w_method = model.W_CompiledMethod(space, 3) newheader = joinbits([0,2,0,0,0,0],[9,8,1,6,4,1]) assert w_method.getliteralsize() == 0 w_method.atput0(space, 0, space.wrap_int(newheader)) @@ -140,37 +140,37 @@ def test_compiledmethod_atput0_not_aligned(): header = joinbits([0,2,0,0,0,0],[9,8,1,6,4,1]) - w_method = model.W_CompiledMethod(3, header) + w_method = model.W_CompiledMethod(space, 3, header) with py.test.raises(error.PrimitiveFailedError): w_method.atput0(space, 7, 'lit1') with py.test.raises(error.PrimitiveFailedError): w_method.atput0(space, 9, space.wrap_int(5)) -def test_is_same_object(w_o1=model.W_PointersObject(None,0), w_o2=None): +def test_is_same_object(w_o1=model.W_PointersObject(space, None,0), w_o2=None): if w_o2 is None: w_o2 = w_o1 assert w_o1.is_same_object(w_o2) assert w_o2.is_same_object(w_o1) -def test_not_is_same_object(w_o1=model.W_PointersObject(None,0),w_o2=model.W_PointersObject(None,0)): +def test_not_is_same_object(w_o1=model.W_PointersObject(space, None,0),w_o2=model.W_PointersObject(space, None,0)): assert not w_o1.is_same_object(w_o2) assert not w_o2.is_same_object(w_o1) w_o2 = model.W_SmallInteger(2) assert not w_o1.is_same_object(w_o2) assert not w_o2.is_same_object(w_o1) - w_o2 = model.W_Float(5.5) + w_o2 = model.W_Float(space, 5.5) assert not w_o1.is_same_object(w_o2) assert not w_o2.is_same_object(w_o1) def test_intfloat_is_same_object(): test_is_same_object(model.W_SmallInteger(1), model.W_SmallInteger(1)) test_is_same_object(model.W_SmallInteger(100), model.W_SmallInteger(100)) - test_is_same_object(model.W_Float(1.100), model.W_Float(1.100)) + test_is_same_object(model.W_Float(space, 1.100), model.W_Float(space, 1.100)) def test_intfloat_notis_same_object(): - test_not_is_same_object(model.W_SmallInteger(1), model.W_Float(1)) - test_not_is_same_object(model.W_Float(100), model.W_SmallInteger(100)) - test_not_is_same_object(model.W_Float(1.100), model.W_Float(1.200)) + test_not_is_same_object(model.W_SmallInteger(1), model.W_Float(space, 1)) + test_not_is_same_object(model.W_Float(space, 100), model.W_SmallInteger(100)) + test_not_is_same_object(model.W_Float(space, 1.100), model.W_Float(space, 1.200)) test_not_is_same_object(model.W_SmallInteger(101), model.W_SmallInteger(100)) def test_charis_same_object(): @@ -220,7 +220,7 @@ def test_word_atput(): i = model.W_SmallInteger(100) - b = model.W_WordsObject(None, 1) + b = model.W_WordsObject(space, None, 1) b.atput0(space, 0, i) assert 100 == b.getword(0) i = space.classtable['w_LargePositiveInteger'].as_class_get_shadow(space).new(4) @@ -229,7 +229,7 @@ assert b.getword(0) == 3221225472 def test_word_at(): - b = model.W_WordsObject(None, 1) + b = model.W_WordsObject(space, None, 1) b.setword(0, 100) r = b.at0(space, 0) assert isinstance(r, model.W_SmallInteger) @@ -241,7 +241,7 @@ assert r.size() == 4 def test_float_at(): - b = model.W_Float(64.0) + b = model.W_Float(space, 64.0) r = b.fetch(space, 0) assert isinstance(r, model.W_BytesObject) assert r.size() == 4 @@ -251,9 +251,9 @@ assert r.value == 0 def test_float_at_put(): - target = model.W_Float(1.0) + target = model.W_Float(space, 1.0) for f in [1.0, -1.0, 1.1, 64.4, -0.0, float('nan'), float('inf')]: - source = model.W_Float(f) + source = model.W_Float(space, f) target.store(space, 0, source.fetch(space, 0)) target.store(space, 1, source.fetch(space, 1)) if math.isnan(f): diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -230,7 +230,7 @@ def test_size_of_compiled_method(): literalsize = 3 bytecount = 3 - w_cm = model.W_CompiledMethod(bytecount) + w_cm = model.W_CompiledMethod(space, bytecount) w_cm.literalsize = literalsize assert prim(primitives.SIZE, [w_cm]).value == (literalsize+1)*constants.BYTES_PER_WORD + bytecount diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -36,7 +36,7 @@ w_Metaclass) w_methoddict = build_methoddict(methods) size = constants.CLASS_NAME_INDEX + 1 - w_class = model.W_PointersObject(w_classofclass, size) + w_class = model.W_PointersObject(space, w_classofclass, size) w_class.store(space, constants.CLASS_SUPERCLASS_INDEX, w_superclass) w_class.store(space, constants.CLASS_METHODDICT_INDEX, w_methoddict) w_class.store(space, constants.CLASS_FORMAT_INDEX, space.wrap_int(format)) @@ -66,8 +66,8 @@ yield basicshape, "CompiledMeth", 0xE02, shadow.COMPILED_METHOD, True, 0 def test_methoddict(): - methods = {'foo': model.W_CompiledMethod(0), - 'bar': model.W_CompiledMethod(0)} + methods = {'foo': model.W_CompiledMethod(space, 0), + 'bar': model.W_CompiledMethod(space, 0)} w_class = build_smalltalk_class("Demo", 0x90, methods=methods) classshadow = w_class.as_class_get_shadow(space) methoddict = classshadow.s_methoddict().methoddict @@ -76,7 +76,7 @@ assert methods[w_key.as_string()].as_compiledmethod_get_shadow(space) is value def method(tempsize=3,argsize=2, bytes="abcde"): - w_m = model.W_CompiledMethod() + w_m = model.W_CompiledMethod(space) w_m.bytes = bytes w_m.tempsize = tempsize w_m.argsize = argsize @@ -85,7 +85,7 @@ def methodcontext(w_sender=space.w_nil, pc=1, stackpointer=0, stacksize=5, method=method()): - w_object = model.W_PointersObject(space.w_MethodContext, constants.MTHDCTX_TEMP_FRAME_START+method.tempsize+stacksize) + w_object = model.W_PointersObject(space, space.w_MethodContext, constants.MTHDCTX_TEMP_FRAME_START+method.tempsize+stacksize) w_object.store(space, constants.CTXPART_SENDER_INDEX, w_sender) w_object.store(space, constants.CTXPART_PC_INDEX, space.wrap_int(pc)) w_object.store(space, constants.CTXPART_STACKP_INDEX, space.wrap_int(method.tempsize+stackpointer)) @@ -99,7 +99,7 @@ def blockcontext(w_sender=space.w_nil, pc=1, stackpointer=1, stacksize=5, home=methodcontext()): - w_object = model.W_PointersObject(space.w_MethodContext, constants.MTHDCTX_TEMP_FRAME_START+stacksize) + w_object = model.W_PointersObject(space, space.w_MethodContext, constants.MTHDCTX_TEMP_FRAME_START+stacksize) w_object.store(space, constants.CTXPART_SENDER_INDEX, w_sender) w_object.store(space, constants.CTXPART_PC_INDEX, space.wrap_int(pc)) w_object.store(space, constants.CTXPART_STACKP_INDEX, space.wrap_int(stackpointer)) @@ -180,7 +180,7 @@ from test_model import joinbits header = joinbits([0,2,0,1,0,0],[9,8,1,6,4,1]) - w_compiledmethod = model.W_CompiledMethod(3, header) + w_compiledmethod = model.W_CompiledMethod(space, 3, header) w_compiledmethod.setbytes(list("abc")) shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abc" @@ -229,9 +229,9 @@ def test_cached_methoddict(): # create a methoddict - foo = model.W_CompiledMethod(0) - bar = model.W_CompiledMethod(0) - baz = model.W_CompiledMethod(0) + foo = model.W_CompiledMethod(space, 0) + bar = model.W_CompiledMethod(space, 0) + baz = model.W_CompiledMethod(space, 0) methods = {'foo': foo, 'bar': bar} w_class = build_smalltalk_class("Demo", 0x90, methods=methods) @@ -241,8 +241,8 @@ i = 0 key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) while key is space.w_nil: + i = i + 1 key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i) - i = i + 1 assert (s_class.lookup(key) is foo.as_compiledmethod_get_shadow(space) or s_class.lookup(key) is bar.as_compiledmethod_get_shadow(space)) @@ -250,19 +250,18 @@ w_array = s_class.w_methoddict()._fetch(constants.METHODDICT_VALUES_INDEX) version = s_class.version w_array.atput0(space, i, baz) - assert s_class.lookup(key) is baz.as_compiledmethod_get_shadow(space) assert version is not s_class.version def test_updating_class_changes_subclasses(): w_parent = build_smalltalk_class("Demo", 0x90, - methods={'bar': model.W_CompiledMethod(0)}) + methods={'bar': model.W_CompiledMethod(space, 0)}) w_class = build_smalltalk_class("Demo", 0x90, - methods={'foo': model.W_CompiledMethod(0)}, w_superclass=w_parent) + methods={'foo': model.W_CompiledMethod(space, 0)}, w_superclass=w_parent) s_class = w_class.as_class_get_shadow(space) version = s_class.version - w_method = model.W_CompiledMethod(0) + w_method = model.W_CompiledMethod(space, 0) key = space.wrap_string('foo') s_md = w_parent.as_class_get_shadow(space).s_methoddict() diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py --- a/spyvm/test/test_wrapper.py +++ b/spyvm/test/test_wrapper.py @@ -10,7 +10,7 @@ return new_frame_tuple("")[0] def test_simpleread(): - w_o = model.W_PointersObject(None, 2) + w_o = model.W_PointersObject(space, None, 2) w = wrapper.Wrapper(space, w_o) w_o._vars[0] = "hello" assert w.read(0) == "hello" @@ -20,7 +20,7 @@ py.test.raises(WrapperException, "w.write(2, \"test\")") def test_accessor_generators(): - w_o = model.W_PointersObject(None, 1) + w_o = model.W_PointersObject(space, None, 1) w = wrapper.LinkWrapper(space, w_o) w_o._vars[0] = "hello" assert w.next_link() == "hello" @@ -28,12 +28,12 @@ assert w.next_link() == "boe" def link(w_next='foo'): - w_object = model.W_PointersObject(None, 1) + w_object = model.W_PointersObject(space, None, 1) wrapper.LinkWrapper(space, w_object).store_next_link(w_next) return w_object def test_linked_list(): - w_object = model.W_PointersObject(None,2) + w_object = model.W_PointersObject(space, None,2) w_last = link(space.w_nil) w_lb1 = link(w_last) w_lb2 = link(w_lb1) @@ -72,7 +72,7 @@ w_suspended_context=space.w_nil, priority=0): w_priority = space.wrap_int(priority) - w_process = model.W_PointersObject(None, 4) + w_process = model.W_PointersObject(space, None, 4) process = wrapper.ProcessWrapper(space, w_process) process.store_next_link(w_next) process.store_my_list(w_my_list) @@ -81,7 +81,7 @@ return process def new_processlist(processes_w=[]): - w_processlist = model.W_PointersObject(None, 2) + w_processlist = model.W_PointersObject(space, None, 2) w_first = space.w_nil w_last = space.w_nil for w_process in processes_w[::-1]: @@ -99,7 +99,7 @@ else: maxpriority = 5 prioritydict = {} - w_prioritylist = model.W_PointersObject(None, maxpriority) + w_prioritylist = model.W_PointersObject(space, None, maxpriority) prioritylist = wrapper.Wrapper(space, w_prioritylist) for i in range(maxpriority): prioritylist.write(i, new_processlist(prioritydict.get(i, []))._w_self) @@ -108,14 +108,14 @@ def new_scheduler(w_process=space.w_nil, prioritydict=None): priority_list = new_prioritylist(prioritydict) - w_scheduler = model.W_PointersObject(None, 2) + w_scheduler = model.W_PointersObject(space, None, 2) scheduler = wrapper.SchedulerWrapper(space, w_scheduler) scheduler.store_active_process(w_process) scheduler.write(0, priority_list._w_self) return scheduler def new_semaphore(excess_signals=0): - w_semaphore = model.W_PointersObject(None, 3) + w_semaphore = model.W_PointersObject(space, None, 3) semaphore = wrapper.SemaphoreWrapper(space, w_semaphore) semaphore.store_excess_signals(excess_signals) return semaphore From noreply at buildbot.pypy.org Wed Mar 20 14:53:31 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Mar 2013 14:53:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: some small changes to make squeakimage.py compilable Message-ID: <20130320135331.13DB11C03A7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r226:e152443ebaf9 Date: 2013-03-19 18:48 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/e152443ebaf9/ Log: some small changes to make squeakimage.py compilable diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -305,7 +305,6 @@ for chunk in self.chunks.itervalues(): casted = chunk.g_object.w_object if isinstance(casted, model.W_PointersObject) and casted.has_shadow(): - assert hasattr(casted, '_vars') assert casted.size() != 0 casted._shadow.update() @@ -508,7 +507,6 @@ self.w_object = objectmodel.instantiate(model.W_CompiledMethod) else: assert 0, "not reachable" - self.w_object.space = self.space return self.w_object def fillin_w_object(self): @@ -532,6 +530,7 @@ def fillin_pointersobject(self, w_pointersobject): assert self.pointers is not None + w_pointersobject.space = self.space w_pointersobject._vars = [g_object.w_object for g_object in self.pointers] w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) @@ -540,6 +539,7 @@ def fillin_floatobject(self, w_floatobject): from rpython.rlib.rarithmetic import r_uint + w_floatobject.space = self.space words = [r_uint(x) for x in self.chunk.data] if len(words) != 2: raise CorruptImageError("Expected 2 words in Float, got %d" % len(words)) @@ -549,6 +549,7 @@ def fillin_wordsobject(self, w_wordsobject): from rpython.rlib.rarithmetic import r_uint + w_wordsobject.space = self.space w_wordsobject.words = [r_uint(x) for x in self.chunk.data] w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) @@ -556,6 +557,7 @@ w_wordsobject.hash = self.chunk.hash12 # XXX check this def fillin_bytesobject(self, w_bytesobject): + w_bytesobject.space = self.space w_class = self.g_class.w_object assert isinstance(w_class, model.W_PointersObject) w_bytesobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space) @@ -583,6 +585,7 @@ return bytes[:stop] # omit odd bytes def fillin_compiledmethod(self, w_compiledmethod): + w_compiledmethod.space = self.space header = self.chunk.data[0] w_compiledmethod.setheader(header>>1) # We untag before giving header for i in range(1,w_compiledmethod.literalsize+1): From noreply at buildbot.pypy.org Wed Mar 20 14:53:32 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Mar 2013 14:53:32 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merged with local branch without any of their changes, because mecurial makes it really hard to loose(remove) commits Message-ID: <20130320135332.314671C03A7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r227:a9faabe07327 Date: 2013-03-20 14:53 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a9faabe07327/ Log: merged with local branch without any of their changes, because mecurial makes it really hard to loose(remove) commits From noreply at buildbot.pypy.org Wed Mar 20 16:31:40 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:40 +0100 (CET) Subject: [pypy-commit] lang-js default: added array benchmarks Message-ID: <20130320153140.2C13A1C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r361:4cd3183a5d9e Date: 2013-02-27 20:05 +0100 http://bitbucket.org/pypy/lang-js/changeset/4cd3183a5d9e/ Log: added array benchmarks diff --git a/bench/array/run.js b/bench/array/run.js new file mode 100644 --- /dev/null +++ b/bench/array/run.js @@ -0,0 +1,107 @@ +function _run(name, func) { + var d = Date.now(); + func(); + print(name + ': ' + (Date.now() - d)); +} + +var max_a = 1000000; + +function array1() { + var x = 0; + var a = []; + while(x < max_a) { + a[x] = x; + x += 1; + } + return a; +} + +function array2() { + var x = 0; + var a = []; + while(x < max_a) { + a[x*2] = x; + x += 1; + } + return a; +} + +function array3() { + var x = 0; + var a = []; + while(x < max_a) { + var idx = Math.floor(Math.random() * max_a); + a[idx] = idx; + x += 1; + } + return a; +} + +function array4() { + var x = 0; + var a = []; + while(x < max_a) { + a.push(x); + x += 1; + } + x = 0; + while(x < max_a) { + a.pop(); + x += 1; + } + return a; +} + +function array5() { + var x = 0; + var a = []; + while(x < max_a) { + a.push(x); + x += 1; + } + x = 0; + while(x < max_a) { + a.pop(); + x += 1; + } + return a; +} + +function array6() { + var x = 0; + var a = []; + while(x < 100) { + while(a.length < max_a) { + a.push(x); + } + while(a.length > 0) { + a.pop(); + } + x += 1; + } + return a; +} + +function arrayXXX() { + var x = 0; + var a = []; + var b = []; + while(x < 100) { + a[x] = x; + x += 1; + } + x = 0; + while(a.length > 0) { + var a_idx = Math.floor(Math.random() * a.length); + var b_idx = a.splice(a_idx, 1); + b[b_idx] = b_idx; + } + return b; +} + +_run('array1', array1); +_run('array2', array2); +_run('array3', array3); +_run('array4', array4); +_run('array5', array5); +//_run('array6', array6); From noreply at buildbot.pypy.org Wed Mar 20 16:31:41 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:41 +0100 (CET) Subject: [pypy-commit] lang-js default: back array by dict Message-ID: <20130320153141.6822E1C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r362:6bb16769d0c0 Date: 2013-02-27 20:06 +0100 http://bitbucket.org/pypy/lang-js/changeset/6bb16769d0c0/ Log: back array by dict access array with integer index diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -12,10 +12,39 @@ @jit.elidable def is_array_index(p): - try: - return unicode(str(uint32(abs(int(str(p)))))) == p - except ValueError: - return False + return make_array_index(p) != NOT_ARRAY_INDEX + + +NOT_ARRAY_INDEX = -1 + + +def _get_from_desc(desc, this): + from js.object_space import newundefined + if desc is None: + return newundefined() + + if is_data_descriptor(desc): + return desc.value + + if desc.has_set_getter() is False: + return newundefined() + + getter = desc.getter + res = getter.Call(this=this) + return res + + + at jit.unroll_safe +def make_array_index(idx): + if len(idx) == 0: + return -1 + + IDX_LIT = '0123456789' + + for c in idx: + if c not in IDX_LIT: + return NOT_ARRAY_INDEX + return int(idx) @jit.elidable @@ -163,13 +192,18 @@ jit.promote(proto_desc) - at jit.elidable def reject(throw, msg=u''): if throw: raise JsTypeError(msg) return False +def _ireject(throw, idx): + if throw: + raise JsTypeError(unicode(str(idx))) + return False + + class W_BasicObject(W_Root): _type_ = 'object' _class_ = 'Object' @@ -200,22 +234,14 @@ # 8.12.3 def get(self, p): - from js.object_space import newundefined assert p is not None and isinstance(p, unicode) desc = self.get_property(p) - if desc is None: - return newundefined() + return _get_from_desc(desc, self) - if is_data_descriptor(desc): - return desc.value - - if desc.has_set_getter() is False: - return newundefined() - - getter = desc.getter - res = getter.Call(this=self) - return res + def w_get(self, w_p): + name = w_p.to_string() + return self.get(name) # 8.12.1 def get_own_property(self, p): @@ -282,8 +308,8 @@ def put(self, p, v, throw=False): assert p is not None and isinstance(p, unicode) - if self.can_put(p) is False: - if throw is True: + if not self.can_put(p): + if throw: raise JsTypeError(u"can't put %s" % (p, )) else: return @@ -303,6 +329,10 @@ new_desc = DataPropertyDescriptor(v, True, True, True) self.define_own_property(p, new_desc, throw) + def w_put(self, w_p, v, throw=False): + name = w_p.to_string() + self.put(name, v, throw) + # 8.12.4 def can_put(self, p): from js.object_space import isundefined, isnull_or_undefined @@ -1252,12 +1282,307 @@ _class_ = 'Array' def __init__(self, length=w_0): + self._array_props_ = {} + #self._array_props_ = [] + W_BasicObject.__init__(self) assert isinstance(length, W_Root) desc = PropertyDescriptor(value=length, writable=True, enumerable=False, configurable=False) W_BasicObject.define_own_property(self, u'length', desc) + ####### dict + def _add_prop(self, name, value): + idx = make_array_index(name) + if idx != NOT_ARRAY_INDEX: + self._add_iprop(idx, value) + else: + W_BasicObject._add_prop(self, name, value) + + def _add_iprop(self, idx, value): + assert isinstance(idx, int) + self._array_props_[idx] = value + + def _get_prop(self, name): + idx = make_array_index(name) + if idx != NOT_ARRAY_INDEX: + return self._get_iprop(idx) + else: + return W_BasicObject._get_prop(self, name) + + def _get_iprop(self, idx): + assert isinstance(idx, int) + assert idx >= 0 + return self._array_props_.get(idx, None) + + def _set_prop(self, name, value): + idx = make_array_index(name) + if idx != NOT_ARRAY_INDEX: + self._set_iprop(idx, value) + else: + W_BasicObject._set_prop(self, name, value) + + def _set_iprop(self, idx, value): + assert isinstance(idx, int) + assert idx >= 0 + self._array_props_[idx] = value + + def _del_prop(self, name): + idx = make_array_index(name) + if idx != NOT_ARRAY_INDEX: + self._del_iprop(idx) + else: + W_BasicObject._del_prop(self, name) + + def _del_iprop(self, idx): + assert isinstance(idx, int) + assert idx >= 0 + try: + del self._array_props_[idx] + except KeyError: + pass + + def _named_properties_dict(self): + from js.object_space import isnull_or_undefined + my_d = {} + for i in self._array_props_.keys(): + my_d[unicode(str(i))] = None + + for i in self._property_map_.keys(): + my_d[i] = None + + proto = self.prototype() + if not isnull_or_undefined(proto): + assert isinstance(proto, W_BasicObject) + proto_d = proto._named_properties_dict() + else: + proto_d = {} + + my_d.update(proto_d) + + return my_d + + def _get_idx_property(self, idx): + from js.object_space import isnull + + prop = self._get_own_idx_property(idx) + if prop is not None: + return prop + + proto = self.prototype() + if isnull(proto): + return None + + if isinstance(proto, W__Array): + return proto._get_idx_property(idx) + + assert isinstance(proto, W_BasicObject) + p = unicode(str(idx)) + return proto.get_property(p) + + def w_get(self, w_p): + if isinstance(w_p, W_IntNumber): + idx = w_p.ToInteger() + if idx >= 0: + desc = self._get_idx_property(idx) + return _get_from_desc(desc, self) + + return W_BasicObject.w_get(self, w_p) + + def w_put(self, w_p, v, throw=False): + if isinstance(w_p, W_IntNumber): + idx = w_p.ToInteger() + if idx >= 0: + if not self._can_idx_put(idx): + if throw: + raise JsTypeError(u"can't put %s" % (str(idx), )) + else: + return + + own_desc = self._get_own_idx_property(idx) + if is_data_descriptor(own_desc) is True: + value_desc = PropertyDescriptor(value=v) + self._define_own_idx_property(idx, value_desc, throw) + return + + desc = self._get_idx_property(idx) + if is_accessor_descriptor(desc) is True: + setter = desc.setter + assert setter is not None + setter.Call(this=self, args=[v]) + + else: + new_desc = DataPropertyDescriptor(v, True, True, True) + self._define_own_idx_property(idx, new_desc, throw) + + else: + W_BasicObject.w_put(self, w_p, v, throw) + + def _can_idx_put(self, idx): + from js.object_space import isundefined, isnull_or_undefined + desc = self._get_own_idx_property(idx) + if desc is not None: + if is_accessor_descriptor(desc) is True: + if isundefined(desc.setter): + return False + else: + return True + return desc.writable + + proto = self.prototype() + + if isnull_or_undefined(proto): + return self.extensible() + + assert isinstance(proto, W_BasicObject) + + if isinstance(proto, W__Array): + inherited = proto._get_idx_property(idx) + else: + p = unicode(str(idx)) + inherited = proto.get_property(p) + + if inherited is None: + return self.extensible() + + if is_accessor_descriptor(inherited) is True: + if isundefined(inherited.setter): + return False + else: + return True + else: + if self.extensible() is False: + return False + else: + return inherited.writable + + def _define_own_idx_property(self, idx, desc, throw=False): + from js.object_space import _w + old_len_desc = self.get_own_property(u'length') + assert old_len_desc is not None + old_len = old_len_desc.value.ToUInt32() + + # a + index = idx + # b + if index >= old_len and old_len_desc.writable is False: + return _ireject(throw, idx) + + # c + succeeded = self._define_own_int_property(idx, desc, False) + # d + if succeeded is False: + return _ireject(throw, idx) + + # e + if index >= old_len: + old_len_desc.value = _w(index + 1) + res = W_BasicObject.define_own_property(self, u'length', old_len_desc, False) + assert res is True + # f + return True + + def _define_own_int_property(self, idx, desc, throw=False): + current = self._get_own_idx_property(idx) + extensible = self.extensible() + + # 3. + if current is None and extensible is False: + return _ireject(throw, idx) + + # 4. + if current is None and extensible is True: + # 4.a + if is_generic_descriptor(desc) or is_data_descriptor(desc): + new_prop = DataProperty( + desc.value, + desc.writable, + desc.enumerable, + desc.configurable + ) + self._add_iprop(idx, new_prop) + # 4.b + else: + assert is_accessor_descriptor(desc) is True + new_prop = AccessorProperty( + desc.getter, + desc.setter, + desc.enumerable, + desc.configurable + ) + self._add_iprop(idx, new_prop) + # 4.c + return True + + # 5. + if desc.is_empty(): + return True + + # 6. + if desc == current: + return True + + # 7. + if current.configurable is False: + if desc.configurable is True: + return _ireject(throw, idx) + if desc.has_set_enumerable() and (not(current.enumerable) == desc.enumerable): + return _ireject(throw, idx) + + # 8. + if is_generic_descriptor(desc): + pass + # 9. + elif is_data_descriptor(current) != is_data_descriptor(desc): + # 9.a + if current.configurable is False: + return _ireject(throw, idx) + # 9.b + if is_data_descriptor(current): + raise NotImplementedError(self.__class__) + # 9.c + else: + raise NotImplementedError(self.__class__) + # 10 + elif is_data_descriptor(current) and is_data_descriptor(desc): + # 10.a + if current.configurable is False: + # 10.a.i + if current.writable is False and desc.writable is True: + return _ireject(throw, idx) + # 10.a.ii + if current.writable is False: + if desc.has_set_value() and desc.value != current.value: + return _ireject(throw, idx) + # 10.b + else: + pass + # 11 + elif is_accessor_descriptor(current) and is_accessor_descriptor(desc): + # 11.a + if current.configurable is False: + # 11.a.i + if desc.has_set_setter() and desc.setter != current.setter: + return _ireject(throw, idx) + # 11.a.ii + if desc.has_set_getter() and desc.getter != current.getter: + return _ireject(throw, idx) + # 12 + prop = self._get_iprop(idx) + prop.update_with_descriptor(desc) + + # 13 + return True + + def _get_own_idx_property(self, idx): + assert isinstance(idx, int) + assert idx >= 0 + prop = self._get_iprop(idx) + if prop is None: + return + + return prop.to_property_descriptor() + # 15.4.5.1 def define_own_property(self, p, desc, throw=False): from js.object_space import _w @@ -1319,27 +1644,9 @@ # 4 elif is_array_index(p): - assert p is not None and isinstance(p, unicode) + index = uint32(int(p)) + return self._define_own_idx_property(index, desc, False) - # a - index = uint32(int(p)) - # b - if index >= old_len and old_len_desc.writable is False: - return reject(throw, p) - - # c - succeeded = W_BasicObject.define_own_property(self, p, desc, False) - # d - if succeeded is False: - return reject(throw, p) - - # e - if index >= old_len: - old_len_desc.value = _w(index + 1) - res = W_BasicObject.define_own_property(self, u'length', old_len_desc, False) - assert res is True - # f - return True # 5 return W_BasicObject.define_own_property(self, p, desc, throw) diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -255,8 +255,9 @@ def eval(self, ctx): w_obj = ctx.stack_pop().ToObject() - name = ctx.stack_pop().to_string() - value = w_obj.get(name) + w_name = ctx.stack_pop() + value = w_obj.w_get(w_name) + ctx.stack_append(value) def __str__(self): @@ -502,14 +503,12 @@ def eval(self, ctx): left = ctx.stack_pop() - member = ctx.stack_pop() - name = member.to_string() - #assert isinstance(name, unicode) + w_name = ctx.stack_pop() value = ctx.stack_pop() l_obj = left.ToObject() - l_obj.put(name, value) + l_obj.w_put(w_name, value) ctx.stack_append(value) diff --git a/test/test_array.py b/test/test_array.py --- a/test/test_array.py +++ b/test/test_array.py @@ -1,19 +1,34 @@ from test.test_interp import assertv, assertp + def test_array_push(capsys): assertv("var x = []; x.push(42); x.length;", 1) assertv("var x = []; x.push(42); x[0];", 42) assertv("var x = [1,2,3]; x.push(42); x[3];", 42) assertp("var x = []; x.push(4); x.push(3); x.push(2); x.push(1); print(x)", '4,3,2,1', capsys) + def test_array_pop(): assertv("var x = [4,3,2,1]; x.pop(); x.length;", 3) assertv("var x = [4,3,2,1]; x.pop();", 1) assertv("var x = [4,3,2,1]; x.pop(); x.pop(); x.pop(); x.pop();", 4) assertv("var x = [4,3,2,1]; x.pop(); x.pop(); x.pop(); x.pop(); x.length", 0) + def test_array_length(): assertv("var x = []; x.length;", 0) - assertv("var x = [1,2,3]; x.length;", 3); - assertv("var x = []; x[0] = 1; x[1] = 2; x[2] = 3; x.length;", 3); - assertv("var x = []; x[2] = 3; x.length;", 3); + assertv("var x = [1,2,3]; x.length;", 3) + assertv("var x = []; x[0] = 1; x[1] = 2; x[2] = 3; x.length;", 3) + assertv("var x = []; x[2] = 3; x.length;", 3) + + +def test_make_array_index(): + from js.jsobj import make_array_index, NOT_ARRAY_INDEX + assert make_array_index('12345') == 12345 + assert make_array_index(u'12345') == 12345 + assert make_array_index('12a45') == NOT_ARRAY_INDEX + assert make_array_index('012345') == 12345 + assert make_array_index('') == NOT_ARRAY_INDEX + assert make_array_index(' ') == NOT_ARRAY_INDEX + assert make_array_index('x') == NOT_ARRAY_INDEX + assert make_array_index('abc123') == NOT_ARRAY_INDEX diff --git a/test/test_w_array.py b/test/test_w_array.py new file mode 100644 --- /dev/null +++ b/test/test_w_array.py @@ -0,0 +1,41 @@ +from js.jsobj import W__Array +from js.property import DataProperty +from js.object_space import _w + + +def test_array_get(): + a = W__Array() + a._set_prop(u'23', DataProperty(42, True, True, True)) + assert a.get(u'23') == 42 + + +def test_array_iprop(): + d = DataProperty(42, True, True, True) + a = W__Array() + a._set_iprop(23, d) + assert a._get_iprop(23) is d + assert a._get_prop(u'23') is d + assert a.get(u'23') == 42 + + +def test_array_w_get(): + d = DataProperty(42, True, True, True) + a = W__Array() + a._set_iprop(23, d) + assert a.w_get(_w(23)) == 42 + assert a.w_get(_w(u'23')) == 42 + + +def test_array_put(): + a = W__Array() + a.put(u'23', 42) + assert a.get(u'23') == 42 + assert a.w_get(_w(u'23')) == 42 + + +def test_array_w_put(): + a = W__Array() + a.w_put(_w(23), 42) + assert a.get(u'23') == 42 + assert a.w_get(_w(23)) == 42 + assert a.w_get(_w(u'23')) == 42 From noreply at buildbot.pypy.org Wed Mar 20 16:31:42 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:42 +0100 (CET) Subject: [pypy-commit] lang-js default: added array trace view samples Message-ID: <20130320153142.80D811C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r363:eab8506c2aed Date: 2013-02-27 20:06 +0100 http://bitbucket.org/pypy/lang-js/changeset/eab8506c2aed/ Log: added array trace view samples diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -286,3 +286,87 @@ """ self.run(code, 'aaaaaaaaaa') + + def test_array_fill(self): + code = """ + (function () { + var i = 0; + var j = []; + while(i < 10) { + j[i] = i; + i += 1; + } + return j; + })(); + """ + + self.run(code, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + def test_array_fill_2x(self): + code = """ + (function () { + var i = 0; + var j = []; + while(i < 10) { + j[i] = null; + i += 1; + } + i = 0; + while(i < 10) { + j[i] = i; + i += 1; + } + return j; + })(); + """ + + self.run(code, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + def test_array_sum(self): + code = """ + (function () { + var i = 0; + var j = []; + while(i < 10) { + j[i] = i; + i += 1; + } + i = 0; + var k = 0; + while(i < j.length) { + k += j[i]; + i += 1; + } + return k; + })(); + """ + + self.run(code, 45) + + def test_array_fill_2x_sum(self): + code = """ + (function () { + var i = 0; + var j = []; + while(i < 10) { + j[i] = null; + i += 1; + } + + i = 0; + while(i < 10) { + j[i] = i; + i += 1; + } + + i = 0; + var k = 0; + while(i < j.length) { + k += j[i]; + i += 1; + } + return k; + })(); + """ + + self.run(code, 45) From noreply at buildbot.pypy.org Wed Mar 20 16:31:43 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:43 +0100 (CET) Subject: [pypy-commit] lang-js default: optimized array index access Message-ID: <20130320153143.909EB1C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r364:856ad47ccf75 Date: 2013-02-27 23:40 +0100 http://bitbucket.org/pypy/lang-js/changeset/856ad47ccf75/ Log: optimized array index access diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -18,6 +18,14 @@ NOT_ARRAY_INDEX = -1 +class Descr(object): + def __init__(self, can_put, own, inherited, prop): + self.can_put = can_put + self.own = own + self.inherited = inherited + self.prop = prop + + def _get_from_desc(desc, this): from js.object_space import newundefined if desc is None: @@ -1393,46 +1401,64 @@ if isinstance(w_p, W_IntNumber): idx = w_p.ToInteger() if idx >= 0: - if not self._can_idx_put(idx): - if throw: - raise JsTypeError(u"can't put %s" % (str(idx), )) - else: - return + self._idx_put(idx, v, throw) + return - own_desc = self._get_own_idx_property(idx) - if is_data_descriptor(own_desc) is True: - value_desc = PropertyDescriptor(value=v) - self._define_own_idx_property(idx, value_desc, throw) - return + W_BasicObject.w_put(self, w_p, v, throw) - desc = self._get_idx_property(idx) - if is_accessor_descriptor(desc) is True: - setter = desc.setter - assert setter is not None - setter.Call(this=self, args=[v]) + def _idx_put(self, idx, v, throw): + d = self._can_idx_put(idx) + can_put = d.can_put + own_desc = d.own + inherited_desc = d.inherited + prop = d.prop - else: - new_desc = DataPropertyDescriptor(v, True, True, True) - self._define_own_idx_property(idx, new_desc, throw) + if not can_put: + if throw: + raise JsTypeError(u"can't put %s" % (str(idx), )) + else: + return + if is_data_descriptor(own_desc): + value_desc = PropertyDescriptor(value=v) + self._define_own_idx_property(idx, value_desc, throw, own_desc, prop) + return + + if own_desc is None: + desc = inherited_desc else: - W_BasicObject.w_put(self, w_p, v, throw) + desc = own_desc + + if is_accessor_descriptor(desc): + setter = desc.setter + assert setter is not None + setter.Call(this=self, args=[v]) + else: + new_desc = DataPropertyDescriptor(v, True, True, True) + self._define_own_idx_property(idx, new_desc, throw) def _can_idx_put(self, idx): from js.object_space import isundefined, isnull_or_undefined - desc = self._get_own_idx_property(idx) + prop = self._get_iprop(idx) + + if prop is None: + desc = None + else: + desc = prop.to_property_descriptor() + + #desc = self._get_own_idx_property(idx) if desc is not None: if is_accessor_descriptor(desc) is True: if isundefined(desc.setter): - return False + return Descr(False, desc, None, prop) else: - return True - return desc.writable + return Descr(True, desc, None, prop) + return Descr(desc.writable, desc, None, prop) proto = self.prototype() if isnull_or_undefined(proto): - return self.extensible() + return Descr(self.extensible(), None, None, prop) assert isinstance(proto, W_BasicObject) @@ -1443,20 +1469,20 @@ inherited = proto.get_property(p) if inherited is None: - return self.extensible() + return Descr(self.extensible(), None, None, prop) if is_accessor_descriptor(inherited) is True: if isundefined(inherited.setter): - return False + return Descr(False, None, inherited, prop) else: - return True + return Descr(True, None, inherited, prop) else: if self.extensible() is False: - return False + return Descr(False, None, inherited, prop) else: - return inherited.writable + return Descr(inherited.writable, None, inherited, prop) - def _define_own_idx_property(self, idx, desc, throw=False): + def _define_own_idx_property(self, idx, desc, throw=False, current_desc=None, prop=None): from js.object_space import _w old_len_desc = self.get_own_property(u'length') assert old_len_desc is not None @@ -1469,7 +1495,7 @@ return _ireject(throw, idx) # c - succeeded = self._define_own_int_property(idx, desc, False) + succeeded = self._define_own_int_property(idx, desc, False, current_desc, prop) # d if succeeded is False: return _ireject(throw, idx) @@ -1482,8 +1508,8 @@ # f return True - def _define_own_int_property(self, idx, desc, throw=False): - current = self._get_own_idx_property(idx) + def _define_own_int_property(self, idx, desc, throw, current_desc, prop): + current = current_desc extensible = self.extensible() # 3. @@ -1568,7 +1594,6 @@ if desc.has_set_getter() and desc.getter != current.getter: return _ireject(throw, idx) # 12 - prop = self._get_iprop(idx) prop.update_with_descriptor(desc) # 13 From noreply at buildbot.pypy.org Wed Mar 20 16:31:44 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:44 +0100 (CET) Subject: [pypy-commit] lang-js default: fixed integer to float contamination Message-ID: <20130320153144.C23581C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r365:f6a6c15c2f42 Date: 2013-03-20 16:19 +0100 http://bitbucket.org/pypy/lang-js/changeset/f6a6c15c2f42/ Log: fixed integer to float contamination diff --git a/js/baseop.py b/js/baseop.py --- a/js/baseop.py +++ b/js/baseop.py @@ -3,7 +3,7 @@ """ from js.jsobj import W_String, W_IntNumber, W_FloatNumber -from js.object_space import _w +from js.object_space import _w, isint from rpython.rlib.rarithmetic import ovfcheck from rpython.rlib.rfloat import isnan, isinf @@ -13,7 +13,7 @@ # 11.6.1, 11.6.3 -def plus(ctx, lval, rval): +def plus(lval, rval): lprim = lval.ToPrimitive() rprim = rval.ToPrimitive() @@ -22,7 +22,7 @@ sright = rprim.to_string() return W_String(sleft + sright) # hot path - if isinstance(lprim, W_IntNumber) and isinstance(rprim, W_IntNumber): + if isint(lprim) and isint(rprim): ileft = lprim.ToInteger() iright = rprim.ToInteger() try: @@ -35,11 +35,11 @@ return W_FloatNumber(fleft + fright) -def increment(ctx, nleft, constval=1): - if isinstance(nleft, W_IntNumber): +def increment(nleft, constval=1): + if isint(nleft): return W_IntNumber(nleft.ToInteger() + constval) else: - return plus(ctx, nleft, W_IntNumber(constval)) + return plus(nleft, W_IntNumber(constval)) def decrement(ctx, nleft, constval=1): @@ -50,7 +50,7 @@ def sub(ctx, nleft, nright): - if isinstance(nleft, W_IntNumber) and isinstance(nright, W_IntNumber): + if isint(nleft) and isint(nright): # XXX fff ileft = nleft.ToInt32() iright = nright.ToInt32() @@ -64,7 +64,7 @@ def mult(ctx, nleft, nright): - if isinstance(nleft, W_IntNumber) and isinstance(nright, W_IntNumber): + if isint(nleft) and isint(nright): # XXXX test & stuff ileft = nleft.ToInteger() iright = nright.ToInteger() @@ -115,7 +115,6 @@ # 11.5.2 def division(ctx, nleft, nright): - fleft = nleft.ToNumber() fright = nright.ToNumber() if isnan(fleft) or isnan(fright): @@ -143,7 +142,7 @@ def compare(ctx, x, y): - if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber): + if isint(x) and isint(y): return x.ToInteger() > y.ToInteger() if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber): if isnan(x.ToNumber()) or isnan(y.ToNumber()): @@ -164,7 +163,7 @@ def compare_e(ctx, x, y): - if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber): + if isint(x) and isint(y): return x.ToInteger() >= y.ToInteger() if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber): if isnan(x.ToNumber()) or isnan(y.ToNumber()): @@ -190,7 +189,7 @@ Implements the Abstract Equality Comparison x == y trying to be fully to the spec """ - if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber): + if isint(x) and isint(y): return x.ToInteger() == y.ToInteger() if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber): if isnan(x.ToNumber()) or isnan(y.ToNumber()): @@ -275,7 +274,7 @@ def uminus(obj, ctx): - if isinstance(obj, W_IntNumber): + if isint(obj): intval = obj.ToInteger() if intval == 0: return W_FloatNumber(-float(intval)) diff --git a/js/object_space.py b/js/object_space.py --- a/js/object_space.py +++ b/js/object_space.py @@ -2,6 +2,11 @@ from rpython.rlib import jit +def isint(w): + from js.jsobj import W_IntNumber + return isinstance(w, W_IntNumber) + + @enforceargs(int) def newint(i): from js.jsobj import W_IntNumber diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -1,7 +1,7 @@ from rpython.rlib.rarithmetic import intmask from rpython.rlib import jit -from js.object_space import _w +from js.object_space import _w, isint from js.exception import JsTypeError from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\ compare_e, increment, decrement, mult, division, uminus, mod @@ -328,7 +328,7 @@ class ADD(BaseBinaryOperation): def operation(self, ctx, left, right): - return plus(ctx, left, right) + return plus(left, right) class BITAND(BaseBinaryBitwiseOp): @@ -424,8 +424,14 @@ class UPLUS(BaseUnaryOperation): def eval(self, ctx): expr = ctx.stack_pop() - num = expr.ToNumber() - res = _w(num) + res = None + + if isint(expr): + res = expr + else: + num = expr.ToNumber() + res = _w(num) + ctx.stack_append(res) @@ -445,15 +451,21 @@ class INCR(BaseUnaryOperation): def eval(self, ctx): value = ctx.stack_pop() - num = _w(value.ToNumber()) - newvalue = increment(ctx, num) + if isint(value): + num = value + else: + num = _w(value.ToNumber()) + newvalue = increment(num) ctx.stack_append(newvalue) class DECR(BaseUnaryOperation): def eval(self, ctx): value = ctx.stack_pop() - num = _w(value.ToNumber()) + if isint(value): + num = value + else: + num = _w(value.ToNumber()) newvalue = decrement(ctx, num) ctx.stack_append(newvalue) From noreply at buildbot.pypy.org Wed Mar 20 16:31:45 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:45 +0100 (CET) Subject: [pypy-commit] lang-js default: added LOAD_MEMBER_DOT alias for LOAD_MEMBER for debugging Message-ID: <20130320153145.E467F1C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r366:2ee7cb2fc38e Date: 2013-03-20 16:20 +0100 http://bitbucket.org/pypy/lang-js/changeset/2ee7cb2fc38e/ Log: added LOAD_MEMBER_DOT alias for LOAD_MEMBER for debugging diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -264,6 +264,11 @@ return 'LOAD_MEMBER' +class LOAD_MEMBER_DOT(LOAD_MEMBER): + def __str__(self): + return 'LOAD_MEMBER_DOT' + + class COMMA(BaseUnaryOperation): def eval(self, ctx): one = ctx.stack_pop() diff --git a/js/operations.py b/js/operations.py --- a/js/operations.py +++ b/js/operations.py @@ -337,7 +337,7 @@ def emit(self, bytecode): bytecode.emit_str(self.name) self.left.emit(bytecode) - bytecode.emit('LOAD_MEMBER') + bytecode.emit('LOAD_MEMBER_DOT') class FunctionStatement(Statement): From noreply at buildbot.pypy.org Wed Mar 20 16:31:47 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:47 +0100 (CET) Subject: [pypy-commit] lang-js default: use _idx_put in LOAD_ARRAY Message-ID: <20130320153147.05D211C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r367:937cc2089ea1 Date: 2013-03-20 16:21 +0100 http://bitbucket.org/pypy/lang-js/changeset/937cc2089ea1/ Log: use _idx_put in LOAD_ARRAY diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -179,7 +179,7 @@ list_w = ctx.stack_pop_n(self.counter) # [:] # pop_n returns a non-resizable list for index, el in enumerate(list_w): - array.put(unicode(str(index)), el) + array._idx_put(index, el, False) ctx.stack_append(array) def stack_change(self): From noreply at buildbot.pypy.org Wed Mar 20 16:31:48 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:48 +0100 (CET) Subject: [pypy-commit] lang-js default: pass function name into printable location Message-ID: <20130320153148.24B6E1C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r368:d4640c906e90 Date: 2013-03-20 16:22 +0100 http://bitbucket.org/pypy/lang-js/changeset/d4640c906e90/ Log: pass function name into printable location diff --git a/js/functions.py b/js/functions.py --- a/js/functions.py +++ b/js/functions.py @@ -160,6 +160,7 @@ def __init__(self, name, js_code): assert isinstance(name, unicode) JsExecutableCode.__init__(self, js_code) + js_code._function_name_ = name self._name_ = name def name(self): diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -10,7 +10,10 @@ def get_printable_location(pc, debug, jscode): if pc < jscode._opcode_count(): opcode = jscode._get_opcode(pc) - return '%d: %s' % (pc, str(opcode)) + if jscode._function_name_ is not None: + return '%d: %s function: %s' % (pc, str(opcode), str(jscode._function_name_)) + else: + return '%d: %s' % (pc, str(opcode)) else: return '%d: %s' % (pc, 'end of opcodes') @@ -47,6 +50,7 @@ self._estimated_stack_size = -1 self._symbols = symbol_map self.parameters = symbol_map.parameters[:] + self._function_name_ = None def variables(self): return self._symbols.variables From noreply at buildbot.pypy.org Wed Mar 20 16:31:49 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:49 +0100 (CET) Subject: [pypy-commit] lang-js default: use _idx_put in array constructor Message-ID: <20130320153149.2E1641C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r369:a380e25f0db6 Date: 2013-03-20 16:23 +0100 http://bitbucket.org/pypy/lang-js/changeset/a380e25f0db6/ Log: use _idx_put in array constructor diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -1015,13 +1015,13 @@ else: length = 1 array = object_space.new_array(_w(length)) - array.put(u'0', _len) + array._idx_put(0, _len, False) return array else: array = object_space.new_array() for index, obj in enumerate(args): - array.put(unicode(str(index)), obj) + array._idx_put(index, obj, False) return array def Construct(self, args=[]): From noreply at buildbot.pypy.org Wed Mar 20 16:31:50 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:50 +0100 (CET) Subject: [pypy-commit] lang-js default: removed some annotaitons Message-ID: <20130320153150.3A9471C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r370:9e9af1fdf61d Date: 2013-03-20 16:23 +0100 http://bitbucket.org/pypy/lang-js/changeset/9e9af1fdf61d/ Log: removed some annotaitons diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -1186,7 +1186,6 @@ @enforceargs(int) - at jit.elidable def int32(n): if n & (1 << (32 - 1)): res = n | ~MASK_32 @@ -1197,13 +1196,11 @@ @enforceargs(int) - at jit.elidable def uint32(n): return n & MASK_32 @enforceargs(int) - at jit.elidable def uint16(n): return n & MASK_16 From noreply at buildbot.pypy.org Wed Mar 20 16:31:51 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Wed, 20 Mar 2013 16:31:51 +0100 (CET) Subject: [pypy-commit] lang-js default: added float jit viewer test Message-ID: <20130320153151.6A4FB1C14FC@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r371:642c59a0ffd5 Date: 2013-03-20 16:24 +0100 http://bitbucket.org/pypy/lang-js/changeset/642c59a0ffd5/ Log: added float jit viewer test diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -48,6 +48,20 @@ self.run(code, 100) + def test_float_loop(self): + code = """ + function f() { + var i = 0; + while(i < 100) { + i += 0.1; + } + return i; + } + return f(); + """ + + self.run(code, 100) + def test_prop_loop_in_func(self): code = """ function f() { From noreply at buildbot.pypy.org Wed Mar 20 16:52:40 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 16:52:40 +0100 (CET) Subject: [pypy-commit] pypy default: fix typo Message-ID: <20130320155240.17F2E1C03A7@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62548:4f5882ea651d Date: 2013-03-18 22:30 +0100 http://bitbucket.org/pypy/pypy/changeset/4f5882ea651d/ Log: fix typo diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -172,17 +172,17 @@ self._lazy_setfields_and_arrayitems = [] self._remove_guard_not_invalidated = False self._seen_guard_not_invalidated = False - self.posponedop = None + self.postponed_op = None def force_at_end_of_preamble(self): self.force_all_lazy_setfields_and_arrayitems() def flush(self): self.force_all_lazy_setfields_and_arrayitems() - if self.posponedop: - posponedop = self.posponedop - self.posponedop = None - self.next_optimization.propagate_forward(posponedop) + if self.postponed_op: + postponed_op = self.postponed_op + self.postponed_op = None + self.next_optimization.propagate_forward(postponed_op) def new(self): return OptHeap() @@ -230,13 +230,13 @@ def emit_operation(self, op): self.emitting_operation(op) - if self.posponedop: - posponedop = self.posponedop - self.posponedop = None - self.next_optimization.propagate_forward(posponedop) + if self.postponed_op: + postponed_op = self.postponed_op + self.postponed_op = None + self.next_optimization.propagate_forward(postponed_op) if (op.is_comparison() or op.getopnum() == rop.CALL_MAY_FORCE or op.is_ovf()): - self.posponedop = op + self.postponed_op = op else: Optimization.emit_operation(self, op) diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py --- a/rpython/jit/metainterp/optimizeopt/pure.py +++ b/rpython/jit/metainterp/optimizeopt/pure.py @@ -5,7 +5,7 @@ class OptPure(Optimization): def __init__(self): - self.posponedop = None + self.postponed_op = None self.pure_operations = args_dict() self.emitted_pure_operations = {} @@ -15,12 +15,12 @@ def optimize_default(self, op): canfold = op.is_always_pure() if op.is_ovf(): - self.posponedop = op + self.postponed_op = op return - if self.posponedop: + if self.postponed_op: nextop = op - op = self.posponedop - self.posponedop = None + op = self.postponed_op + self.postponed_op = None canfold = nextop.getopnum() == rop.GUARD_NO_OVERFLOW else: nextop = None @@ -83,10 +83,10 @@ self.emit_operation(op) def flush(self): - assert self.posponedop is None + assert self.postponed_op is None def new(self): - assert self.posponedop is None + assert self.postponed_op is None return OptPure() def setup(self): From noreply at buildbot.pypy.org Wed Mar 20 16:52:41 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 16:52:41 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130320155241.5EED81C03A7@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62549:9b711f742ce4 Date: 2013-03-20 16:41 +0100 http://bitbucket.org/pypy/pypy/changeset/9b711f742ce4/ Log: merge diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -172,17 +172,17 @@ self._lazy_setfields_and_arrayitems = [] self._remove_guard_not_invalidated = False self._seen_guard_not_invalidated = False - self.posponedop = None + self.postponed_op = None def force_at_end_of_preamble(self): self.force_all_lazy_setfields_and_arrayitems() def flush(self): self.force_all_lazy_setfields_and_arrayitems() - if self.posponedop: - posponedop = self.posponedop - self.posponedop = None - self.next_optimization.propagate_forward(posponedop) + if self.postponed_op: + postponed_op = self.postponed_op + self.postponed_op = None + self.next_optimization.propagate_forward(postponed_op) def new(self): return OptHeap() @@ -230,13 +230,13 @@ def emit_operation(self, op): self.emitting_operation(op) - if self.posponedop: - posponedop = self.posponedop - self.posponedop = None - self.next_optimization.propagate_forward(posponedop) + if self.postponed_op: + postponed_op = self.postponed_op + self.postponed_op = None + self.next_optimization.propagate_forward(postponed_op) if (op.is_comparison() or op.getopnum() == rop.CALL_MAY_FORCE or op.is_ovf()): - self.posponedop = op + self.postponed_op = op else: Optimization.emit_operation(self, op) diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py --- a/rpython/jit/metainterp/optimizeopt/pure.py +++ b/rpython/jit/metainterp/optimizeopt/pure.py @@ -5,7 +5,7 @@ class OptPure(Optimization): def __init__(self): - self.posponedop = None + self.postponed_op = None self.pure_operations = args_dict() self.emitted_pure_operations = {} @@ -15,12 +15,12 @@ def optimize_default(self, op): canfold = op.is_always_pure() if op.is_ovf(): - self.posponedop = op + self.postponed_op = op return - if self.posponedop: + if self.postponed_op: nextop = op - op = self.posponedop - self.posponedop = None + op = self.postponed_op + self.postponed_op = None canfold = nextop.getopnum() == rop.GUARD_NO_OVERFLOW else: nextop = None @@ -83,10 +83,10 @@ self.emit_operation(op) def flush(self): - assert self.posponedop is None + assert self.postponed_op is None def new(self): - assert self.posponedop is None + assert self.postponed_op is None return OptPure() def setup(self): From noreply at buildbot.pypy.org Wed Mar 20 17:48:23 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Mar 2013 17:48:23 +0100 (CET) Subject: [pypy-commit] pypy default: apparently kwargs.setdefault is a thing people use (e.g. the pylib) Message-ID: <20130320164823.EE3E41C03A7@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62550:80dedbfdeecb Date: 2013-03-20 17:40 +0100 http://bitbucket.org/pypy/pypy/changeset/80dedbfdeecb/ Log: apparently kwargs.setdefault is a thing people use (e.g. the pylib) diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py --- a/pypy/objspace/std/kwargsdict.py +++ b/pypy/objspace/std/kwargsdict.py @@ -72,9 +72,17 @@ values_w.append(w_value) def setdefault(self, w_dict, w_key, w_default): - # XXX could do better, but is it worth it? - self.switch_to_object_strategy(w_dict) - return w_dict.setdefault(w_key, w_default) + space = self.space + if self.is_correct_type(w_key): + key = self.unwrap(w_key) + w_result = self.getitem_str(w_dict, key) + if w_result is not None: + return w_result + self.setitem_str(w_dict, key, w_default) + return w_default + else: + self.switch_to_object_strategy(w_dict) + return w_dict.setdefault(w_key, w_default) def delitem(self, w_dict, w_key): # XXX could do better, but is it worth it? diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py --- a/pypy/objspace/std/test/test_kwargsdict.py +++ b/pypy/objspace/std/test/test_kwargsdict.py @@ -146,3 +146,16 @@ assert dict.fromkeys(f(a=2, b=3)) == {"a": None, "b": None} assert sorted(f(a=2, b=3).itervalues()) == [2, 3] + + def test_setdefault(self): + def f(**args): + return args + d = f(a=1, b=2) + a = d.setdefault("a", 0) + assert a == 1 + a = d.setdefault("b", 0) + assert a == 2 + a = d.setdefault("c", 3) + assert a == 3 + assert "KwargsDictStrategy" in self.get_strategy(d) + From noreply at buildbot.pypy.org Wed Mar 20 18:34:55 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 18:34:55 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: some whitespace Message-ID: <20130320173455.EAF8F1C03A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62551:c89ecff7b525 Date: 2013-03-20 10:34 -0700 http://bitbucket.org/pypy/pypy/changeset/c89ecff7b525/ Log: some whitespace diff --git a/pypy/objspace/std/multimethod.py b/pypy/objspace/std/multimethod.py --- a/pypy/objspace/std/multimethod.py +++ b/pypy/objspace/std/multimethod.py @@ -32,10 +32,10 @@ def get_w_value(self, space): return None - + def get_w_type(self, space): return None - + def __str__(self): return '' @@ -47,13 +47,13 @@ def get_w_value(self, space): # convenience: same semantics as with OperationError return self.w_value - + def get_w_type(self, space): return self.w_type def __str__(self): return '' % (self.w_type, self.w_value) - + def raiseFailedToImplement(): @@ -108,9 +108,9 @@ if installer.is_empty(): return None else: - return installer.install() - - + return installer.install() + + # ____________________________________________________________ # limited dict-like interface to the dispatch table @@ -176,7 +176,7 @@ self.non_empty = self.build_tree([], multimethod.dispatch_tree) self.baked_perform_call = baked_perform_call - + if self.non_empty: perform = [(None, prefix, 0)] else: @@ -353,18 +353,18 @@ bodylines.append('') source = '\n'.join(bodylines) - # XXX find a better place (or way) to avoid duplicate functions + # XXX find a better place (or way) to avoid duplicate functions l = miniglobals.items() l.sort() l = tuple(l) key = (source, l) - try: + try: func = self.mmfunccache[key] - except KeyError: + except KeyError: exec compile2(source) in miniglobals func = miniglobals[funcname] - self.mmfunccache[key] = func - #else: + self.mmfunccache[key] = func + #else: # print "avoided duplicate function", func self.to_install.append((target, funcname, func, source, fallback)) return func @@ -791,7 +791,7 @@ if '_mixin_' not in base.__dict__: result |= baseclasses(base) return result - + bag = baseclasses(classlist[0]) for cls in classlist[1:]: bag &= baseclasses(cls) @@ -959,6 +959,7 @@ miniglobals['__name__'] = __name__ entry = FuncEntry(bodylines, miniglobals, fallback) key = entry.key() + try: entry = self.mmfunccache[key] except KeyError: From noreply at buildbot.pypy.org Wed Mar 20 19:54:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 19:54:34 +0100 (CET) Subject: [pypy-commit] buildbot default: use xerxes Message-ID: <20130320185434.48C561C03A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r742:bc921d1e6a36 Date: 2013-03-20 11:53 -0700 http://bitbucket.org/pypy/buildbot/changeset/bc921d1e6a36/ Log: use xerxes diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -435,7 +435,7 @@ "category": 'mac32' }, {"name" : JITMACOSX64, - "slavenames": ["joushou-slave"], + "slavenames": ["xerxes"], 'builddir' : JITMACOSX64, 'factory' : pypyJITTranslatedTestFactoryOSX64, 'category' : 'mac64', From noreply at buildbot.pypy.org Wed Mar 20 20:14:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 20:14:27 +0100 (CET) Subject: [pypy-commit] pypy default: make namedtuple fast Message-ID: <20130320191427.C4F2F1C03A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62552:8bd3b5c5365d Date: 2013-03-20 12:14 -0700 http://bitbucket.org/pypy/pypy/changeset/8bd3b5c5365d/ Log: make namedtuple fast diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -12,6 +12,10 @@ import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from itertools import imap as _imap +try: + from __pypy__ import newdict +except ImportError: + newdict = lambda _ : {} try: from thread import get_ident as _get_ident @@ -326,8 +330,11 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = newdict('module') + namespace['OrderedDict'] = OrderedDict + namespace['_property'] = property + namespace['_tuple'] = tuple + namespace['__name__'] = 'namedtuple_%s' % typename try: exec template in namespace except SyntaxError, e: From noreply at buildbot.pypy.org Wed Mar 20 21:02:03 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 20 Mar 2013 21:02:03 +0100 (CET) Subject: [pypy-commit] pypy longdouble: preliminary implementation of long double Message-ID: <20130320200203.37C891C019F@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble Changeset: r62553:e5b66e73b23e Date: 2013-03-20 20:00 +0000 http://bitbucket.org/pypy/pypy/changeset/e5b66e73b23e/ Log: preliminary implementation of long double diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -131,7 +131,7 @@ def is_((obj1, obj2)): r = SomeBool() if obj2.is_constant(): - if obj1.is_constant(): + if obj1.is_constant(): r.const = obj1.const is obj2.const if obj2.const is None and not obj1.can_be_none(): r.const = False @@ -149,7 +149,7 @@ def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): - add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, + add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, bk.valueoftype(src_obj.const)) assert annotator.binding(op.args[tgt_arg]) == tgt_obj @@ -175,7 +175,7 @@ getbookkeeper().count("coerce", obj1, obj2) return pair(obj1, obj2).union() # reasonable enough - # approximation of an annotation intersection, the result should be the annotation obj or + # approximation of an annotation intersection, the result should be the annotation obj or # the intersection of obj and improvement def improve((obj, improvement)): if not improvement.contains(obj) and obj.contains(improvement): @@ -322,7 +322,7 @@ return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') - + add_knowntypedata(knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): @@ -333,7 +333,7 @@ # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) - if (isinstance(op.args[1], Constant) and + if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: @@ -354,14 +354,14 @@ class __extend__(pairtype(SomeBool, SomeBool)): def union((boo1, boo2)): - s = SomeBool() - if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): - s.const = boo1.const + s = SomeBool() + if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): + s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) s.set_knowntypedata(ktd) - return s + return s def and_((boo1, boo2)): s = SomeBool() @@ -386,13 +386,13 @@ if boo2.const: s.const = True return s - + def xor((boo1, boo2)): s = SomeBool() if boo1.is_constant() and boo2.is_constant(): s.const = boo1.const ^ boo2.const return s - + class __extend__(pairtype(SomeString, SomeString)): def union((str1, str2)): @@ -495,7 +495,7 @@ return s_string.__class__() class __extend__(pairtype(SomeFloat, SomeFloat)): - + def union((flt1, flt2)): return SomeFloat() @@ -512,16 +512,26 @@ class __extend__(pairtype(SomeSingleFloat, SomeSingleFloat)): - + def union((flt1, flt2)): return SomeSingleFloat() class __extend__(pairtype(SomeLongFloat, SomeLongFloat)): - + def union((flt1, flt2)): return SomeLongFloat() + add = sub = mul = union + + def div((flt1, flt2)): + return SomeLongFloat() + div.can_only_throw = [] + truediv = div + + # repeat these in order to copy the 'can_only_throw' attribute + inplace_div = div + inplace_truediv = truediv class __extend__(pairtype(SomeList, SomeList)): @@ -610,7 +620,7 @@ class __extend__(pairtype(SomeTuple, SomeInteger)): - + def getitem((tup1, int2)): if int2.is_immutable_constant(): try: @@ -624,7 +634,7 @@ class __extend__(pairtype(SomeList, SomeInteger)): - + def mul((lst1, int2)): return lst1.listdef.offspring() @@ -643,27 +653,27 @@ getitem_idx_key = getitem_idx def setitem((lst1, int2), s_value): - getbookkeeper().count("list_setitem", int2) + getbookkeeper().count("list_setitem", int2) lst1.listdef.mutate() lst1.listdef.generalize(s_value) setitem.can_only_throw = [IndexError] def delitem((lst1, int2)): - getbookkeeper().count("list_delitem", int2) + getbookkeeper().count("list_delitem", int2) lst1.listdef.resize() delitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] @@ -675,14 +685,14 @@ class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem_idx.can_only_throw = [IndexError] @@ -694,7 +704,7 @@ class __extend__(pairtype(SomeInteger, SomeString), pairtype(SomeInteger, SomeUnicodeString)): - + def mul((int1, str2)): # xxx do we want to support this getbookkeeper().count("str_mul", str2, int1) return str2.basestringclass() @@ -714,7 +724,7 @@ return result class __extend__(pairtype(SomeInteger, SomeList)): - + def mul((int1, lst2)): return lst2.listdef.offspring() @@ -787,7 +797,7 @@ class __extend__(pairtype(SomePBC, SomePBC)): - def union((pbc1, pbc2)): + def union((pbc1, pbc2)): d = pbc1.descriptions.copy() d.update(pbc2.descriptions) return SomePBC(d, can_be_None = pbc1.can_be_None or pbc2.can_be_None) 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 @@ -10,8 +10,8 @@ from rpython.annotator.listdef import ListDef, ListChangeUnallowed from rpython.annotator.dictdef import DictDef from rpython.flowspace.model import * -from rpython.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong -from rpython.rlib.rarithmetic import r_singlefloat +from rpython.rlib.rarithmetic import (r_uint, base_int, r_longlong, + r_ulonglong, r_singlefloat, r_longfloat) from rpython.rlib import objectmodel from rpython.flowspace.objspace import build_flow, FlowingError @@ -3263,6 +3263,17 @@ s = a.build_types(g, [int]) assert isinstance(s, annmodel.SomeSingleFloat) + def test_r_longfloat(self): + z = r_longfloat(0.4) + def g(n): + if n > 0: + return r_longfloat(n * 0.1) + else: + return z + a = self.RPythonAnnotator() + s = a.build_types(g, [int]) + assert isinstance(s, annmodel.SomeLongFloat) + def test_unicode_simple(self): def f(): return u'xxx' diff --git a/rpython/annotator/test/test_model.py b/rpython/annotator/test/test_model.py --- a/rpython/annotator/test/test_model.py +++ b/rpython/annotator/test/test_model.py @@ -56,11 +56,11 @@ (s6, s6)]) def test_commonbase_simple(): - class A0: + class A0: pass - class A1(A0): + class A1(A0): pass - class A2(A0): + class A2(A0): pass class B1(object): pass @@ -72,10 +72,10 @@ except TypeError: # if A0 is also a new-style class, e.g. in PyPy class B3(A0, object): pass - assert commonbase(A1,A2) is A0 + assert commonbase(A1,A2) is A0 assert commonbase(A1,A0) is A0 assert commonbase(A1,A1) is A1 - assert commonbase(A2,B2) is object + assert commonbase(A2,B2) is object assert commonbase(A2,B3) is A0 def test_list_union(): @@ -124,8 +124,8 @@ s_pos = SomeInteger(nonneg=True) s_1 = SomeInteger(nonneg=True); s_1.const = 1 s_m1 = SomeInteger(nonneg=False); s_m1.const = -1 - s_u = SomeInteger(nonneg=True, unsigned=True); - s_u1 = SomeInteger(nonneg=True, unsigned=True); + s_u = SomeInteger(nonneg=True, unsigned=True); + s_u1 = SomeInteger(nonneg=True, unsigned=True); s_u1.const = r_uint(1) assert annotation_to_lltype(s_i) == lltype.Signed assert annotation_to_lltype(s_pos) == lltype.Signed @@ -145,7 +145,10 @@ s_singlefloat = SomeSingleFloat() s_singlefloat.const = r_singlefloat(0.0) assert annotation_to_lltype(s_singlefloat) == lltype.SingleFloat - + s_longfloat = SomeLongFloat() + s_longfloat.const = r_longfloat(0.0) + assert annotation_to_lltype(s_longfloat) == lltype.LongFloat + def test_ll_union(): PS1 = lltype.Ptr(lltype.GcStruct('s')) PS2 = lltype.Ptr(lltype.GcStruct('s')) diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -611,6 +611,28 @@ return hop.genop('cast_primitive', [v], resulttype = lltype.SingleFloat) +class For_r_longfloat_values_Entry(extregistry.ExtRegistryEntry): + _type_ = r_longfloat + + def compute_annotation(self): + from rpython.annotator import model as annmodel + return annmodel.SomeLongFloat() + +class For_r_longfloat_type_Entry(extregistry.ExtRegistryEntry): + _about_ = r_longfloat + + def compute_result_annotation(self, *args_s, **kwds_s): + from rpython.annotator import model as annmodel + return annmodel.SomeLongFloat() + + def specialize_call(self, hop): + from rpython.rtyper.lltypesystem import lltype + v, = hop.inputargs(lltype.Float) + hop.exception_cannot_occur() + # we use cast_primitive to go between Float and LongFloat. + return hop.genop('cast_primitive', [v], + resulttype = lltype.LongFloat) + def int_between(n, m, p): """ check that n <= m < p. This assumes that n <= p. This is useful because diff --git a/rpython/rtyper/rfloat.py b/rpython/rtyper/rfloat.py --- a/rpython/rtyper/rfloat.py +++ b/rpython/rtyper/rfloat.py @@ -226,3 +226,18 @@ # we use cast_primitive to go between Float and LongFloat. return hop.genop('cast_primitive', [v], resulttype = lltype.Float) + +class __extend__(pairtype(LongFloatRepr, LongFloatRepr)): + + #Arithmetic + + def rtype_add(_, hop): + return _rtype_template_long(hop, 'add') + + rtype_inplace_add = rtype_add + + +def _rtype_template_long(hop, func): + vlist = hop.inputargs(lltype.LongFloat, lltype.LongFloat) + return hop.genop('float_'+func, vlist, resulttype=lltype.LongFloat) + From noreply at buildbot.pypy.org Wed Mar 20 21:13:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 20 Mar 2013 21:13:53 +0100 (CET) Subject: [pypy-commit] pypy default: the workaround for translation is only needed for setitem_str, not setitem Message-ID: <20130320201353.E5D231C019F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62554:29eb449022f8 Date: 2013-03-20 16:03 -0400 http://bitbucket.org/pypy/pypy/changeset/29eb449022f8/ Log: the workaround for translation is only needed for setitem_str, not setitem diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,19 +106,16 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def setitem(self, w_key, w_value): - self.strategy.setitem(self, w_key, w_value) - def setitem_str(self, key, w_value): self.strategy.setitem_str(self, key, w_value) def _add_indirections(): - dict_methods = "getitem \ - getitem_str delitem length \ - clear w_keys values \ - items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int \ + dict_methods = "getitem getitem_str setitem setdefault \ + popitem delitem clear \ + length w_keys values items \ + iterkeys itervalues iteritems \ + listview_str listview_unicode listview_int \ view_as_kwargs".split() def make_method(method): From noreply at buildbot.pypy.org Wed Mar 20 21:16:18 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:18 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: merge default into branch Message-ID: <20130320201618.A97401C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62555:ae694c5a2c60 Date: 2013-03-19 18:37 -0700 http://bitbucket.org/pypy/pypy/changeset/ae694c5a2c60/ Log: merge default into branch diff too long, truncating to 2000 out of 113434 lines diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -43,7 +43,7 @@ if prefix is None: prefix = PREFIX if standard_lib: - return os.path.join(prefix, "lib-python", get_python_version()) + return os.path.join(prefix, "lib-python", sys.version[0]) return os.path.join(prefix, 'site-packages') @@ -61,6 +61,7 @@ g['SO'] = _get_so_extension() or ".so" g['SOABI'] = g['SO'].rsplit('.')[0] g['LIBDIR'] = os.path.join(sys.prefix, 'lib') + g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check global _config_vars _config_vars = g diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,6 +34,8 @@ import struct import re +from __pypy__.builders import StringBuilder + __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1409,11 +1411,24 @@ except ImportError: from StringIO import StringIO + +class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + self.write = self.builder.append + + def getvalue(self): + return self.builder.build() + + def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib-python/2/sysconfig.py b/lib-python/2/sysconfig.py --- a/lib-python/2/sysconfig.py +++ b/lib-python/2/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python/{py_version_short}', - 'platstdlib': '{base}/lib-python/{py_version_short}', - 'purelib': '{base}/lib-python/{py_version_short}', - 'platlib': '{base}/lib-python/{py_version_short}', + 'stdlib': '{base}/lib-python/{py_version}', + 'platstdlib': '{base}/lib-python/{py_version}', + 'purelib': '{base}/lib-python/{py_version}', + 'platlib': '{base}/lib-python/{py_version}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -7,7 +7,6 @@ # the "sandboxed" process. It must work for Python2 as well. import types -from _codecs import utf_8_decode, utf_8_encode try: intern @@ -166,9 +165,8 @@ def dump_unicode(self, x): self._write(TYPE_UNICODE) - #s = x.encode('utf8') - s, len_s = utf_8_encode(x) - self.w_long(len_s) + s = x.encode('utf8') + self.w_long(len(s)) self._write(s) try: unicode @@ -386,8 +384,7 @@ def load_unicode(self): n = self.r_long() s = self._read(n) - #ret = s.decode('utf8') - ret, len_ret = utf_8_decode(s) + ret = s.decode('utf8') return ret dispatch[TYPE_UNICODE] = load_unicode diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -364,9 +364,10 @@ self._in_transaction = False self.isolation_level = isolation_level - self._cursors = [] + self.__cursors = [] + self.__cursors_counter = 0 self.__statements = [] - self.__statement_counter = 0 + self.__statements_counter = 0 self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} @@ -394,10 +395,7 @@ def close(self): self._check_thread() - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._finalize() + self.__do_all_statements(Statement._finalize, True) if self._db: ret = _lib.sqlite3_close(self._db) @@ -469,13 +467,33 @@ exc.error_code = error_code return exc + def _remember_cursor(self, cursor): + self.__cursors.append(weakref.ref(cursor)) + self.__cursors_counter += 1 + if self.__cursors_counter < 200: + return + self.__cursors_counter = 0 + self.__cursors = [r for r in self.__cursors if r() is not None] + def _remember_statement(self, statement): self.__statements.append(weakref.ref(statement)) - self.__statement_counter += 1 + self.__statements_counter += 1 + if self.__statements_counter < 200: + return + self.__statements_counter = 0 + self.__statements = [r for r in self.__statements if r() is not None] - if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements - if ref() is not None] + def __do_all_statements(self, action, reset_cursors): + for weakref in self.__statements: + statement = weakref() + if statement is not None: + action(statement) + + if reset_cursors: + for weakref in self.__cursors: + cursor = weakref() + if cursor is not None: + cursor._reset = True @_check_thread_wrap @_check_closed_wrap @@ -528,10 +546,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() + self.__do_all_statements(Statement._reset, False) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, @@ -552,15 +567,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() - - for cursor_ref in self._cursors: - cursor = cursor_ref() - if cursor: - cursor._reset = True + self.__do_all_statements(Statement._reset, True) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, @@ -787,14 +794,9 @@ __statement = None def __init__(self, con): - self.__initialized = True - self.__connection = con - if not isinstance(con, Connection): raise TypeError - con._check_thread() - con._check_closed() - con._cursors.append(weakref.ref(self)) + self.__connection = con self.arraysize = 1 self.row_factory = None @@ -804,11 +806,12 @@ self.__description = None self.__rowcount = -1 + con._check_thread() + con._remember_cursor(self) + + self.__initialized = True + def __del__(self): - try: - self.__connection._cursors.remove(weakref.ref(self)) - except (AttributeError, ValueError): - pass if self.__statement: self.__statement._reset() @@ -883,7 +886,6 @@ self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False - return self @__check_cursor_wrap @@ -921,9 +923,10 @@ if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement) if rc == _lib.SQLITE_OK: - return self + break else: raise self.__connection._get_exception(rc) + rc = _lib.sqlite3_finalize(statement) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -1000,6 +1003,7 @@ def __init__(self, connection, sql): self.__con = connection + self.__con._remember_statement(self) if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") @@ -1027,10 +1031,9 @@ ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(sql)) self._kind = Statement._DQL - if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) - self.__con._remember_statement(self) + sql = sql.value.decode('utf-8') if _check_remaining_sql(sql): raise Warning("You can only execute one statement at a time.") diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -96,6 +96,11 @@ # closer to the ones produced by cPickle in CPython from pickle import StringIO +try: + from pickle import StringBuilderFile +except ImportError: + assert '__pypy__' not in sys.builtin_module_names + from pickle import StringIO as StringBuilderFile PythonPickler = Pickler class Pickler(PythonPickler): @@ -120,7 +125,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -4,6 +4,7 @@ 'array_repr', 'array_str', 'set_string_function', 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + 'seterr', ] import sys diff --git a/pypy/TODO b/pypy/TODO new file mode 100644 --- /dev/null +++ b/pypy/TODO @@ -0,0 +1,2 @@ + +* ARM diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: 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 @@ -11,6 +11,8 @@ .. branch: callback-jit Callbacks from C are now better JITted +.. branch: fix-jit-logs + .. branch: remove-globals-in-jit .. branch: length-hint @@ -24,6 +26,9 @@ .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality +.. branch: indexing-by-array +Adds indexing by scalar, adds int conversion from scalar and single element array, +fixes compress, indexing by an array with a smaller shape and the indexed object. .. branch: signatures Improved RPython typing @@ -42,6 +47,8 @@ .. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal +.. branch: pickle-dumps +.. branch: scalar_get_set .. branch: release-2.0-beta1 @@ -85,3 +92,11 @@ .. branch: vendor-rename Remove minor verison number from lib-python dirs to simplify stdlib upgrades. + +.. branch: jitframe-on-heap +Moves optimized JIT frames from stack to heap. As a side effect it enables +stackless to work well with the JIT on PyPy. Also removes a bunch of code from +the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. diff --git a/pypy/goal/getnightly.py b/pypy/goal/getnightly.py new file mode 100755 --- /dev/null +++ b/pypy/goal/getnightly.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import sys +import os +import py + +if sys.platform.startswith('linux'): + arch = 'linux' +else: + print 'Cannot determine the platform, please update this scrip' + sys.exit(1) + +if sys.maxint == 2**63 - 1: + arch += '64' + +filename = 'pypy-c-jit-latest-%s.tar.bz2' % arch +url = 'http://buildbot.pypy.org/nightly/trunk/%s' % filename +tmp = py.path.local.mkdtemp() +mydir = tmp.chdir() +print 'Downloading pypy to', tmp +if os.system('wget "%s"' % url) != 0: + sys.exit(1) + +print 'Extracting pypy binary' +mydir.chdir() +os.system("tar -x -v --wildcards --strip-components=2 -f %s '*/bin/pypy'" % tmp.join(filename)) + diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -1,7 +1,14 @@ -import os, sys +import cStringIO +import os +import sys +import traceback +from errno import EINTR + from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated -from errno import EINTR + +from pypy.interpreter import debug + AUTO_DEBUG = os.getenv('PYPY_DEBUG') RECORD_INTERPLEVEL_TRACEBACK = True @@ -61,7 +68,7 @@ if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -95,7 +102,8 @@ def print_application_traceback(self, space, file=None): "NOT_RPYTHON: Dump a standard application-level traceback." - if file is None: file = sys.stderr + if file is None: + file = sys.stderr self.print_app_tb_only(file) print >> file, self.errorstr(space) @@ -130,8 +138,8 @@ def print_detailed_traceback(self, space=None, file=None): """NOT_RPYTHON: Dump a nice detailed interpreter- and application-level traceback, useful to debug the interpreter.""" - import traceback, cStringIO - if file is None: file = sys.stderr + if file is None: + file = sys.stderr f = cStringIO.StringIO() for i in range(len(self.debug_excs)-1, -1, -1): print >> f, "Traceback (interpreter-level):" @@ -144,7 +152,6 @@ self.print_app_tb_only(file) print >> file, '(application-level)', self.errorstr(space) if AUTO_DEBUG: - import debug debug.fire(self) @jit.unroll_safe @@ -174,7 +181,7 @@ # ("string", ...) ("string", ...) deprecated # (inst, None) (inst.__class__, inst) no # - w_type = self.w_type + w_type = self.w_type w_value = self.get_w_value(space) while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -211,7 +218,7 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type + self.w_type = w_type self._w_value = w_value def _exception_getclass(self, space, w_inst): @@ -327,7 +334,7 @@ from rpython.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(enumerate(attrs)) - # + class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): self.setup(w_type) @@ -336,6 +343,7 @@ for i, attr in entries: setattr(self, attr, args[i]) assert w_type is not None + def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -1,11 +1,13 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter import function, pycode, pyframe -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.astcompiler import consts from rpython.rlib import jit from rpython.tool.uid import uid +from pypy.interpreter import function, pycode, pyframe +from pypy.interpreter.astcompiler import consts +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule + + class Cell(Wrappable): "A simple container for a wrapped value." @@ -20,7 +22,7 @@ def get(self): if self.w_value is None: - raise ValueError, "get() from an empty cell" + raise ValueError("get() from an empty cell") return self.w_value def set(self, w_value): @@ -28,9 +30,9 @@ def delete(self): if self.w_value is None: - raise ValueError, "delete() on an empty cell" + raise ValueError("delete() on an empty cell") self.w_value = None - + def descr__cmp__(self, space, w_other): other = space.interpclass_w(w_other) if not isinstance(other, Cell): @@ -46,10 +48,10 @@ return space.cmp(self.w_value, other.w_value) def descr__reduce__(self, space): - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('cell_new') - if self.w_value is None: #when would this happen? + if self.w_value is None: # when would this happen? return space.newtuple([new_inst, space.newtuple([])]) tup = [self.w_value] return space.newtuple([new_inst, space.newtuple([]), @@ -57,7 +59,7 @@ def descr__setstate__(self, space, w_state): self.w_value = space.getitem(w_state, space.wrap(0)) - + def __repr__(self): """ representation for debugging purposes """ if self.w_value is None: @@ -74,10 +76,9 @@ raise OperationError(space.w_ValueError, space.wrap("Cell is empty")) - super_initialize_frame_scopes = pyframe.PyFrame.initialize_frame_scopes -super_fast2locals = pyframe.PyFrame.fast2locals -super_locals2fast = pyframe.PyFrame.locals2fast +super_fast2locals = pyframe.PyFrame.fast2locals +super_locals2fast = pyframe.PyFrame.locals2fast class __extend__(pyframe.PyFrame): @@ -132,7 +133,7 @@ def fast2locals(self): super_fast2locals(self) # cellvars are values exported to inner scopes - # freevars are values coming from outer scopes + # freevars are values coming from outer scopes freevarnames = list(self.pycode.co_cellvars) if self.pycode.co_flags & consts.CO_OPTIMIZED: freevarnames.extend(self.pycode.co_freevars) @@ -197,11 +198,11 @@ except ValueError: varname = self.getfreevarname(varindex) if self.iscellvar(varindex): - message = "local variable '%s' referenced before assignment"%varname + message = "local variable '%s' referenced before assignment" % varname w_exc_type = self.space.w_UnboundLocalError else: message = ("free variable '%s' referenced before assignment" - " in enclosing scope"%varname) + " in enclosing scope" % varname) w_exc_type = self.space.w_NameError raise OperationError(w_exc_type, self.space.wrap(message)) else: diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -19,11 +19,6 @@ # - normal: self.sthread != None, not is_empty_handle(self.h) # - finished: self.sthread != None, is_empty_handle(self.h) - def __del__(self): - sthread = self.sthread - if sthread is not None and not sthread.is_empty_handle(self.h): - sthread.destroy(self.h) - def check_sthread(self): ec = self.space.getexecutioncontext() if ec.stacklet_thread is not self.sthread: @@ -34,7 +29,6 @@ if self.sthread is not None: raise geterror(self.space, "continulet already __init__ialized") sthread = build_sthread(self.space) - workaround_disable_jit(sthread) # # hackish: build the frame "by hand", passing it the correct arguments space = self.space @@ -77,8 +71,7 @@ global_state.clear() raise geterror(self.space, "continulet already finished") self.check_sthread() - workaround_disable_jit(self.sthread) - # + global_state.origin = self if to is None: # simple switch: going to self.h @@ -271,16 +264,6 @@ sthread = ec.stacklet_thread = SThread(space, ec) return sthread -def workaround_disable_jit(sthread): - # A bad workaround to kill the JIT anywhere in this thread. - # This forces all the frames. It's a bad workaround because - # it takes O(depth) time, and it will cause some "abort: - # vable escape" in the JIT. The goal is to prevent any frame - # from being still virtuals, because the JIT generates code - # to un-virtualizable them "on demand" by loading values based - # on FORCE_TOKEN, which is an address in the stack. - sthread.ec.force_all_frames() - # ____________________________________________________________ def permute(space, args_w): diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -350,7 +350,11 @@ def remove(self, w_iobase): holder = w_iobase.streamholder if holder is not None: - del self.streams[holder] + try: + del self.streams[holder] + except KeyError: + # this can happen in daemon threads + pass def flush_all(self, space): while self.streams: diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi/reflex_capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -9,18 +9,23 @@ srcpath = pkgpath.join("src") incpath = pkgpath.join("include") +import commands +(config_stat, incdir) = commands.getstatusoutput("root-config --incdir") + if os.environ.get("ROOTSYS"): - import commands - (stat, incdir) = commands.getstatusoutput("root-config --incdir") - if stat != 0: # presumably Reflex-only + if config_stat != 0: # presumably Reflex-only rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")] else: rootincpath = [incdir] rootlibpath = commands.getoutput("root-config --libdir").split() else: - rootincpath = [] - rootlibpath = [] + if config_stat == 0: + rootincpath = [incdir] + rootlibpath = commands.getoutput("root-config --libdir").split() + else: + rootincpath = [] + rootlibpath = [] def identify(): return 'Reflex' diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -7,7 +7,7 @@ ifeq ($(ROOTSYS),) genreflex=genreflex - cppflags= + cppflags=-I$(shell root-config --incdir) -L$(shell root-config --libdir) else genreflex=$(ROOTSYS)/bin/genreflex ifeq ($(wildcard $(ROOTSYS)/include),) # standard locations used? diff --git a/pypy/module/cppyy/test/test_crossing.py b/pypy/module/cppyy/test/test_crossing.py --- a/pypy/module/cppyy/test/test_crossing.py +++ b/pypy/module/cppyy/test/test_crossing.py @@ -1,6 +1,16 @@ import py, os, sys +from pypy.interpreter.gateway import interp2app, unwrap_spec +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.translator import platform +from rpython.translator.gensupp import uniquemodulename +from rpython.tool.udir import udir + +from pypy.module.cpyext import api +from pypy.module.cpyext.state import State + from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("crossingDict.so")) @@ -11,27 +21,90 @@ if err: raise OSError("'make' failed (see stderr)") +# from pypy/module/cpyext/test/test_cpyext.py; modified to accept more external +# symbols and called directly instead of import_module +def compile_extension_module(space, modname, symbols, **kwds): + """ + Build an extension module and return the filename of the resulting native + code file. + + modname is the name of the module, possibly including dots if it is a module + inside a package. + + Any extra keyword arguments are passed on to ExternalCompilationInfo to + build the module (so specify your source with one of those). + """ + state = space.fromcache(State) + api_library = state.api_lib + if sys.platform == 'win32': + kwds["libraries"] = [api_library] + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] + elif sys.platform == 'darwin': + kwds["link_files"] = [str(api_library + '.dylib')] + else: + kwds["link_files"] = [str(api_library + '.so')] + if sys.platform.startswith('linux'): + kwds["compile_extra"]=["-Werror=implicit-function-declaration"] + + modname = modname.split('.')[-1] + eci = ExternalCompilationInfo( + export_symbols=['init%s' % (modname,)]+symbols, + include_dirs=api.include_dirs, + **kwds + ) + eci = eci.convert_sources_to_files() + dirname = (udir/uniquemodulename('module')).ensure(dir=1) + soname = platform.platform.compile( + [], eci, + outputfilename=str(dirname/modname), + standalone=False) + from pypy.module.imp.importing import get_so_extension + pydname = soname.new(purebasename=modname, ext=get_so_extension(space)) + soname.rename(pydname) + return str(pydname) class AppTestCrossing(AppTestCpythonExtensionBase): spaceconfig = dict(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi', 'array', 'itertools', 'rctime', 'binascii']) def setup_class(cls): - # following from AppTestCpythonExtensionBase, with cppyy added - cls.space.getbuiltinmodule("cpyext") - from pypy.module.imp.importing import importhook - importhook(cls.space, "os") # warm up reference counts - from pypy.module.cpyext.pyobject import RefcountState - state = cls.space.fromcache(RefcountState) - state.non_heaptypes_w[:] = [] - - # cppyy specific additions (not that the test_dct is loaded late + AppTestCpythonExtensionBase.setup_class.im_func(cls) + # cppyy specific additions (note that test_dct is loaded late # to allow the generated extension module be loaded first) cls.w_test_dct = cls.space.wrap(test_dct) cls.w_pre_imports = cls.space.appexec([], """(): import cppyy, ctypes""") # prevents leak-checking complaints on ctypes - from pypy.module.imp.importing import get_so_extension - cls.w_soext = cls.space.wrap(get_so_extension(cls.space)) + + def setup_method(self, func): + AppTestCpythonExtensionBase.setup_method.im_func(self, func) + + @unwrap_spec(name=str, init=str, body=str) + def load_cdll(space, name, init, body, w_symbols): + # the following is loosely from test_cpyext.py import_module; it + # is copied here to be able to tweak the call to + # compile_extension_module and to get a different return result + # than in that function + code = """ + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + kwds = dict(separate_module_sources=[code]) + symbols = [space.str_w(w_item) for w_item in space.fixedview(w_symbols)] + mod = compile_extension_module(space, name, symbols, **kwds) + + # explicitly load the module as a CDLL rather than as a module + import ctypes + from pypy.module.imp.importing import get_so_extension + fullmodname = os.path.join( + os.path.dirname(mod), name + get_so_extension(space)) + return ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) + + self.w_load_cdll = self.space.wrap(interp2app(load_cdll)) def test00_base_class(self): """Test from cpyext; only here to see whether the imported class works""" @@ -49,10 +122,13 @@ import os, ctypes + name = 'bar' + init = """ if (Py_IsInitialized()) Py_InitModule("bar", methods); """ + # note: only the symbols are needed for C, none for python body = """ long bar_unwrap(PyObject* arg) @@ -67,10 +143,12 @@ { NULL } }; """ + # explicitly load the module as a CDLL rather than as a module +# dirname = space.wrap(os.path.dirname(mod)) - dirname = self.import_module(name='bar', init=init, body=body, load_it=False) - fullmodname = os.path.join(dirname, 'bar' + self.soext) - self.cmodule = ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) +# dirname = self.import_module(name='bar', init=init, body=body, load_it=False) +# fullmodname = os.path.join(dirname, name + self.soext) + self.cmodule = self.load_cdll(name, init, body, ['bar_unwrap', 'bar_wrap'])#ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) def test02_crossing_dict(self): """Test availability of all needed classes in the dict""" diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py --- a/pypy/module/cppyy/test/test_pythonify.py +++ b/pypy/module/cppyy/test/test_pythonify.py @@ -6,6 +6,9 @@ test_dct = str(currpath.join("example01Dict.so")) def setup_module(mod): + # force removal of ROOTSYS for this one test, which serves as a test itself + if os.getenv("ROOTSYS"): + os.unsetenv("ROOTSYS") if sys.platform == 'win32': py.test.skip("win32 not supported so far") err = os.system("cd '%s' && make example01Dict.so" % currpath) diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -6,7 +6,7 @@ def base(self): raise NotImplementedError - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): raise NotImplementedError class BaseArrayIterator(object): diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,5 +1,5 @@ -from pypy.module.micronumpy.arrayimpl import base +from pypy.module.micronumpy.arrayimpl import base, scalar from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException @@ -20,7 +20,7 @@ parent = None # JIT hints that length of all those arrays is a constant - + def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) @@ -71,7 +71,7 @@ new_shape, self, orig_array) else: return None - + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -79,15 +79,19 @@ dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) - return SliceArray(self.start, strides, backstrides, + return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) + def set_real(self, space, orig_array, w_value): + tmp = self.get_real(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type - return SliceArray(self.start + dtype.get_size(), strides, + return SliceArray(self.start + dtype.get_size(), strides, backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag @@ -98,6 +102,10 @@ impl.fill(self.dtype.box(0)) return impl + def set_imag(self, space, orig_array, w_value): + tmp = self.get_imag(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + # -------------------- applevel get/setitem ----------------------- @jit.unroll_safe @@ -148,16 +156,12 @@ space.isinstance_w(w_idx, space.w_slice) or space.is_w(w_idx, space.w_None)): raise IndexError - if isinstance(w_idx, W_NDimArray): + if isinstance(w_idx, W_NDimArray) and not isinstance(w_idx.implementation, scalar.Scalar): raise ArrayArgumentException shape = self.get_shape() shape_len = len(shape) - if shape_len == 0: - raise OperationError(space.w_IndexError, space.wrap( - "0-d arrays can't be indexed")) view_w = None - if (space.isinstance_w(w_idx, space.w_list) or - isinstance(w_idx, W_NDimArray)): + if space.isinstance_w(w_idx, space.w_list): raise ArrayArgumentException if space.isinstance_w(w_idx, space.w_tuple): view_w = space.fixedview(w_idx) @@ -260,10 +264,10 @@ shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] - shape[axis1], shape[axis2] = shape[axis2], shape[axis1] + shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] - backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] - return W_NDimArray.new_slice(self.start, strides, + backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] + return W_NDimArray.new_slice(self.start, strides, backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): @@ -298,12 +302,12 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is None or shape == self.get_shape(): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, backward_broadcast) return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): @@ -334,13 +338,13 @@ free_raw_storage(self.storage, track_allocation=False) - + class NonWritableArray(ConcreteArray): def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) - + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, orig_arr, @@ -366,15 +370,16 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), - self.get_shape(), shape) + self.get_shape(), shape, + backward_broadcast) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return iter.OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -1,6 +1,6 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.base import W_NDimArray, convert_to_array from pypy.module.micronumpy import support from pypy.interpreter.error import OperationError @@ -38,7 +38,10 @@ def get_strides(self): return [] - def create_iter(self, shape=None): + def get_backstrides(self): + return [] + + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) def get_scalar_value(self): @@ -58,6 +61,62 @@ def transpose(self, _): return self + def get_real(self, orig_array): + if self.dtype.is_complex_type(): + scalar = Scalar(self.dtype.float_type) + scalar.value = self.value.convert_real_to(scalar.dtype) + return scalar + return self + + def set_real(self, space, orig_array, w_val): + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type or self.dtype + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + if self.dtype.is_complex_type(): + #imag = dtype.itemtype.unbox(self.value.convert_imag_to(dtype)) + #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). + # convert_to(dtype)) + #self.value = self.dtype.box_complex(val, imag) + self.value = self.dtype.itemtype.composite(w_arr.get_scalar_value().convert_to(dtype), + self.value.convert_imag_to(dtype)) + else: + self.value = w_arr.get_scalar_value() + + def get_imag(self, orig_array): + if self.dtype.is_complex_type(): + scalar = Scalar(self.dtype.float_type) + scalar.value = self.value.convert_imag_to(scalar.dtype) + return scalar + scalar = Scalar(self.dtype) + if self.dtype.is_flexible_type(): + scalar.value = self.value + else: + scalar.value = scalar.dtype.itemtype.box(0) + return scalar + + def set_imag(self, space, orig_array, w_val): + #Only called on complex dtype + assert self.dtype.is_complex_type() + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + #real = dtype.itemtype.unbox(self.value.convert_real_to(dtype)) + #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). + # convert_to(dtype)) + #self.value = self.dtype.box_complex(real, val) + self.value = self.dtype.itemtype.composite( + self.value.convert_real_to(dtype), + w_arr.get_scalar_value(), + ) + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -69,7 +128,7 @@ def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - + def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -86,7 +145,7 @@ def reshape(self, space, orig_array, new_shape): return self.set_shape(space, orig_array, new_shape) - + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") 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 @@ -73,7 +73,6 @@ def build_and_convert(self, space, box): return self.itemtype.build_and_convert(space, self, box) - def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -19,7 +19,7 @@ def get_shape(self): return self.shape - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.base(), W_NDimArray) return self.base().create_iter() diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -15,6 +15,7 @@ from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes from pypy.module.micronumpy.interp_arrayops import repeat, choose +from pypy.module.micronumpy.arrayimpl import scalar from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -79,7 +80,11 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) size = loop.count_all_true(arr) - res = W_NDimArray.from_shape([size], self.get_dtype()) + if len(arr.get_shape()) == 1: + res_shape = [size] + self.get_shape()[1:] + else: + res_shape = [size] + res = W_NDimArray.from_shape(res_shape, self.get_dtype()) return loop.getitem_filter(res, self, arr) def setitem_filter(self, space, idx, val): @@ -223,9 +228,10 @@ s.append('])') return s.build() - def create_iter(self, shape=None): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseArrayImplementation) - return self.implementation.create_iter(shape) + return self.implementation.create_iter(shape=shape, + backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) @@ -266,16 +272,14 @@ def descr_set_real(self, space, w_value): # copy (broadcast) values into self - tmp = self.implementation.get_real(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_real(space, self, w_value) def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) - tmp = self.implementation.get_imag(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_imag(space, self, w_value) def descr_reshape(self, space, args_w): """reshape(...) @@ -362,8 +366,11 @@ if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for compress")) + arr = self + else: + arr = self.descr_reshape(space, [space.wrap(-1)]) index = convert_to_array(space, w_obj) - return self.getitem_filter(space, index) + return arr.getitem_filter(space, index) def descr_flatten(self, space, w_order=None): if self.is_scalar(): @@ -759,6 +766,15 @@ descr_argmax = _reduce_argmax_argmin_impl("max") descr_argmin = _reduce_argmax_argmin_impl("min") + def descr_int(self, space): + shape = self.get_shape() + if len(shape) == 0: + assert isinstance(self.implementation, scalar.Scalar) + return space.int(space.wrap(self.implementation.get_scalar_value())) + if shape == [1]: + return space.int(self.descr_getitem(space, space.wrap(0))) + raise OperationError(space.w_TypeError, space.wrap("only length-1 arrays can be converted to Python scalars")) + @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, @@ -799,6 +815,7 @@ __repr__ = interp2app(W_NDimArray.descr_repr), __str__ = interp2app(W_NDimArray.descr_str), + __int__ = interp2app(W_NDimArray.descr_int), __pos__ = interp2app(W_NDimArray.descr_pos), __neg__ = interp2app(W_NDimArray.descr_neg), 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 @@ -17,9 +17,9 @@ return not dtype.itemtype.bool(val) class W_Ufunc(Wrappable): - _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", + _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex", "complex_to_float"] - _immutable_fields_ = ["promote_to_float", "promote_bools", "name", + _immutable_fields_ = ["promote_to_float", "promote_bools", "name", "allow_complex", "complex_to_float"] def __init__(self, name, promote_to_float, promote_bools, identity, @@ -151,13 +151,13 @@ assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) if obj.get_dtype().is_flexible_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() shapelen = len(obj_shape) - axis = unwrap_axis_arg(space, shapelen, w_axis) + axis = unwrap_axis_arg(space, shapelen, w_axis) assert axis >= 0 size = obj.get_size() dtype = interp_dtype.decode_w_dtype(space, dtype) @@ -256,7 +256,7 @@ out = None w_obj = convert_to_array(space, w_obj) if w_obj.get_dtype().is_flexible_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('Not implemented for this type')) if self.int_only and not w_obj.get_dtype().is_int_type(): raise OperationError(space.w_TypeError, space.wrap( @@ -281,7 +281,7 @@ if self.complex_to_float and calc_dtype.is_complex_type(): if calc_dtype.name == 'complex64': res_dtype = interp_dtype.get_dtype_cache(space).w_float32dtype - else: + else: res_dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if w_obj.is_scalar(): w_val = self.func(calc_dtype, @@ -304,7 +304,7 @@ argcount = 2 def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, comparison_func=False, int_only=False, + identity=None, comparison_func=False, int_only=False, allow_complex=True, complex_to_float=False): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, @@ -526,11 +526,11 @@ return current_guess elif space.isinstance_w(w_obj, space.w_str): if (current_guess is None): - return interp_dtype.variable_dtype(space, + return interp_dtype.variable_dtype(space, 'S%d' % space.len_w(w_obj)) elif current_guess.num ==18: if current_guess.itemtype.get_size() < space.len_w(w_obj): - return interp_dtype.variable_dtype(space, + return interp_dtype.variable_dtype(space, 'S%d' % space.len_w(w_obj)) return current_guess if current_guess is complex_type: @@ -607,7 +607,7 @@ ("negative", "neg", 1), ("absolute", "abs", 1, {"complex_to_float": True}), ("sign", "sign", 1, {"promote_bools": True}), - ("signbit", "signbit", 1, {"bool_result": True, + ("signbit", "signbit", 1, {"bool_result": True, "allow_complex": False}), ("reciprocal", "reciprocal", 1), ("conjugate", "conj", 1), @@ -618,7 +618,7 @@ "allow_complex": False}), ("fmax", "fmax", 2, {"promote_to_float": True}), ("fmin", "fmin", 2, {"promote_to_float": True}), - ("fmod", "fmod", 2, {"promote_to_float": True, + ("fmod", "fmod", 2, {"promote_to_float": True, 'allow_complex': False}), ("floor", "floor", 1, {"promote_to_float": True, "allow_complex": False}), 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 @@ -318,9 +318,12 @@ def getitem_filter(res, arr, index): res_iter = res.create_iter() - index_iter = index.create_iter() + shapelen = len(arr.get_shape()) + if shapelen > 1 and len(index.get_shape()) < 2: + index_iter = index.create_iter(arr.get_shape(), backward_broadcast=True) + else: + index_iter = index.create_iter() arr_iter = arr.create_iter() - shapelen = len(arr.get_shape()) arr_dtype = arr.get_dtype() index_dtype = index.get_dtype() # XXX length of shape of index as well? diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -40,7 +40,7 @@ rshape += shape[s:] return rshape, rstart, rstrides, rbackstrides -def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape): +def calculate_broadcast_strides(strides, backstrides, orig_shape, res_shape, backwards=False): rstrides = [] rbackstrides = [] for i in range(len(orig_shape)): @@ -50,8 +50,12 @@ else: rstrides.append(strides[i]) rbackstrides.append(backstrides[i]) - rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides - rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides + if backwards: + rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape)) + rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape)) + else: + rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides + rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides return rstrides, rbackstrides def is_single_elem(space, w_elem, is_rec_type): 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 @@ -140,25 +140,25 @@ def test_fmax(self): from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') - a = array((complex(ninf, 10), complex(10, ninf), + a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), 5+5j, 5-5j, -5+5j, -5-5j, 0+5j, 0-5j, 5, -5, complex(nan, 0), complex(0, nan)), dtype = complex) b = [ninf]*a.size - res = [a[0 ], a[1 ], a[2 ], a[3 ], + res = [a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ], a[8 ], a[9 ], a[10], a[11], b[12], b[13]] assert (fmax(a, b) == res).all() b = [inf]*a.size - res = [b[0 ], b[1 ], a[2 ], b[3 ], + res = [b[0 ], b[1 ], a[2 ], b[3 ], b[4 ], b[5 ], b[6 ], b[7 ], b[8 ], b[9 ], b[10], b[11], b[12], b[13]] assert (fmax(a, b) == res).all() b = [0]*a.size - res = [b[0 ], a[1 ], a[2 ], a[3 ], + res = [b[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], b[6 ], b[7 ], a[8 ], b[9 ], a[10], b[11], b[12], b[13]] @@ -167,25 +167,25 @@ def test_fmin(self): from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') - a = array((complex(ninf, 10), complex(10, ninf), + a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), 5+5j, 5-5j, -5+5j, -5-5j, 0+5j, 0-5j, 5, -5, complex(nan, 0), complex(0, nan)), dtype = complex) b = [inf]*a.size - res = [a[0 ], a[1 ], b[2 ], a[3 ], + res = [a[0 ], a[1 ], b[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ], a[8 ], a[9 ], a[10], a[11], b[12], b[13]] assert (fmin(a, b) == res).all() b = [ninf]*a.size - res = [b[0 ], b[1 ], b[2 ], b[3 ], + res = [b[0 ], b[1 ], b[2 ], b[3 ], b[4 ], b[5 ], b[6 ], b[7 ], b[8 ], b[9 ], b[10], b[11], b[12], b[13]] assert (fmin(a, b) == res).all() b = [0]*a.size - res = [a[0 ], b[1 ], b[2 ], b[3 ], + res = [a[0 ], b[1 ], b[2 ], b[3 ], b[4 ], b[5 ], a[6 ], a[7 ], b[8 ], a[9 ], b[10], a[11], b[12], b[13]] @@ -205,17 +205,17 @@ pass # no longdouble yet inf = float('inf') nan = float('nan') - #complex - orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, - complex(inf, 3), complex(inf, -3), complex(inf, -inf), + #complex + orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, + complex(inf, 3), complex(inf, -3), complex(inf, -inf), complex(nan, 3), 0+0j, 0-0j] a2 = 2.**2 + 4.**2 r = 2. / a2 i = 4. / a2 cnan = complex(nan, nan) - expected = [complex(r, -i), complex(-r, -i), complex(r, i), - complex(-r, i), - -0j, 0j, cnan, + expected = [complex(r, -i), complex(-r, -i), complex(r, i), + complex(-r, i), + -0j, 0j, cnan, cnan, cnan, cnan] for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) @@ -225,7 +225,7 @@ def test_floorceiltrunc(self): from numpypy import array, floor, ceil, trunc - a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) + a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) @@ -270,11 +270,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res[0]) - t2 = float(b[i].real) + t1 = float(res[0]) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res[1]) - t2 = float(b[i].imag) + t1 = float(res[1]) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_expm1(self): @@ -310,11 +310,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): @@ -330,16 +330,16 @@ raises(TypeError, logaddexp, complex(1, 1), complex(3, 3)) raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3)) raises(TypeError, arctan2, complex(1, 1), complex(3, 3)) - raises (TypeError, fmod, complex(90,90), 3) + raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): from numpypy import isnan, isinf, array - assert (isnan(array([0.2+2j, complex(float('inf'),0), + assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ [False, False, False, True, True]).all() - assert (isinf(array([0.2+2j, complex(float('inf'),0), + assert (isinf(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ [False, True, True, False, False]).all() @@ -374,7 +374,7 @@ b = power(a, p) for i in range(len(a)): try: - r = self.c_pow((float(a[i].real), float(a[i].imag)), + r = self.c_pow((float(a[i].real), float(a[i].imag)), (float(p.real), float(p.imag))) except ZeroDivisionError: r = (nan, nan) @@ -384,10 +384,10 @@ r = (nan, nan) msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ (c,a[i], p, b[i], r) - t1 = float(r[0]) - t2 = float(b[i].real) + t1 = float(r[0]) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(r[1]) + t1 = float(r[1]) t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) @@ -445,11 +445,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7)): b = log1p(array(a,dtype=c)) @@ -465,11 +465,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): @@ -520,7 +520,26 @@ assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real + b[0] = 1024 + assert a[0].real == 1024 assert b.dtype == dtype(float) + a = array(complex(3.0, 4.0)) + b = a.real + assert b == array(3) + a.real = 1024 + assert a.real == 1024 + assert a.imag == array(4) + assert b.dtype == dtype(float) + a = array(4.0) + b = a.imag + assert b == 0 + assert b.dtype == dtype(float) + raises(TypeError, 'a.imag = 1024') + raises(ValueError, 'a.real = [1, 3]') + a = array('abc') + assert str(a.real) == 'abc' + # numpy imag for flexible types returns self + assert str(a.imag) == 'abc' for complex_ in complex_dtypes: O = complex(0, 0) @@ -547,12 +566,12 @@ assert add(c1, c2) == complex_(complex(4, 6)) assert add(c1, c2) == complex(4, 6) - + assert sub(c0, c0) == sub(c1, c1) == 0 assert sub(c1, c2) == complex(-2, -2) assert negative(complex(1,1)) == complex(-1, -1) assert negative(complex(0, 0)) == 0 - + assert multiply(1, c1) == c1 assert multiply(2, c2) == complex(6, 8) @@ -610,7 +629,7 @@ for complex_, abs_err, testcases in (\ (np.complex128, 5e-323, self.testcases128), - # (np.complex64, 5e-32, self.testcases64), + # (np.complex64, 5e-32, self.testcases64), ): for id, fn, ar, ai, er, ei, flags in testcases: arg = complex_(complex(ar, ai)) @@ -648,7 +667,7 @@ ) % (id, fn, complex_, ar, ai, expected[0], expected[1], actual[0], actual[1]) - + # since rAlmostEqual is a wrapped function, # convert arguments to avoid boxed values rAlmostEqual(float(expected[0]), float(actual[0]), 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 @@ -1357,7 +1357,7 @@ assert a[1] == 'xyz' assert a.imag[0] == 'abc' raises(TypeError, 'a.imag = "qop"') - a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) + a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) assert a.real[0,1] == 2 a.real[0,1] = -20 assert a[0,1].real == -20 @@ -1367,7 +1367,7 @@ assert a[1,2].imag == 30 a.real = 13 assert a[1,1].real == 13 - a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) + a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) a.real = 13 assert a[3].real == 13 a.imag = -5 @@ -1564,29 +1564,29 @@ from numpypy import array # testcases from numpy docstring x = array([[1, 2, 3]]) - assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() + assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() x = array([[[0,1],[2,3]],[[4,5],[6,7]]]) # shape = (2, 2, 2) - assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], - [[1, 5], [3, 7]]])).all() - assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], + assert (x.swapaxes(0, 2) == array([[[0, 4], [2, 6]], + [[1, 5], [3, 7]]])).all() + assert (x.swapaxes(0, 1) == array([[[0, 1], [4, 5]], [[2, 3], [6, 7]]])).all() - assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], + assert (x.swapaxes(1, 2) == array([[[0, 2], [1, 3]], [[4, 6],[5, 7]]])).all() # more complex shape i.e. (2, 2, 3) - x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) - assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], - [[4, 5, 6], [10, 11, 12]]])).all() - assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], - [[3, 9], [6, 12]]])).all() - assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], - [[7, 10], [8, 11],[9, 12]]])).all() + x = array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) + assert (x.swapaxes(0, 1) == array([[[1, 2, 3], [7, 8, 9]], + [[4, 5, 6], [10, 11, 12]]])).all() + assert (x.swapaxes(0, 2) == array([[[1, 7], [4, 10]], [[2, 8], [5, 11]], + [[3, 9], [6, 12]]])).all() + assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], + [[7, 10], [8, 11],[9, 12]]])).all() # test slice - assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], + assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() # test virtual - assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], + assert ((x + x).swapaxes(0,1) == array([[[ 2, 4, 6], [14, 16, 18]], [[ 8, 10, 12], [20, 22, 24]]])).all() assert array(1).swapaxes(10, 12) == 1 @@ -1615,7 +1615,7 @@ assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): - from numpypy import array, arange, zeros + from numpypy import arange, zeros, array a = arange(10) a[[3, 2, 1, 5]] = zeros(4, dtype=int) assert (a == [0, 0, 0, 0, 4, 0, 6, 7, 8, 9]).all() @@ -1630,12 +1630,16 @@ assert (b[array([True, False, True])] == [0, 2]).all() raises(ValueError, "array([1, 2])[array([True, True, True])]") raises(ValueError, "b[array([[True, False], [True, False]])]") + a = array([[1,2,3],[4,5,6],[7,8,9]],int) + c = array([True,False,True],bool) + b = a[c] + assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all() def test_bool_array_index_setitem(self): from numpypy import arange, array b = arange(5) b[array([True, False, True])] = [20, 21, 0, 0, 0, 0, 0] - assert (b == [20, 1, 21, 3, 4]).all() + assert (b == [20, 1, 21, 3, 4]).all() raises(ValueError, "array([1, 2])[array([True, False, True])] = [1, 2, 3]") def test_weakref(self): @@ -1753,6 +1757,13 @@ b = array([1, 2, 3, 4]) assert (a == b) == False + def test__int__(self): + from numpypy import array + assert int(array(1)) == 1 + assert int(array([1])) == 1 + assert raises(TypeError, "int(array([1, 2]))") + assert int(array([1.5])) == 1 + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): @@ -2089,7 +2100,6 @@ assert isinstance(i['data'][0], int) def test_array_indexing_one_elem(self): - skip("not yet") from numpypy import array, arange raises(IndexError, 'arange(3)[array([3.5])]') a = arange(3)[array([1])] @@ -2183,6 +2193,7 @@ a = arange(10) assert (a.compress([True, False, True]) == [0, 2]).all() assert (a.compress([1, 0, 13]) == [0, 2]).all() + assert (a.compress([1, 0, 13]) == [0, 2]).all() assert (a.compress([1, 0, 13.5]) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype='>f4')) == [0, 2]).all() assert (a.compress(array([1, 0, 13.5], dtype=' Author: Matti Picus Branch: str-dtype-improvement Changeset: r62556:ee54a9e3ac5a Date: 2013-03-20 11:44 -0700 http://bitbucket.org/pypy/pypy/changeset/ee54a9e3ac5a/ Log: test, fix concatenate two str arrays diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -133,9 +133,6 @@ raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) if _axis < 0 or len(shape) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) - if dtype is None: - raise OperationError(space.w_TypeError, space.wrap( - 'invalid type promotion')) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -441,12 +441,14 @@ return dt2 if dt1.is_str_or_unicode(): if dt2.num == 18: - size = max(dt2.itemtype.get_element_size(), - dt1.itemtype.get_element_size()) - return interp_dtype.new_string_dtype(space, size) - size = max(dt2.itemtype.get_element_size(), - dt1.itemtype.get_element_size()) - return interp_dtype.new_unicode_dtype(space, size) + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 return dt2 else: # increase to the next signed type 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 @@ -1484,6 +1484,9 @@ assert str(a.dtype) == '|S3' a = concatenate((array([]), array(['abc']))) assert a[0] == 'abc' + a = concatenate((['abcdef'], ['abc'])) + assert a[0] == 'abcdef' + assert str(a.dtype) == '|S6' def test_record_concatenate(self): # only an exact match can succeed From noreply at buildbot.pypy.org Wed Mar 20 21:16:21 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:21 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: check result from raises in tests Message-ID: <20130320201621.458191C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62557:ab13ea6f9492 Date: 2013-03-20 11:57 -0700 http://bitbucket.org/pypy/pypy/changeset/ab13ea6f9492/ Log: check result from raises in tests 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 @@ -1494,13 +1494,16 @@ a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), zeros((2,),dtype=[('x', int), ('y', float)]))) assert a.shape == (4,) - raises(TypeError, concatenate, + exc = raises(TypeError, concatenate, (zeros((2,), dtype=[('x', int), ('y', float)]), (zeros((2,), dtype=[('x', float), ('y', float)])))) - raises(TypeError, concatenate, ([1], zeros((2,), + assert str(exc.value).startswith('record type mismatch') + exc = raises(TypeError, concatenate, ([1], zeros((2,), dtype=[('x', int), ('y', float)]))) - raises(TypeError, concatenate, (['abc'], zeros((2,), + assert str(exc.value).startswith('invalid type promotion') + exc = raises(TypeError, concatenate, (['abc'], zeros((2,), dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') From noreply at buildbot.pypy.org Wed Mar 20 21:16:22 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:22 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: remove redundant check Message-ID: <20130320201622.82CA51C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62558:7341166639d1 Date: 2013-03-20 12:06 -0700 http://bitbucket.org/pypy/pypy/changeset/7341166639d1/ Log: remove redundant check diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -131,8 +131,6 @@ arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -265,10 +265,7 @@ def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - if ret: - return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, - space.wrap('imag not implemented for this dtype')) + return W_NDimArray(ret) def descr_set_real(self, space, w_value): # copy (broadcast) values into self From noreply at buildbot.pypy.org Wed Mar 20 21:16:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:23 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: improve test coverage Message-ID: <20130320201623.C340F1C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62559:4f6b118f7561 Date: 2013-03-20 12:40 -0700 http://bitbucket.org/pypy/pypy/changeset/4f6b118f7561/ Log: improve test coverage 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 @@ -294,10 +294,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.StringType) - return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -311,11 +307,6 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.UnicodeType) - return self - class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -527,7 +527,8 @@ b = a.real assert b == array(3) a.real = 1024 - assert a.real == 1024 + a.imag = 2048 + assert a.real == 1024 and a.imag == 2048 assert a.imag == array(4) assert b.dtype == dtype(float) a = array(4.0) From noreply at buildbot.pypy.org Wed Mar 20 21:16:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:24 +0100 (CET) Subject: [pypy-commit] pypy str-dtype-improvement: close about-to-be-merged branch Message-ID: <20130320201624.E9BB31C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: str-dtype-improvement Changeset: r62560:ffa7dd14b213 Date: 2013-03-20 12:46 -0700 http://bitbucket.org/pypy/pypy/changeset/ffa7dd14b213/ Log: close about-to-be-merged branch From noreply at buildbot.pypy.org Wed Mar 20 21:16:26 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:26 +0100 (CET) Subject: [pypy-commit] pypy default: merge str-dtype-improvement which allows concatenation of str and numerical arrays Message-ID: <20130320201626.2B25C1C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62561:0222524b2c0d Date: 2013-03-20 12:48 -0700 http://bitbucket.org/pypy/pypy/changeset/0222524b2c0d/ Log: merge str-dtype-improvement which allows concatenation of str and numerical arrays diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -49,8 +49,8 @@ return shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy() - loop.setslice(shape, self, impl) + impl = impl.copy(space) + loop.setslice(space, shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -245,12 +245,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self): + def copy(self, space): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.get_shape(), impl, self) + return loop.setslice(space, self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -281,7 +281,11 @@ def astype(self, space, dtype): new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) + if dtype.is_str_or_unicode(): + raise OperationError(space.w_NotImplementedError, space.wrap( + "astype(%s) not implemented yet" % self.dtype)) + else: + loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -50,7 +50,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self): + def copy(self, space): scalar = Scalar(self.dtype) scalar.value = self.value return scalar diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,12 +116,21 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + a_dt = arr.get_dtype() + if dtype.is_record_type() and a_dt.is_record_type(): + #Record types must match + for f in dtype.fields: + if f not in a_dt.fields or \ + dtype.fields[f] != a_dt.fields[f]: + raise OperationError(space.w_TypeError, + space.wrap("record type mismatch")) + elif dtype.is_record_type() or a_dt.is_record_type(): + raise OperationError(space.w_TypeError, + space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -277,6 +277,10 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) + def convert_to(self, dtype): + # if we reach here, the record fields are guarenteed to match. + return self + class W_CharacterBox(W_FlexibleBox): pass @@ -290,10 +294,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.StringType) - return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -307,11 +307,6 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.UnicodeType) - return self - class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -71,6 +71,8 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) + def build_and_convert(self, space, box): + return self.itemtype.build_and_convert(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -76,7 +76,7 @@ base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) arr = convert_to_array(space, w_value) - loop.flatiter_setitem(self.base, arr, start, step, length) + loop.flatiter_setitem(space, self.base, arr, start, step, length) def descr_iter(self): return self diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -258,17 +258,14 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy()) + return W_NDimArray(self.implementation.copy(space)) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - if ret: - return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, - space.wrap('imag not implemented for this dtype')) + return W_NDimArray(ret) def descr_set_real(self, space, w_value): # copy (broadcast) values into self 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind: + if dt1.kind == dt2.kind and not dt2.is_flexible_type(): return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,7 +434,23 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - else: + elif dt2.is_flexible_type(): + # For those operations that get here (concatenate, stack), + # flexible types take precedence over numeric type + if dt2.is_record_type(): + return dt2 + if dt1.is_str_or_unicode(): + if dt2.num == 18: + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + return dt2 + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -65,12 +65,19 @@ obj_iter.next() return out -setslice_driver = jit.JitDriver(name='numpy_setslice', +setslice_driver1 = jit.JitDriver(name='numpy_setslice1', greens = ['shapelen', 'dtype'], - reds = ['target', 'source', 'target_iter', - 'source_iter']) + reds = 'auto') +setslice_driver2 = jit.JitDriver(name='numpy_setslice2', + greens = ['shapelen', 'dtype'], + reds = 'auto') -def setslice(shape, target, source): +def setslice(space, shape, target, source): + if target.dtype.is_str_or_unicode(): + return setslice_build_and_convert(space, shape, target, source) + return setslice_to(space, shape, target, source) + +def setslice_to(space, shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -78,15 +85,26 @@ dtype = target.dtype shapelen = len(shape) while not target_iter.done(): - setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, - target=target, source=source, - target_iter=target_iter, - source_iter=source_iter) + setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +def setslice_build_and_convert(space, shape, target, source): + # note that unlike everything else, target and source here are + # array implementations, not arrays + target_iter = target.create_iter(shape) + source_iter = source.create_iter(shape) + dtype = target.dtype + shapelen = len(shape) + while not target_iter.done(): + setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem())) + target_iter.next() + source_iter.next() + return target + reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], @@ -358,17 +376,27 @@ ri.next() return res -flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', +flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1', greens = ['dtype'], reds = 'auto') -def flatiter_setitem(arr, val, start, step, length): +flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2', + greens = ['dtype'], + reds = 'auto') + +def flatiter_setitem(space, arr, val, start, step, length): + dtype = arr.get_dtype() + if dtype.is_str_or_unicode(): + return flatiter_setitem_build_and_convert(space, arr, val, start, step, length) + return flatiter_setitem_to(space, arr, val, start, step, length) + +def flatiter_setitem_to(space, arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver.jit_merge_point(dtype=dtype) + flatiter_setitem_driver1.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -377,6 +405,21 @@ # WTF numpy? val_iter.reset() +def flatiter_setitem_build_and_convert(space, arr, val, start, step, length): + dtype = arr.get_dtype() + arr_iter = arr.create_iter() + val_iter = val.create_iter() + arr_iter.next_skip_x(start) + while length > 0: + flatiter_setitem_driver2.jit_merge_point(dtype=dtype) + arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem())) + # need to repeat i_nput values until all assignments are done + arr_iter.next_skip_x(step) + length -= 1 + val_iter.next() + # WTF numpy? + val_iter.reset() + fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], reds = 'auto') @@ -461,18 +504,6 @@ val_arr.descr_getitem(space, w_idx)) iter.next() -copy_from_to_driver = jit.JitDriver(greens = ['dtype'], - reds = 'auto') - -def copy_from_to(from_, to, dtype): - from_iter = from_.create_iter() - to_iter = to.create_iter() - while not from_iter.done(): - copy_from_to_driver.jit_merge_point(dtype=dtype) - to_iter.setitem(from_iter.getitem().convert_to(dtype)) - to_iter.next() - from_iter.next() - byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') 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 @@ -527,7 +527,8 @@ b = a.real assert b == array(3) a.real = 1024 - assert a.real == 1024 + a.imag = 2048 + assert a.real == 1024 and a.imag == 2048 assert a.imag == array(4) assert b.dtype == dtype(float) a = array(4.0) 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 @@ -1480,6 +1480,32 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() + a = concatenate((array([1]), array(['abc']))) + assert str(a.dtype) == '|S3' + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' + a = concatenate((['abcdef'], ['abc'])) + assert a[0] == 'abcdef' + assert str(a.dtype) == '|S6' + + def test_record_concatenate(self): + # only an exact match can succeed + from numpypy import zeros, concatenate + a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), + zeros((2,),dtype=[('x', int), ('y', float)]))) + assert a.shape == (4,) + exc = raises(TypeError, concatenate, + (zeros((2,), dtype=[('x', int), ('y', float)]), + (zeros((2,), dtype=[('x', float), ('y', float)])))) + assert str(exc.value).startswith('record type mismatch') + exc = raises(TypeError, concatenate, ([1], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + exc = raises(TypeError, concatenate, (['abc'], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + + def test_std(self): from numpypy import array @@ -1650,6 +1676,12 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 + # scalar vs. array + try: + a = array([1, 2, 3.14156]).astype('S3').dtype + assert a.itemsize == 3 + except NotImplementedError: + skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array @@ -1955,7 +1987,7 @@ assert (a.transpose() == b).all() def test_flatiter(self): - from numpypy import array, flatiter, arange + from numpypy import array, flatiter, arange, zeros a = array([[10, 30], [40, 60]]) f_iter = a.flat assert f_iter.next() == 10 @@ -1971,6 +2003,9 @@ a = arange(10).reshape(5, 2) raises(IndexError, 'a.flat[(1, 2)]') assert a.flat.base is a + m = zeros((2,2), dtype='S3') + m.flat[1] = 1 + assert m[0,1] == '1' def test_flatiter_array_conv(self): from numpypy import array, dot 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 @@ -1635,6 +1635,7 @@ def get_size(self): return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1642,7 +1643,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) @@ -1683,6 +1684,20 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) + def build_and_convert(self, space, mydtype, box): + if box.get_dtype(space).is_str_or_unicode(): + arg = box.get_dtype(space).itemtype.to_str(box) + else: + w_arg = box.descr_str(space) + arg = space.str_w(space.str(w_arg)) + arr = VoidBoxStorage(self.size, mydtype) + i = 0 + for i in range(min(len(arg), self.size)): + arr.storage[i] = arg[i] + for j in range(i + 1, self.size): + arr.storage[j] = '\x00' + return interp_boxes.W_StringBox(arr, 0, arr.dtype) + class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Wed Mar 20 21:16:27 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:27 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups and small fixes of str-dtypes-improvement Message-ID: <20130320201627.6D0FA1C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62562:b9c5e3df5a82 Date: 2013-03-20 13:11 -0700 http://bitbucket.org/pypy/pypy/changeset/b9c5e3df5a82/ Log: cleanups and small fixes of str-dtypes-improvement diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -77,12 +77,9 @@ "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) if self.dtype.is_complex_type(): - #imag = dtype.itemtype.unbox(self.value.convert_imag_to(dtype)) - #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). - # convert_to(dtype)) - #self.value = self.dtype.box_complex(val, imag) - self.value = self.dtype.itemtype.composite(w_arr.get_scalar_value().convert_to(dtype), - self.value.convert_imag_to(dtype)) + self.value = self.dtype.itemtype.composite( + w_arr.get_scalar_value().convert_to(dtype), + self.value.convert_imag_to(dtype)) else: self.value = w_arr.get_scalar_value() @@ -108,13 +105,9 @@ "could not broadcast input array from shape " + "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) - #real = dtype.itemtype.unbox(self.value.convert_real_to(dtype)) - #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). - # convert_to(dtype)) - #self.value = self.dtype.box_complex(real, val) self.value = self.dtype.itemtype.composite( self.value.convert_real_to(dtype), - w_arr.get_scalar_value(), + w_arr.get_scalar_value().convert_to(dtype), ) def descr_getitem(self, space, _, w_idx): 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 @@ -526,17 +526,20 @@ a = array(complex(3.0, 4.0)) b = a.real assert b == array(3) + assert a.imag == array(4) a.real = 1024 a.imag = 2048 assert a.real == 1024 and a.imag == 2048 - assert a.imag == array(4) assert b.dtype == dtype(float) a = array(4.0) b = a.imag assert b == 0 assert b.dtype == dtype(float) - raises(TypeError, 'a.imag = 1024') - raises(ValueError, 'a.real = [1, 3]') + exc = raises(TypeError, 'a.imag = 1024') + assert str(exc.value).startswith("array does not have imaginary") + exc = raises(ValueError, 'a.real = [1, 3]') + assert str(exc.value) == \ + "could not broadcast input array from shape (2) into shape ()" a = array('abc') assert str(a.real) == 'abc' # numpy imag for flexible types returns self @@ -610,8 +613,10 @@ assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' # numpy actually raises an AttributeError, # but numpypy raises a TypeError - raises((TypeError, AttributeError), 'c2.real = 10.') - raises((TypeError, AttributeError), 'c2.imag = 10.') + exc = raises((TypeError, AttributeError), 'c2.real = 10.') + assert str(exc.value) == "readonly attribute" + exc = raises((TypeError, AttributeError), 'c2.imag = 10.') + assert str(exc.value) == "readonly attribute" assert(real(c2) == 3.0) assert(imag(c2) == 4.0) From noreply at buildbot.pypy.org Wed Mar 20 21:16:28 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:28 +0100 (CET) Subject: [pypy-commit] pypy default: document branch Message-ID: <20130320201628.94D521C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62563:39ad5d9ff56d Date: 2013-03-20 13:13 -0700 http://bitbucket.org/pypy/pypy/changeset/39ad5d9ff56d/ Log: document branch 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 @@ -20,16 +20,22 @@ .. branch: numpypy-longdouble Long double support for numpypy + .. branch: numpypy-disable-longdouble Since r_longdouble support is missing, disable all longdouble and derivative dtypes using ENABLED_LONG_DOUBLE = False + .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality + .. branch: indexing-by-array Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. +.. branch: str-dtype-improvement +Allow concatenation of str and numeric arrays + .. branch: signatures Improved RPython typing From noreply at buildbot.pypy.org Wed Mar 20 21:16:29 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:16:29 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130320201629.CED391C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62564:fe2fef48ab4e Date: 2013-03-20 13:15 -0700 http://bitbucket.org/pypy/pypy/changeset/fe2fef48ab4e/ Log: merge heads diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,19 +106,16 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def setitem(self, w_key, w_value): - self.strategy.setitem(self, w_key, w_value) - def setitem_str(self, key, w_value): self.strategy.setitem_str(self, key, w_value) def _add_indirections(): - dict_methods = "getitem \ - getitem_str delitem length \ - clear w_keys values \ - items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int \ + dict_methods = "getitem getitem_str setitem setdefault \ + popitem delitem clear \ + length w_keys values items \ + iterkeys itervalues iteritems \ + listview_str listview_unicode listview_int \ view_as_kwargs".split() def make_method(method): From noreply at buildbot.pypy.org Wed Mar 20 21:17:11 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:17:11 +0100 (CET) Subject: [pypy-commit] pypy default: (fijal, alex) Removed spli/ directory, Message-ID: <20130320201711.184FF1C03A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62565:8ed70c17c0ed Date: 2013-03-20 13:16 -0700 http://bitbucket.org/pypy/pypy/changeset/8ed70c17c0ed/ Log: (fijal, alex) Removed spli/ directory, diff --git a/spli/__init__.py b/spli/__init__.py deleted file mode 100644 diff --git a/spli/examples.py b/spli/examples.py deleted file mode 100644 --- a/spli/examples.py +++ /dev/null @@ -1,16 +0,0 @@ - -def f(): - return 1 - -print f() - -def adder(a, b): - return a + b - -def while_loop(): - i = 0 - while i < 10000000: - i = i + 1 - return None - -while_loop() diff --git a/spli/execution.py b/spli/execution.py deleted file mode 100644 --- a/spli/execution.py +++ /dev/null @@ -1,47 +0,0 @@ -from spli import interpreter, objects, pycode - - -def run_from_cpython_code(co, args=[], locs=None, globs=None): - space = objects.DumbObjSpace() - pyco = pycode.Code._from_code(space, co) - return run(pyco, [space.wrap(arg) for arg in args], locs, globs) - -def run(pyco, args, locs=None, globs=None): - frame = interpreter.SPLIFrame(pyco, locs, globs) - frame.set_args(args) - return get_ec().execute_frame(frame) - - -def get_ec(): - ec = state.get() - if ec is None: - ec = ExecutionContext() - state.set(ec) - return ec - - -class State(object): - - def __init__(self): - self.value = None - - def get(self): - return self.value - - def set(self, new): - self.value = new - -state = State() - - -class ExecutionContext(object): - - def __init__(self): - self.framestack = [] - - def execute_frame(self, frame): - self.framestack.append(frame) - try: - return frame.run() - finally: - self.framestack.pop() diff --git a/spli/interpreter.py b/spli/interpreter.py deleted file mode 100644 --- a/spli/interpreter.py +++ /dev/null @@ -1,241 +0,0 @@ -import os -from rpython.tool import stdlib_opcode -from spli import objects, pycode -from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.jit import JitDriver, promote, dont_look_inside -from rpython.rlib.objectmodel import we_are_translated - -opcode_method_names = stdlib_opcode.host_bytecode_spec.method_names -unrolling_opcode_descs = unrolling_iterable( - stdlib_opcode.host_bytecode_spec.ordered_opdescs) -HAVE_ARGUMENT = stdlib_opcode.host_HAVE_ARGUMENT - -compare_ops = [ - "cmp_lt", # "<" - "cmp_le", # "<=" - "cmp_eq", # "==" - "cmp_ne", # "!=" - "cmp_gt", # ">" - "cmp_ge", # ">=" -# "cmp_in", -# "cmp_not_in", -# "cmp_is", -# "cmp_is_not", -# "cmp_exc_match", -] -unrolling_compare_dispatch_table = unrolling_iterable( - enumerate(compare_ops)) - -jitdriver = JitDriver(greens = ['instr_index', 'code'], - reds = ['frame'], - virtualizables = ['frame']) - - -class BlockUnroller(Exception): - pass - -class Return(BlockUnroller): - - def __init__(self, value): - self.value = value - -class MissingOpcode(Exception): - pass - -class SPLIFrame(object): - - _virtualizable2_ = ['value_stack[*]', 'locals[*]', 'stack_depth'] - - @dont_look_inside - def __init__(self, code, locs=None, globs=None): - self.code = code - self.value_stack = [None] * code.co_stacksize - self.locals = [None] * code.co_nlocals - if locs is not None: - self.locals_dict = locs - else: - self.locals_dict = {} - if globs is not None: - self.globs = globs - else: - self.globs = {} - self.stack_depth = 0 - - def set_args(self, args): - for i in range(len(args)): - self.locals[i] = args[i] - - def run(self): - self.stack_depth = 0 - try: - self._dispatch_loop() - except Return, ret: - return ret.value - - def _dispatch_loop(self): - code = self.code.co_code - instr_index = 0 - while True: - jitdriver.jit_merge_point(code=code, instr_index=instr_index, - frame=self) - self.stack_depth = promote(self.stack_depth) - op = ord(code[instr_index]) - instr_index += 1 - if op >= HAVE_ARGUMENT: - low = ord(code[instr_index]) - hi = ord(code[instr_index + 1]) - oparg = (hi << 8) | low - instr_index += 2 - else: - oparg = 0 - if we_are_translated(): - for opdesc in unrolling_opcode_descs: - if op == opdesc.index: - meth = getattr(self, opdesc.methodname) - instr_index = meth(oparg, instr_index, code) - break - else: - raise MissingOpcode(op) - else: - meth = getattr(self, opcode_method_names[op]) - instr_index = meth(oparg, instr_index, code) - - def push(self, value): - self.value_stack[self.stack_depth] = value - self.stack_depth += 1 - - def pop(self): - sd = self.stack_depth - 1 - assert sd >= 0 - self.stack_depth = sd - val = self.value_stack[sd] - self.value_stack[sd] = None - return val - - def pop_many(self, n): - return [self.pop() for i in range(n)] - - def peek(self): - sd = self.stack_depth - 1 - assert sd >= 0 - return self.value_stack[sd] - - def POP_TOP(self, _, next_instr, code): - self.pop() - return next_instr - - def LOAD_FAST(self, name_index, next_instr, code): - assert name_index >= 0 - self.push(self.locals[name_index]) - return next_instr - - def STORE_FAST(self, name_index, next_instr, code): - assert name_index >= 0 - self.locals[name_index] = self.pop() - return next_instr - - def LOAD_NAME(self, name_index, next_instr, code): - name = self.code.co_names[name_index] - self.push(self.locals_dict[name]) - return next_instr - - def STORE_NAME(self, name_index, next_instr, code): - name = self.code.co_names[name_index] - self.locals_dict[name] = self.pop() - return next_instr - - def LOAD_GLOBAL(self, name_index, next_instr, code): - name = self.code.co_names[name_index] - self.push(self.globs[name]) - return next_instr - - def STORE_GLOBAL(self, name_index, next_instr, code): - name = self.code.co_names[name_index] - self.globs[name] = self.pop() - return next_instr - - def RETURN_VALUE(self, _, next_instr, code): - raise Return(self.pop()) - - def LOAD_CONST(self, const_index, next_instr, code): - self.push(self.code.co_consts_w[const_index]) - return next_instr - - def BINARY_ADD(self, _, next_instr, code): - right = self.pop() - left = self.pop() - self.push(left.add(right)) - return next_instr - - def BINARY_SUBTRACT(self, _, next_instr, code): - right = self.pop() - left = self.pop() - self.push(left.sub(right)) - return next_instr - - def BINARY_AND(self, _, next_instr, code): - right = self.pop() - left = self.pop() - self.push(left.and_(right)) - return next_instr - - def SETUP_LOOP(self, _, next_instr, code): - return next_instr - - def POP_BLOCK(self, _, next_instr, code): - return next_instr - - def JUMP_IF_FALSE(self, arg, next_instr, code): - w_cond = self.peek() - if not w_cond.is_true(): - next_instr += arg - return next_instr - - def POP_JUMP_IF_FALSE(self, arg, next_instr, code): - w_cond = self.pop() - if not w_cond.is_true(): - next_instr = arg - return next_instr - - def JUMP_FORWARD(self, arg, next_instr, code): - return next_instr + arg - - def JUMP_ABSOLUTE(self, arg, next_instr, code): - jitdriver.can_enter_jit(frame=self, code=code, instr_index=arg) - return arg - - def COMPARE_OP(self, arg, next_instr, code): - right = self.pop() - left = self.pop() - for num, name in unrolling_compare_dispatch_table: - if num == arg: - self.push(getattr(left, name)(right)) - return next_instr - - def MAKE_FUNCTION(self, _, next_instr, code): - func_code = self.pop().as_interp_class(pycode.Code) - func = objects.Function(func_code, self.globs) - self.push(func) - return next_instr - - def CALL_FUNCTION(self, arg_count, next_instr, code): - args = self.pop_many(arg_count) - func = self.pop() - self.push(func.call(args)) - return next_instr - - def PRINT_ITEM(self, _, next_instr, code): - value = self.pop().repr().as_str() - os.write(1, value) - return next_instr - - def PRINT_NEWLINE(self, _, next_instr, code): - os.write(1, '\n') - return next_instr - - -items = [] -for item in unrolling_opcode_descs._items: - if getattr(SPLIFrame, item.methodname, None) is not None: - items.append(item) -unrolling_opcode_descs = unrolling_iterable(items) diff --git a/spli/objects.py b/spli/objects.py deleted file mode 100644 --- a/spli/objects.py +++ /dev/null @@ -1,158 +0,0 @@ -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -from rpython.rlib.objectmodel import specialize - -class DumbObjSpace(ObjSpace): - """Implement just enough of the ObjSpace API to satisfy PyCode.""" - - @specialize.argtype(1) - def wrap(self, x): - if isinstance(x, int): - return Int(x) - elif isinstance(x, str): - return Str(x) - elif x is None: - return spli_None - elif isinstance(x, Wrappable): - return x.__spacebind__(self) - elif isinstance(x, SPLIObject): - return x # Already done. - else: - raise NotImplementedError("Wrapping %s" % x) - - def new_interned_str(self, x): - return self.wrap(x) - - -class SPLIException(Exception): - pass - - -class W_TypeError(SPLIException): - pass - - -class SPLIObject(object): - - def add(self, other): - raise W_TypeError - - def sub(self, other): - raise W_TypeError - - def and_(self, other): - raise W_TypeError - - def call(self, args): - raise W_TypeError - - def cmp_lt(self, other): - raise W_TypeError - - def cmp_gt(self, other): - raise W_TypeError - - def cmp_eq(self, other): - raise W_TypeError - - def cmp_ne(self, other): - raise W_TypeError - - def cmp_ge(self, other): - raise W_TypeError - - def cmp_le(self, other): - raise W_TypeError - - def as_int(self): - raise W_TypeError - - def as_str(self): - raise W_TypeError - - def repr(self): - return Str("") - - def is_true(self): - raise W_TypeError - - def as_interp_class(self, cls): - if not isinstance(self, cls): - raise W_TypeError - return self - - -class Bool(SPLIObject): - - def __init__(self, value): - self.value = value - - def is_true(self): - return self.value - - def repr(self): - if self.is_true(): - name = "True" - else: - name = "False" - return Str(name) - - -class Int(SPLIObject): - - def __init__(self, value): - self.value = value - - def add(self, other): - return Int(self.value + other.as_int()) - - def sub(self, other): - return Int(self.value - other.as_int()) - - def and_(self, other): - return Int(self.value & other.as_int()) - - def cmp_lt(self, other): - return Bool(self.value < other.as_int()) - - def as_int(self): - return self.value - - def is_true(self): - return bool(self.value) - - def repr(self): - return Str(str(self.value)) - - -class Str(SPLIObject): - - def __init__(self, value): - self.value = value - - def as_str(self): - return self.value - - def add(self, other): - return Str(self.value + other.as_str()) - - def repr(self): - return Str("'" + self.value + "'") - - -class SPLINone(SPLIObject): - - def repr(self): - return Str('None') - -spli_None = SPLINone() - - -class Function(SPLIObject): - - def __init__(self, code, globs): - self.code = code - self.globs = globs - - def call(self, args): - from spli import execution - return execution.run(self.code, args, None, self.globs) diff --git a/spli/pycode.py b/spli/pycode.py deleted file mode 100644 --- a/spli/pycode.py +++ /dev/null @@ -1,22 +0,0 @@ -from pypy.interpreter import pycode -from spli import objects - - -class Code(objects.SPLIObject): - - def __init__(self, argcount, nlocals, stacksize, code, consts, names): - """Initialize a new code object from parameters given by - the pypy compiler""" - self.co_argcount = argcount - self.co_nlocals = nlocals - self.co_stacksize = stacksize - self.co_code = code - self.co_consts_w = consts - self.co_names = names - - @classmethod - def _from_code(cls, space, code, hidden_applevel=False, code_hook=None): - pyco = pycode.PyCode._from_code(space, code, code_hook=cls._from_code) - return cls(pyco.co_argcount, pyco.co_nlocals, pyco.co_stacksize, - pyco.co_code, pyco.co_consts_w, - [name.as_str() for name in pyco.co_names_w]) diff --git a/spli/serializer.py b/spli/serializer.py deleted file mode 100644 --- a/spli/serializer.py +++ /dev/null @@ -1,116 +0,0 @@ - -""" Usage: -serialize.py python_file func_name output_file -""" - -import py -import sys -import types -from spli.objects import Int, Str, spli_None -from spli.pycode import Code -from rpython.rlib.rstruct.runpack import runpack -import struct - -FMT = 'iiii' -int_lgt = len(struct.pack('i', 0)) -header_lgt = int_lgt * len(FMT) - -class NotSupportedFormat(Exception): - pass - -def serialize_str(value): - return struct.pack('i', len(value)) + value - -def unserialize_str(data, start): - end_lgt = start + int_lgt - lgt = runpack('i', data[start:end_lgt]) - assert lgt >= 0 - end_str = end_lgt + lgt - return data[end_lgt:end_str], end_str - -def serialize_const(const): - if isinstance(const, int): - return 'd' + struct.pack('i', const) - elif isinstance(const, str): - return 's' + serialize_str(const) - elif const is None: - return 'n' - elif isinstance(const, types.CodeType): - return 'c' + serialize(const) - else: - raise NotSupportedFormat(str(const)) - -def unserialize_const(c, start): - assert start >= 0 - if c[start] == 'd': - end = start + int_lgt + 1 - intval = runpack('i', c[start + 1:end]) - return Int(intval), end - elif c[start] == 's': - value, end = unserialize_str(c, start + 1) - return Str(value), end - elif c[start] == 'n': - return spli_None, start + 1 - elif c[start] == 'c': - return unserialize_code(c, start + 1) - else: - raise NotSupportedFormat(c[start]) - -def unserialize_consts(constrepr): - pos = int_lgt - consts_w = [] - num = runpack('i', constrepr[:int_lgt]) - for i in range(num): - next_const, pos = unserialize_const(constrepr, pos) - consts_w.append(next_const) - return consts_w, pos - -def unserialize_names(namesrepr, num): - pos = 0 - names = [] - for i in range(num): - name, pos = unserialize_str(namesrepr, pos) - names.append(name) - return names, pos - -def unserialize_code(coderepr, start=0): - coderepr = coderepr[start:] - header = coderepr[:header_lgt] - argcount, nlocals, stacksize, code_len = runpack(FMT, header) - assert code_len >= 0 - names_pos = code_len + header_lgt - code = coderepr[header_lgt:names_pos] - num = runpack('i', coderepr[names_pos:names_pos + int_lgt]) - names, end_names = unserialize_names(coderepr[names_pos + int_lgt:], num) - const_start = names_pos + int_lgt + end_names - consts, pos = unserialize_consts(coderepr[const_start:]) - pos = start + const_start + pos - return Code(argcount, nlocals, stacksize, code, consts, names), pos - -# ------------------- PUBLIC API ---------------------- - -def serialize(code): - header = struct.pack(FMT, code.co_argcount, code.co_nlocals, - code.co_stacksize, len(code.co_code)) - namesrepr = (struct.pack('i', len(code.co_names)) + - "".join(serialize_str(name) for name in code.co_names)) - constsrepr = (struct.pack('i', len(code.co_consts)) + - "".join([serialize_const(const) for const in code.co_consts])) - return header + code.co_code + namesrepr + constsrepr - -def deserialize(data, start=0): - return unserialize_code(data)[0] - -def main(argv): - if len(argv) != 3: - print __doc__ - sys.exit(1) - code_file = argv[1] - mod = py.path.local(code_file).read() - r = serialize(compile(mod, code_file, "exec")) - outfile = py.path.local(argv[2]) - outfile.write(r) - -if __name__ == '__main__': - import sys - main(sys.argv) diff --git a/spli/targetspli.py b/spli/targetspli.py deleted file mode 100644 --- a/spli/targetspli.py +++ /dev/null @@ -1,38 +0,0 @@ - -""" usage: spli-c code_obj_file [i:int_arg s:s_arg ...] -""" - -import sys, os -from spli import execution, serializer, objects -from rpython.rlib.streamio import open_file_as_stream - - -def unwrap_arg(arg): - if arg.startswith('s:'): - return objects.Str(arg[2:]) - elif arg.startswith('i:'): - return objects.Int(int(arg[2:])) - else: - raise NotImplementedError - -def entry_point(argv): - if len(argv) < 2: - print __doc__ - os._exit(1) - args = argv[2:] - stream = open_file_as_stream(argv[1]) - co = serializer.deserialize(stream.readall()) - w_args = [unwrap_arg(args[i]) for i in range(len(args))] - execution.run(co, w_args) - return 0 - -def target(drver, args): - return entry_point, None - -def jitpolicy(driver): - """Returns the JIT policy to use when translating.""" - from rpython.jit.codewriter.policy import JitPolicy - return JitPolicy() - -if __name__ == '__main__': - entry_point(sys.argv) diff --git a/spli/test/__init__.py b/spli/test/__init__.py deleted file mode 100644 diff --git a/spli/test/test_interpreter.py b/spli/test/test_interpreter.py deleted file mode 100644 --- a/spli/test/test_interpreter.py +++ /dev/null @@ -1,113 +0,0 @@ -import py -import os -from spli import execution, objects - -class TestSPLIInterpreter: - - def eval(self, func, args=[]): - return execution.run_from_cpython_code(func.func_code, args) - - def test_int_add(self): - def f(): - return 4 + 6 - v = self.eval(f) - assert isinstance(v, objects.Int) - assert v.value == 10 - def f(): - a = 4 - return a + 6 - assert self.eval(f).value == 10 - - def test_str(self): - def f(): - return "Hi!" - v = self.eval(f) - assert isinstance(v, objects.Str) - assert v.value == "Hi!" - def f(): - a = "Hello, " - return a + "SPLI world!" - v = self.eval(f) - assert isinstance(v, objects.Str) - assert v.value == "Hello, SPLI world!" - - def test_comparison(self): - def f(i): - return i < 10 - - v = self.eval(f, [0]) - assert isinstance(v, objects.Bool) - assert v.value == True - - def test_while_loop(self): - def f(): - i = 0 - while i < 100: - i = i + 1 - return i - - v = self.eval(f) - assert v.value == 100 - - def test_invalid_adds(self): - def f(): - "3" + 3 - py.test.raises(objects.W_TypeError, self.eval, f) - def f(): - 3 + "3" - py.test.raises(objects.W_TypeError, self.eval, f) - - def test_call(self): - code = compile(""" -def g(): - return 4 -def f(): - return g() + 3 -res = f()""", "", "exec") - globs = {} - mod_res = execution.run_from_cpython_code(code, [], globs, globs) - assert mod_res is objects.spli_None - assert len(globs) == 3 - assert globs["res"].as_int() == 7 - - def test_print(self): - def f(thing): - print thing - things = ( - ("x", "'x'"), - (4, "4"), - (True, "True"), - (False, "False"), - ) - def mock_os_write(fd, what): - assert fd == 1 - buf.append(what) - save = os.write - os.write = mock_os_write - try: - for obj, res in things: - buf = [] - assert self.eval(f, [obj]) is objects.spli_None - assert "".join(buf) == res + '\n' - finally: - os.write = save - - def test_binary_op(self): - def f(a, b): - return a & b - a - - v = self.eval(f, [1, 2]) - assert v.value == f(1, 2) - - def test_while_2(self): - def f(a, b): - total = 0 - i = 0 - while i < 100: - if i & 1: - total = total + a - else: - total = total + b - i = i + 1 - return total - assert self.eval(f, [1, 10]).value == f(1, 10) diff --git a/spli/test/test_jit.py b/spli/test/test_jit.py deleted file mode 100644 --- a/spli/test/test_jit.py +++ /dev/null @@ -1,74 +0,0 @@ - -import py -from rpython.jit.metainterp.test.support import JitMixin -from spli import interpreter, objects, serializer -from rpython.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper -from rpython.jit.backend.llgraph import runner -from rpython.rtyper.annlowlevel import llstr, hlstr - -class TestSPLIJit(JitMixin): - type_system = 'lltype' - CPUClass = runner.LLGraphCPU - - def interpret(self, f, args): - coderepr = serializer.serialize(f.func_code) - arg_params = ", ".join(['arg%d' % i for i in range(len(args))]) - arg_ass = ";".join(['frame.locals[%d] = space.wrap(arg%d)' % (i, i) for - i in range(len(args))]) - space = objects.DumbObjSpace() - source = py.code.Source(""" - def bootstrap(%(arg_params)s): - co = serializer.deserialize(coderepr) - frame = interpreter.SPLIFrame(co) - %(arg_ass)s - return frame.run() - """ % locals()) - d = globals().copy() - d['coderepr'] = coderepr - d['space'] = space - exec source.compile() in d - return self.meta_interp(d['bootstrap'], args, listops=True) - - def test_basic(self): - def f(): - i = 0 - while i < 20: - i = i + 1 - return i - self.interpret(f, []) - self.check_resops(new_with_vtable=0) - - def test_bridge(self): - py.test.skip('We currently cant virtualize across bridges') - def f(a, b): - total = 0 - i = 0 - while i < 100: - if i & 1: - total = total + a - else: - total = total + b - i = i + 1 - return total - - self.interpret(f, [1, 10]) - self.check_resops(new_with_vtable=0) - - def test_bridge_bad_case(self): - py.test.skip('We currently cant virtualize across bridges') - def f(a, b): - i = 0 - while i < 100: - if i & 1: - a = a + 1 - else: - b = b + 1 - i = i + 1 - return a + b - - self.interpret(f, [1, 10]) - self.check_resops(new_with_vtable=1) # XXX should eventually be 0? - # I think it should be either 0 or 2, 1 makes little sense - # If the loop after entering goes first time to the bridge, a - # is rewrapped again, without preserving the identity. I'm not - # sure how bad it is diff --git a/spli/test/test_serializer.py b/spli/test/test_serializer.py deleted file mode 100644 --- a/spli/test/test_serializer.py +++ /dev/null @@ -1,30 +0,0 @@ -from spli.serializer import serialize, deserialize -from spli import execution, pycode, objects - -class TestSerializer(object): - - def eval(self, code, args=[]): - return execution.run(code, args) - - def test_basic(self): - def f(): - return 1 - - coderepr = serialize(f.func_code) - code = deserialize(coderepr) - assert code.co_nlocals == f.func_code.co_nlocals - assert code.co_argcount == 0 - assert code.co_stacksize == f.func_code.co_stacksize - assert code.co_names == [] - assert self.eval(code).value == 1 - - def test_nested_code_objects(self): - mod = """ -def f(): return 1 -f()""" - data = serialize(compile(mod, "spli", "exec")) - spli_code = deserialize(data) - assert len(spli_code.co_consts_w) == 2 - assert isinstance(spli_code.co_consts_w[0], pycode.Code) - assert spli_code.co_consts_w[0].co_consts_w[0] is objects.spli_None - assert spli_code.co_consts_w[0].co_consts_w[1].as_int() == 1 diff --git a/spli/test/test_translated.py b/spli/test/test_translated.py deleted file mode 100644 --- a/spli/test/test_translated.py +++ /dev/null @@ -1,24 +0,0 @@ - -from rpython.rtyper.test.test_llinterp import interpret -from spli import execution, objects -from spli.serializer import serialize, deserialize - -class TestSPLITranslated(object): - - def test_one(self): - def f(a, b): - return a + b - data = serialize(f.func_code) - space = objects.DumbObjSpace() - def run(a, b): - co = deserialize(data) - args = [] - args.append(space.wrap(a)) - args.append(space.wrap(b)) - w_res = execution.run(co, args) - assert isinstance(w_res, objects.Int) - return w_res.value - - assert run(2, 3) == 5 - res = interpret(run, [2, 3]) - assert res == 5 From noreply at buildbot.pypy.org Wed Mar 20 21:17:12 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:17:12 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130320201712.7540E1C03A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62566:8090d3a2b6db Date: 2013-03-20 13:16 -0700 http://bitbucket.org/pypy/pypy/changeset/8090d3a2b6db/ Log: merged upstream diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -12,6 +12,10 @@ import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from itertools import imap as _imap +try: + from __pypy__ import newdict +except ImportError: + newdict = lambda _ : {} try: from thread import get_ident as _get_ident @@ -326,8 +330,11 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = newdict('module') + namespace['OrderedDict'] = OrderedDict + namespace['_property'] = property + namespace['_tuple'] = tuple + namespace['__name__'] = 'namedtuple_%s' % typename try: exec template in namespace except SyntaxError, e: 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 @@ -20,16 +20,22 @@ .. branch: numpypy-longdouble Long double support for numpypy + .. branch: numpypy-disable-longdouble Since r_longdouble support is missing, disable all longdouble and derivative dtypes using ENABLED_LONG_DOUBLE = False + .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality + .. branch: indexing-by-array Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. +.. branch: str-dtype-improvement +Allow concatenation of str and numeric arrays + .. branch: signatures Improved RPython typing diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -49,8 +49,8 @@ return shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy() - loop.setslice(shape, self, impl) + impl = impl.copy(space) + loop.setslice(space, shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -245,12 +245,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self): + def copy(self, space): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.get_shape(), impl, self) + return loop.setslice(space, self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -281,7 +281,11 @@ def astype(self, space, dtype): new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) + if dtype.is_str_or_unicode(): + raise OperationError(space.w_NotImplementedError, space.wrap( + "astype(%s) not implemented yet" % self.dtype)) + else: + loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -50,7 +50,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self): + def copy(self, space): scalar = Scalar(self.dtype) scalar.value = self.value return scalar @@ -77,12 +77,9 @@ "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) if self.dtype.is_complex_type(): - #imag = dtype.itemtype.unbox(self.value.convert_imag_to(dtype)) - #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). - # convert_to(dtype)) - #self.value = self.dtype.box_complex(val, imag) - self.value = self.dtype.itemtype.composite(w_arr.get_scalar_value().convert_to(dtype), - self.value.convert_imag_to(dtype)) + self.value = self.dtype.itemtype.composite( + w_arr.get_scalar_value().convert_to(dtype), + self.value.convert_imag_to(dtype)) else: self.value = w_arr.get_scalar_value() @@ -108,13 +105,9 @@ "could not broadcast input array from shape " + "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) - #real = dtype.itemtype.unbox(self.value.convert_real_to(dtype)) - #val = dtype.itemtype.unbox(w_arr.get_scalar_value(). - # convert_to(dtype)) - #self.value = self.dtype.box_complex(real, val) self.value = self.dtype.itemtype.composite( self.value.convert_real_to(dtype), - w_arr.get_scalar_value(), + w_arr.get_scalar_value().convert_to(dtype), ) def descr_getitem(self, space, _, w_idx): diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,12 +116,21 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + a_dt = arr.get_dtype() + if dtype.is_record_type() and a_dt.is_record_type(): + #Record types must match + for f in dtype.fields: + if f not in a_dt.fields or \ + dtype.fields[f] != a_dt.fields[f]: + raise OperationError(space.w_TypeError, + space.wrap("record type mismatch")) + elif dtype.is_record_type() or a_dt.is_record_type(): + raise OperationError(space.w_TypeError, + space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -277,6 +277,10 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) + def convert_to(self, dtype): + # if we reach here, the record fields are guarenteed to match. + return self + class W_CharacterBox(W_FlexibleBox): pass @@ -290,10 +294,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.StringType) - return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -307,11 +307,6 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.UnicodeType) - return self - class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -71,6 +71,8 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) + def build_and_convert(self, space, box): + return self.itemtype.build_and_convert(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -76,7 +76,7 @@ base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) arr = convert_to_array(space, w_value) - loop.flatiter_setitem(self.base, arr, start, step, length) + loop.flatiter_setitem(space, self.base, arr, start, step, length) def descr_iter(self): return self diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -258,17 +258,14 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy()) + return W_NDimArray(self.implementation.copy(space)) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - if ret: - return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, - space.wrap('imag not implemented for this dtype')) + return W_NDimArray(ret) def descr_set_real(self, space, w_value): # copy (broadcast) values into self 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind: + if dt1.kind == dt2.kind and not dt2.is_flexible_type(): return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,7 +434,23 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - else: + elif dt2.is_flexible_type(): + # For those operations that get here (concatenate, stack), + # flexible types take precedence over numeric type + if dt2.is_record_type(): + return dt2 + if dt1.is_str_or_unicode(): + if dt2.num == 18: + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + return dt2 + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -65,12 +65,19 @@ obj_iter.next() return out -setslice_driver = jit.JitDriver(name='numpy_setslice', +setslice_driver1 = jit.JitDriver(name='numpy_setslice1', greens = ['shapelen', 'dtype'], - reds = ['target', 'source', 'target_iter', - 'source_iter']) + reds = 'auto') +setslice_driver2 = jit.JitDriver(name='numpy_setslice2', + greens = ['shapelen', 'dtype'], + reds = 'auto') -def setslice(shape, target, source): +def setslice(space, shape, target, source): + if target.dtype.is_str_or_unicode(): + return setslice_build_and_convert(space, shape, target, source) + return setslice_to(space, shape, target, source) + +def setslice_to(space, shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -78,15 +85,26 @@ dtype = target.dtype shapelen = len(shape) while not target_iter.done(): - setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, - target=target, source=source, - target_iter=target_iter, - source_iter=source_iter) + setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +def setslice_build_and_convert(space, shape, target, source): + # note that unlike everything else, target and source here are + # array implementations, not arrays + target_iter = target.create_iter(shape) + source_iter = source.create_iter(shape) + dtype = target.dtype + shapelen = len(shape) + while not target_iter.done(): + setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem())) + target_iter.next() + source_iter.next() + return target + reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], @@ -358,17 +376,27 @@ ri.next() return res -flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', +flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1', greens = ['dtype'], reds = 'auto') -def flatiter_setitem(arr, val, start, step, length): +flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2', + greens = ['dtype'], + reds = 'auto') + +def flatiter_setitem(space, arr, val, start, step, length): + dtype = arr.get_dtype() + if dtype.is_str_or_unicode(): + return flatiter_setitem_build_and_convert(space, arr, val, start, step, length) + return flatiter_setitem_to(space, arr, val, start, step, length) + +def flatiter_setitem_to(space, arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver.jit_merge_point(dtype=dtype) + flatiter_setitem_driver1.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -377,6 +405,21 @@ # WTF numpy? val_iter.reset() +def flatiter_setitem_build_and_convert(space, arr, val, start, step, length): + dtype = arr.get_dtype() + arr_iter = arr.create_iter() + val_iter = val.create_iter() + arr_iter.next_skip_x(start) + while length > 0: + flatiter_setitem_driver2.jit_merge_point(dtype=dtype) + arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem())) + # need to repeat i_nput values until all assignments are done + arr_iter.next_skip_x(step) + length -= 1 + val_iter.next() + # WTF numpy? + val_iter.reset() + fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], reds = 'auto') @@ -461,18 +504,6 @@ val_arr.descr_getitem(space, w_idx)) iter.next() -copy_from_to_driver = jit.JitDriver(greens = ['dtype'], - reds = 'auto') - -def copy_from_to(from_, to, dtype): - from_iter = from_.create_iter() - to_iter = to.create_iter() - while not from_iter.done(): - copy_from_to_driver.jit_merge_point(dtype=dtype) - to_iter.setitem(from_iter.getitem().convert_to(dtype)) - to_iter.next() - from_iter.next() - byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') 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 @@ -526,16 +526,20 @@ a = array(complex(3.0, 4.0)) b = a.real assert b == array(3) + assert a.imag == array(4) a.real = 1024 - assert a.real == 1024 - assert a.imag == array(4) + a.imag = 2048 + assert a.real == 1024 and a.imag == 2048 assert b.dtype == dtype(float) a = array(4.0) b = a.imag assert b == 0 assert b.dtype == dtype(float) - raises(TypeError, 'a.imag = 1024') - raises(ValueError, 'a.real = [1, 3]') + exc = raises(TypeError, 'a.imag = 1024') + assert str(exc.value).startswith("array does not have imaginary") + exc = raises(ValueError, 'a.real = [1, 3]') + assert str(exc.value) == \ + "could not broadcast input array from shape (2) into shape ()" a = array('abc') assert str(a.real) == 'abc' # numpy imag for flexible types returns self @@ -609,8 +613,10 @@ assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' # numpy actually raises an AttributeError, # but numpypy raises a TypeError - raises((TypeError, AttributeError), 'c2.real = 10.') - raises((TypeError, AttributeError), 'c2.imag = 10.') + exc = raises((TypeError, AttributeError), 'c2.real = 10.') + assert str(exc.value) == "readonly attribute" + exc = raises((TypeError, AttributeError), 'c2.imag = 10.') + assert str(exc.value) == "readonly attribute" assert(real(c2) == 3.0) assert(imag(c2) == 4.0) 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 @@ -1480,6 +1480,32 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() + a = concatenate((array([1]), array(['abc']))) + assert str(a.dtype) == '|S3' + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' + a = concatenate((['abcdef'], ['abc'])) + assert a[0] == 'abcdef' + assert str(a.dtype) == '|S6' + + def test_record_concatenate(self): + # only an exact match can succeed + from numpypy import zeros, concatenate + a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), + zeros((2,),dtype=[('x', int), ('y', float)]))) + assert a.shape == (4,) + exc = raises(TypeError, concatenate, + (zeros((2,), dtype=[('x', int), ('y', float)]), + (zeros((2,), dtype=[('x', float), ('y', float)])))) + assert str(exc.value).startswith('record type mismatch') + exc = raises(TypeError, concatenate, ([1], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + exc = raises(TypeError, concatenate, (['abc'], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + + def test_std(self): from numpypy import array @@ -1650,6 +1676,12 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 + # scalar vs. array + try: + a = array([1, 2, 3.14156]).astype('S3').dtype + assert a.itemsize == 3 + except NotImplementedError: + skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array @@ -1955,7 +1987,7 @@ assert (a.transpose() == b).all() def test_flatiter(self): - from numpypy import array, flatiter, arange + from numpypy import array, flatiter, arange, zeros a = array([[10, 30], [40, 60]]) f_iter = a.flat assert f_iter.next() == 10 @@ -1971,6 +2003,9 @@ a = arange(10).reshape(5, 2) raises(IndexError, 'a.flat[(1, 2)]') assert a.flat.base is a + m = zeros((2,2), dtype='S3') + m.flat[1] = 1 + assert m[0,1] == '1' def test_flatiter_array_conv(self): from numpypy import array, dot 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 @@ -1635,6 +1635,7 @@ def get_size(self): return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1642,7 +1643,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) @@ -1683,6 +1684,20 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) + def build_and_convert(self, space, mydtype, box): + if box.get_dtype(space).is_str_or_unicode(): + arg = box.get_dtype(space).itemtype.to_str(box) + else: + w_arg = box.descr_str(space) + arg = space.str_w(space.str(w_arg)) + arr = VoidBoxStorage(self.size, mydtype) + i = 0 + for i in range(min(len(arg), self.size)): + arr.storage[i] = arg[i] + for j in range(i + 1, self.size): + arr.storage[j] = '\x00' + return interp_boxes.W_StringBox(arr, 0, arr.dtype) + class VoidType(BaseType, BaseStringType): T = lltype.Char diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,19 +106,16 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def setitem(self, w_key, w_value): - self.strategy.setitem(self, w_key, w_value) - def setitem_str(self, key, w_value): self.strategy.setitem_str(self, key, w_value) def _add_indirections(): - dict_methods = "getitem \ - getitem_str delitem length \ - clear w_keys values \ - items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int \ + dict_methods = "getitem getitem_str setitem setdefault \ + popitem delitem clear \ + length w_keys values items \ + iterkeys itervalues iteritems \ + listview_str listview_unicode listview_int \ view_as_kwargs".split() def make_method(method): From noreply at buildbot.pypy.org Wed Mar 20 21:20:05 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:20:05 +0100 (CET) Subject: [pypy-commit] pypy default: Remove unused callbench directory Message-ID: <20130320202005.5ECA21C019F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62567:dfeafbb406c6 Date: 2013-03-20 13:19 -0700 http://bitbucket.org/pypy/pypy/changeset/dfeafbb406c6/ Log: Remove unused callbench directory diff --git a/pypy/interpreter/callbench/bltn04.py b/pypy/interpreter/callbench/bltn04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn04.py +++ /dev/null @@ -1,40 +0,0 @@ -from sup import run - -def w(N, start): - c = chr - - start() - i = 0 - while i < N: - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltn_instantiate.py b/pypy/interpreter/callbench/bltn_instantiate.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn_instantiate.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - o = object - start() - i = 0 - while i < N: - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna1.py b/pypy/interpreter/callbench/bltna1.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna1.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - while i < N: - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna2.py b/pypy/interpreter/callbench/bltna2.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna2.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - z = l.__init__ - while i < N: - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bm14.py b/pypy/interpreter/callbench/bm14.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bm14.py +++ /dev/null @@ -1,51 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f0(self): - pass - def f1(self, a): - pass - def f2(self, a, b): - pass - def f3(self, a, b, c): - pass - def f4(self, a, b, c, d): - pass - - a = A() - f0 = a.f0 - f1 = a.f1 - f2 = a.f2 - f3 = a.f3 - f4 = a.f4 - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f1(1) - f2(1, 2) - f2(1, 2) - f2(1, 2) - f3(1, 2, 3) - f3(1, 2, 3) - f4(1, 2, 3, 4) - - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f2(1, 2) - - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmabvararg.py b/pypy/interpreter/callbench/bmabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmabvararg.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f(self, a, b, *args): - pass - - a = A() - f = a.f - z = (3, 4, 5) - - start() - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmfilter.py b/pypy/interpreter/callbench/bmfilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmfilter.py +++ /dev/null @@ -1,20 +0,0 @@ -from sup import run - -def w(N, start): - x = range(50) - class A(object): - def f1(self, a): - return False - - x = range(50) - a = A() - f1 = a.f1 - flt = filter - - start() - i = 0 - while i < N: - flt(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/bmmore.py b/pypy/interpreter/callbench/bmmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmmore.py +++ /dev/null @@ -1,30 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f4(self, a, b, c, d): - pass - def f5(self, a, b, c, d, e): - pass - a = A() - f4 = a.f4 - f5 = a.f5 - - start() - i = 0 - while i < N: - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/compare.py b/pypy/interpreter/callbench/compare.py deleted file mode 100644 --- a/pypy/interpreter/callbench/compare.py +++ /dev/null @@ -1,22 +0,0 @@ -# compare.py - -import sys - -def main(cur, ref): - cur = open(cur, 'rU') - ref = open(ref, 'rU') - try: - while True: - cur_line = cur.next() - ref_line = ref.next() - cur_name, cur_t = cur_line.split() - ref_name, ref_t = ref_line.split() - assert cur_name == ref_name - cur_t = float(cur_t) - ref_t = float(ref_t) - print "%-16s %.06g (x%.02f)" % (cur_name, cur_t, cur_t/ref_t) - except StopIteration: - pass - -if __name__ == '__main__': - main(sys.argv[1], sys.argv[2]) diff --git a/pypy/interpreter/callbench/f04.py b/pypy/interpreter/callbench/f04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/f04.py +++ /dev/null @@ -1,39 +0,0 @@ -from sup import run - -def w(N, start): - def f0(): - pass - def f1(a): - pass - def f2(a, b): - pass - def f3(a, b, c): - pass - def f4(a, b, c, d): - pass - def f5(a, b, c, d, e): - pass - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fabvararg.py b/pypy/interpreter/callbench/fabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fabvararg.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - def f(a, b, *args): - pass - - z = (3, 4, 5) - start() - - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/ffilter.py b/pypy/interpreter/callbench/ffilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffilter.py +++ /dev/null @@ -1,14 +0,0 @@ -from sup import run - -def w(N, start): - def f1(a): - return False - x = range(50) - - start() - i = 0 - while i < N: - filter(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/ffunccall.py b/pypy/interpreter/callbench/ffunccall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffunccall.py +++ /dev/null @@ -1,36 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def foo(self, x): - pass - - __add__ = foo - - a = A() - a1 = A() - - start() - i = 0 - while i < N: - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fmore.py b/pypy/interpreter/callbench/fmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fmore.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - def f5(a, b, c, d, e): - pass - def f6(a, b, c, d, e, f): - pass - - start() - - i = 0 - while i < N: - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/inst.py b/pypy/interpreter/callbench/inst.py deleted file mode 100644 --- a/pypy/interpreter/callbench/inst.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def __init__(self): - pass - - class B(object): - def __init__(self, x, y): - pass - - start() - i = 0 - while i < N: - A() - A() - A() - A() - A() - B(1, 2) - B(1, 2) - B(1, 2) - B(1, 2) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/inst_no_init.py b/pypy/interpreter/callbench/inst_no_init.py deleted file mode 100644 --- a/pypy/interpreter/callbench/inst_no_init.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - pass - - start() - i = 0 - while i < N: - A() - A() - A() - A() - A() - A() - A() - A() - A() - A() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/instcall.py b/pypy/interpreter/callbench/instcall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/instcall.py +++ /dev/null @@ -1,35 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def __call__(self): - pass - - a = A() - - start() - i = 0 - while i < N: - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/sup.py b/pypy/interpreter/callbench/sup.py deleted file mode 100644 --- a/pypy/interpreter/callbench/sup.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys, time - -def ref(N, start): - start() - i = 0 - while i < N: - i+=1 - - -def run(func, n): - n *= int(sys.argv[1]) - st = [None] - t = time.time - - def start(): - st[0] = t() - - ref(n, start) - elapsed_ref1 = t() - st[0] - ref(n, start) - elapsed_ref2 = t() - st[0] - ref(n, start) - elapsed_ref3 = t() - st[0] - elapsed_ref = min(elapsed_ref1, elapsed_ref2, elapsed_ref3) - - func(n, start) - elapsed1 = t() - st[0] - func(n, start) - elapsed2 = t() - st[0] - func(n, start) - elapsed3 = t() - st[0] - elapsed = min(elapsed1, elapsed2, elapsed3) - - #if elapsed < elapsed_ref*10: - # print "not enough meat", elapsed, elapsed_ref - - print sys.argv[0].replace('.py', ''), elapsed-elapsed_ref - - From noreply at buildbot.pypy.org Wed Mar 20 21:24:24 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:24:24 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, armin): remove unused objspace/proxy Message-ID: <20130320202424.0E1AA1C03A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62568:9aaaf0245344 Date: 2013-03-20 13:24 -0700 http://bitbucket.org/pypy/pypy/changeset/9aaaf0245344/ Log: (alex, armin): remove unused objspace/proxy diff --git a/pypy/objspace/proxy.py b/pypy/objspace/proxy.py deleted file mode 100644 --- a/pypy/objspace/proxy.py +++ /dev/null @@ -1,23 +0,0 @@ -from pypy.interpreter.baseobjspace import ObjSpace - -# __________________________________________________________________________ - -def get_operations(): - return [r[0] for r in ObjSpace.MethodTable] + ObjSpace.IrregularOpTable - -def patch_space_in_place(space, proxyname, proxymaker, operations=None): - """Patches the supplied space.""" - - if operations is None: - operations = get_operations() - - for name in operations: - parentfn = getattr(space, name) - proxy = proxymaker(space, name, parentfn) - if proxy: - setattr(space, name, proxy) - - prevrepr = repr(space) - space._this_space_repr_ = '%s(%s)' % (proxyname, prevrepr) - -# __________________________________________________________________________ From noreply at buildbot.pypy.org Wed Mar 20 21:25:35 2013 From: noreply at buildbot.pypy.org (aljosa) Date: Wed, 20 Mar 2013 21:25:35 +0100 (CET) Subject: [pypy-commit] jitviewer default: fixed bridge "name" for "show bridge" link Message-ID: <20130320202535.04D121C03A7@cobra.cs.uni-duesseldorf.de> Author: Aljosa Mohorovic Branch: Changeset: r218:110982753cb2 Date: 2013-03-19 18:22 -0700 http://bitbucket.org/pypy/jitviewer/changeset/110982753cb2/ Log: fixed bridge "name" for "show bridge" link diff --git a/_jitviewer/templates/loop.html b/_jitviewer/templates/loop.html --- a/_jitviewer/templates/loop.html +++ b/_jitviewer/templates/loop.html @@ -13,7 +13,7 @@ {% for op in chunk.operations %} {% if op.name != "debug_merge_point" %} {% if op.bridge %} - {{op.html_repr()}} show bridge  (run {{op.count}} times, ~{{op.percentage}}%)
+ {{op.html_repr()}} show bridge  (run {{op.count}} times, ~{{op.percentage}}%)
{% if op.asm %}

{{op.asm}}

{% endif %} From noreply at buildbot.pypy.org Wed Mar 20 21:29:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 21:29:25 +0100 (CET) Subject: [pypy-commit] jitviewer default: update the log Message-ID: <20130320202925.6B3321C019F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r219:2e6fc75b2ba8 Date: 2013-03-20 13:29 -0700 http://bitbucket.org/pypy/jitviewer/changeset/2e6fc75b2ba8/ Log: update the log diff too long, truncating to 2000 out of 4466 lines diff --git a/log.pypylog b/log.pypylog --- a/log.pypylog +++ b/log.pypylog @@ -1,121 +1,121 @@ -[1ce3a81d0bf7] {jit-backend-dump +[19c473e15553] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[1ce3a81e1ef9] jit-backend-dump} -[1ce3a81e8972] {jit-backend-dump +CODE_DUMP @7fe7c97fa000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e25f71] jit-backend-dump} +[19c473e2c5ce] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[1ce3a81eb566] jit-backend-dump} -[1ce3a81ee823] {jit-backend-dump +CODE_DUMP @7fe7c97fa085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e2ecc8] jit-backend-dump} +[19c473e31f04] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e12e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[1ce3a81f04ef] jit-backend-dump} -[1ce3a81f2d06] {jit-backend-dump +CODE_DUMP @7fe7c97fa12e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[19c473e338a2] jit-backend-dump} +[19c473e366e6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[1ce3a81f4c86] jit-backend-dump} -[1ce3a81f85ce] {jit-backend-dump +CODE_DUMP @7fe7c97fa191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[19c473e38072] jit-backend-dump} +[19c473e3b5e9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e1fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 -[1ce3a81fa494] jit-backend-dump} -[1ce3a81fe75a] {jit-backend-dump +CODE_DUMP @7fe7c97fa1fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 +[19c473e3d069] jit-backend-dump} +[19c473e40c38] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[1ce3a8203464] jit-backend-dump} -[1ce3a82046fc] {jit-backend-dump +CODE_DUMP @7fe7c97fa275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[19c473e45561] jit-backend-dump} +[19c473e467bb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[1ce3a820724d] jit-backend-dump} -[1ce3a82087e7] {jit-backend-dump +CODE_DUMP @7fe7c97fa491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e48f8b] jit-backend-dump} +[19c473e4a206] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[1ce3a821855b] jit-backend-dump} -[1ce3a821a1ef] {jit-backend-dump +CODE_DUMP @7fe7c97fa595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e56f01] jit-backend-dump} +[19c473e58819] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e6bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[1ce3a821d5e3] jit-backend-dump} -[1ce3a821ec8b] {jit-backend-dump +CODE_DUMP @7fe7c97fa6bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[19c473e5b9af] jit-backend-dump} +[19c473e5cf8d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e81e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[1ce3a82221b7] jit-backend-dump} -[1ce3a82233d9] {jit-backend-dump +CODE_DUMP @7fe7c97fa81e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[19c473e5fee0] jit-backend-dump} +[19c473e6101c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[1ce3a8224b24] jit-backend-dump} -[1ce3a822aa70] {jit-backend-dump +CODE_DUMP @7fe7c97fa988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e625e0] jit-backend-dump} +[19c473e68362] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17e9e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFDE1179E467F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB88E9179E467F000041FFE3 -[1ce3a822ee4e] jit-backend-dump} -[1ce3a82310c7] {jit-backend-dump +CODE_DUMP @7fe7c97fa9e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFDA17FC9E77F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB88A97FC9E77F000041FFE3 +[19c473e6c488] jit-backend-dump} +[19c473e6ed0e] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ebd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB88E9179E467F000041FFE3 -[1ce3a823258e] jit-backend-dump} -[1ce3a8232c9f] {jit-backend-counts -[1ce3a8233062] jit-backend-counts} -[1ce3a89027aa] {jit-backend -[1ce3a8be3976] {jit-backend-dump +CODE_DUMP @7fe7c97fabd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB88A97FC9E77F000041FFE3 +[19c473e70017] jit-backend-dump} +[19c473e70673] {jit-backend-counts +[19c473e70a42] jit-backend-counts} +[19c47442a7d0] {jit-backend +[19c4746efe37] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ece0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BBF03000A1467F00004D8B3B4D8D770149BBF03000A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB083100A1467F0000498B03488D500149BB083100A1467F00004989134983F8010F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB100DA59E467F00004D39DC0F85000000004C8B63084981FC4F0400000F8D00000000498D5C24014C8B2425807816034983FC000F8C0000000049BB203100A1467F00004D8B234D8D54240149BB203100A1467F00004D89134881FB4F0400000F8D000000004C8D5301488B1C25807816034883FB000F8C000000004C89D3E9B6FFFFFF49BBF8492A9E467F0000415349BB40EC179E467F0000415349BB00E0179E467F000041FFE349BBD0532A9E467F0000415349BB50EC179E467F0000415349BB00E0179E467F000041FFE349BB58532A9E467F0000415349BB60EC179E467F0000415349BB00E0179E467F000041FFE349BBE0522A9E467F0000415349BB70EC179E467F0000415349BB00E0179E467F000041FFE349BB68522A9E467F0000415349BB80EC179E467F0000415349BB00E0179E467F000041FFE349BBF0512A9E467F0000415349BB90EC179E467F0000415349BB00E0179E467F000041FFE349BB78512A9E467F0000415349BBA0EC179E467F0000415349BB00E0179E467F000041FFE349BB00512A9E467F0000415349BBB0EC179E467F0000415349BB00E0179E467F000041FFE349BB88502A9E467F0000415349BBC0EC179E467F0000415349BB00E0179E467F000041FFE349BB10502A9E467F0000415349BBD0EC179E467F0000415349BB00E0179E467F000041FFE3 -[1ce3a8bfbea3] jit-backend-dump} -[1ce3a8bfca00] {jit-backend-addr -Loop 0 ( #9 LOAD_FAST) has address 0x7f469e17ed30 to 0x7f469e17ee7b (bootstrap 0x7f469e17ece0) -[1ce3a8bfe00b] jit-backend-addr} -[1ce3a8bfea4e] {jit-backend-dump +CODE_DUMP @7fe7c97face0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6AB7FC9E77F000041FFD349BBF0E067CCE77F00004D8B3B4D8D770149BBF0E067CCE77F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB08E167CCE77F0000498B03488D500149BB08E167CCE77F00004989134983F8010F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB10CD0CCAE77F00004D39DC0F85000000004C8B63084981FC4F0400000F8D00000000498D5C24014C8B2425807816034983FC000F8C0000000049BB20E167CCE77F00004D8B234D8D54240149BB20E167CCE77F00004D89134881FB4F0400000F8D000000004C8D5301488B1C25807816034883FB000F8C000000004C89D3E9B6FFFFFF49BB802991C9E77F0000415349BB40AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB583391C9E77F0000415349BB50AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE03291C9E77F0000415349BB60AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB683291C9E77F0000415349BB70AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF03191C9E77F0000415349BB80AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB783191C9E77F0000415349BB90AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB003191C9E77F0000415349BBA0AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB883091C9E77F0000415349BBB0AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB103091C9E77F0000415349BBC0AC7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB982F91C9E77F0000415349BBD0AC7FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4747066e6] jit-backend-dump} +[19c474707091] {jit-backend-addr +Loop 0 ( #9 LOAD_FAST) has address 0x7fe7c97fad30 to 0x7fe7c97fae7b (bootstrap 0x7fe7c97face0) +[19c4747084f3] jit-backend-addr} +[19c474708f62] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17edd6 +0 A1000000 -[1ce3a8bff959] jit-backend-dump} -[1ce3a8c0004d] {jit-backend-dump +CODE_DUMP @7fe7c97fadd6 +0 A1000000 +[19c474709e17] jit-backend-dump} +[19c47470a414] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ede8 +0 B4000000 -[1ce3a8c00a8f] jit-backend-dump} -[1ce3a8c00f2b] {jit-backend-dump +CODE_DUMP @7fe7c97fade8 +0 B4000000 +[19c47470ae2a] jit-backend-dump} +[19c47470b293] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17edf2 +0 CF000000 -[1ce3a8c018fa] jit-backend-dump} -[1ce3a8c01d69] {jit-backend-dump +CODE_DUMP @7fe7c97fadf2 +0 CF000000 +[19c47470bc50] jit-backend-dump} +[19c47470c075] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ee05 +0 E1000000 -[1ce3a8c02720] jit-backend-dump} -[1ce3a8c02b74] {jit-backend-dump +CODE_DUMP @7fe7c97fae05 +0 E1000000 +[19c47470c9b8] jit-backend-dump} +[19c47470cdc2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ee16 +0 F5000000 -[1ce3a8c035c9] jit-backend-dump} -[1ce3a8c03dd4] {jit-backend-dump +CODE_DUMP @7fe7c97fae16 +0 F5000000 +[19c47470d695] jit-backend-dump} +[19c47470dc77] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ee2d +0 28010000 -[1ce3a8c04867] jit-backend-dump} -[1ce3a8c04d0c] {jit-backend-dump +CODE_DUMP @7fe7c97fae2d +0 28010000 +[19c47470e564] jit-backend-dump} +[19c47470e995] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ee59 +0 21010000 -[1ce3a8c05757] jit-backend-dump} -[1ce3a8c05c99] {jit-backend-dump +CODE_DUMP @7fe7c97fae59 +0 21010000 +[19c47470f2a6] jit-backend-dump} +[19c47470f74a] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17ee6f +0 55010000 -[1ce3a8c06645] jit-backend-dump} -[1ce3a8c0767f] jit-backend} -[1ce3a8c09553] {jit-log-opt-loop +CODE_DUMP @7fe7c97fae6f +0 55010000 +[19c4747100a2] jit-backend-dump} +[19c474710d6a] jit-backend} +[19c4747123d4] {jit-log-opt-loop # Loop 0 ( #9 LOAD_FAST) : loop with 54 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -130,17 +130,17 @@ +160: p13 = getarrayitem_gc(p9, 1, descr=) +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p16 = getfield_gc(p0, descr=) -+168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(139941277979224)) ++168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(140633495987968)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] -+250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] -+268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] ++240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] ++250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] ++268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] ++278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] debug_merge_point(0, 0, ' #15 COMPARE_OP') +297: i21 = getfield_gc_pure(p11, descr=) +301: i23 = int_lt(i21, 1103) -guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] +guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_FAST') debug_merge_point(0, 0, ' #24 LOAD_CONST') @@ -148,17 +148,17 @@ +314: i25 = int_add(i21, 1) debug_merge_point(0, 0, ' #28 STORE_FAST') debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+319: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i25] ++319: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i25] +319: i27 = getfield_raw(51804288, descr=) +327: i29 = int_lt(i27, 0) -guard_false(i29, descr=) [p1, p0, p2, p3, p6, i25] +guard_false(i29, descr=) [p1, p0, p2, p3, p6, i25] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+337: label(p0, p1, p2, p3, p6, i25, descr=TargetToken(139941277979312)) ++337: label(p0, p1, p2, p3, p6, i25, descr=TargetToken(140633495988056)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +368: i30 = int_lt(i25, 1103) -guard_true(i30, descr=) [p1, p0, p2, p3, p6, i25] +guard_true(i30, descr=) [p1, p0, p2, p3, p6, i25] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_FAST') debug_merge_point(0, 0, ' #24 LOAD_CONST') @@ -166,85 +166,85 @@ +381: i31 = int_add(i25, 1) debug_merge_point(0, 0, ' #28 STORE_FAST') debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+385: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i31, None] ++385: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i31, None] +385: i33 = getfield_raw(51804288, descr=) +393: i34 = int_lt(i33, 0) -guard_false(i34, descr=) [p1, p0, p2, p3, p6, i31, None] +guard_false(i34, descr=) [p1, p0, p2, p3, p6, i31, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+403: jump(p0, p1, p2, p3, p6, i31, descr=TargetToken(139941277979312)) ++403: jump(p0, p1, p2, p3, p6, i31, descr=TargetToken(140633495988056)) +411: --end of the loop-- -[1ce3a8ca19fa] jit-log-opt-loop} -[1ce3a903b35c] {jit-backend -[1ce3a91672ee] {jit-backend-dump +[19c4747929e2] jit-log-opt-loop} +[19c474a8bcae] {jit-backend +[19c474b8b379] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f100 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BBD83000A1467F00004D8B3B4D8D770149BBD83000A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB383100A1467F0000498B03488D500149BB383100A1467F00004989134983F8010F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB800EA59E467F00004D39DC0F85000000004C8B63084981FC4F0400000F8D000000004D8B560849BBC8009F9E467F00004D39DA0F85000000004D8B421049BBA84EA49E467F00004D39D80F85000000004C89B53801000048899D6001000049BB80F0179E467F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDE1179E467F000041FFD348C7452000000000488B58504989EE4C8B50604D85D20F85000000004C8B50404983FA000F85000000004D8D5424014C8B2425807816034983FC000F8C0000000049BB503100A1467F00004D8B234D8D74240149BB503100A1467F00004D89334981FA4F0400000F8D000000004D8D72014C8B1425807816034983FA000F8C000000004D89F2E9B6FFFFFF49BBF0112D9E467F0000415349BB00F0179E467F0000415349BB00E0179E467F000041FFE349BB406D2E9E467F0000415349BB10F0179E467F0000415349BB00E0179E467F000041FFE349BBC86C2E9E467F0000415349BB20F0179E467F0000415349BB00E0179E467F000041FFE349BB506C2E9E467F0000415349BB30F0179E467F0000415349BB00E0179E467F000041FFE349BBD86B2E9E467F0000415349BB40F0179E467F0000415349BB00E0179E467F000041FFE349BB606B2E9E467F0000415349BB50F0179E467F0000415349BB00E0179E467F000041FFE349BBE86A2E9E467F0000415349BB60F0179E467F0000415349BB00E0179E467F000041FFE349BB706A2E9E467F0000415349BB70F0179E467F0000415349BB00E0179E467F000041FFE349BBF8692E9E467F0000415349BB90F0179E467F0000415349BB00E0179E467F000041FFE349BB80692E9E467F0000415349BBA0F0179E467F0000415349BB00E0179E467F000041FFE349BB08692E9E467F0000415349BBB0F0179E467F0000415349BB00E0179E467F000041FFE349BB90682E9E467F0000415349BBC0F0179E467F0000415349BB00E0179E467F000041FFE349BB18682E9E467F0000415349BBD0F0179E467F0000415349BB00E0179E467F000041FFE349BBA0672E9E467F0000415349BBE0F0179E467F0000415349BB00E0179E467F000041FFE349BB28672E9E467F0000415349BBF0F0179E467F0000415349BB00E0179E467F000041FFE3 -[1ce3a917f7da] jit-backend-dump} -[1ce3a918019d] {jit-backend-addr -Loop 1 ( #9 LOAD_FAST) has address 0x7f469e17f150 to 0x7f469e17f32b (bootstrap 0x7f469e17f100) -[1ce3a9181915] jit-backend-addr} -[1ce3a918245a] {jit-backend-dump +CODE_DUMP @7fe7c97fb100 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6AB7FC9E77F000041FFD349BBD8E067CCE77F00004D8B3B4D8D770149BBD8E067CCE77F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B46204C89BD480100004C89AD500100004C898D580100004889BD60010000488995680100004889857001000049BB38E167CCE77F0000498B03488D500149BB38E167CCE77F00004989134983F8010F85000000004883FB017206813B180C00000F85000000004983FA000F850000000049BB80CE0CCAE77F00004D39DC0F85000000004C8B63084981FC4F0400000F8D000000004D8B560849BBB00007CAE77F00004D39DA0F85000000004D8B421049BB900E0CCAE77F00004D39D80F850000000048899D380100004C89B56001000049BB80B07FC9E77F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C74520000000004C8B70504889EB4C8B50604D85D20F85000000004C8B50404983FA000F85000000004D8D5424014C8B2425807816034983FC000F8C0000000049BB50E167CCE77F00004D8B234D8D74240149BB50E167CCE77F00004D89334981FA4F0400000F8D000000004D8D72014C8B1425807816034983FA000F8C000000004D89F2E9B6FFFFFF49BBF05194C9E77F0000415349BB00B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB40AD95C9E77F0000415349BB10B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BBC8AC95C9E77F0000415349BB20B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB50AC95C9E77F0000415349BB30B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD8AB95C9E77F0000415349BB40B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB60AB95C9E77F0000415349BB50B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE8AA95C9E77F0000415349BB60B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB70AA95C9E77F0000415349BB70B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF8A995C9E77F0000415349BB90B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB80A995C9E77F0000415349BBA0B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB08A995C9E77F0000415349BBB0B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB90A895C9E77F0000415349BBC0B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB18A895C9E77F0000415349BBD0B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA0A795C9E77F0000415349BBE0B07FC9E77F0000415349BB00A07FC9E77F000041FFE349BB28A795C9E77F0000415349BBF0B07FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c474b9edc8] jit-backend-dump} +[19c474b9f656] {jit-backend-addr +Loop 1 ( #9 LOAD_FAST) has address 0x7fe7c97fb150 to 0x7fe7c97fb32b (bootstrap 0x7fe7c97fb100) +[19c474ba0722] jit-backend-addr} +[19c474ba105f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f1f6 +0 31010000 -[1ce3a91833b0] jit-backend-dump} -[1ce3a9183a06] {jit-backend-dump +CODE_DUMP @7fe7c97fb1f6 +0 31010000 +[19c474ba1e7c] jit-backend-dump} +[19c474ba2395] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f208 +0 44010000 -[1ce3a91843e1] jit-backend-dump} -[1ce3a9184844] {jit-backend-dump +CODE_DUMP @7fe7c97fb208 +0 44010000 +[19c474ba2cfc] jit-backend-dump} +[19c474ba314d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f212 +0 5F010000 -[1ce3a9185196] jit-backend-dump} -[1ce3a9185608] {jit-backend-dump +CODE_DUMP @7fe7c97fb212 +0 5F010000 +[19c474ba3a2b] jit-backend-dump} +[19c474ba3e5f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f225 +0 71010000 -[1ce3a91860ad] jit-backend-dump} -[1ce3a9186507] {jit-backend-dump +CODE_DUMP @7fe7c97fb225 +0 71010000 +[19c474ba4793] jit-backend-dump} +[19c474ba4bc7] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f236 +0 85010000 -[1ce3a9186ee2] jit-backend-dump} -[1ce3a9187333] {jit-backend-dump +CODE_DUMP @7fe7c97fb236 +0 85010000 +[19c474ba5566] jit-backend-dump} +[19c474ba59a0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f24d +0 93010000 -[1ce3a9187c8e] jit-backend-dump} -[1ce3a91880e0] {jit-backend-dump +CODE_DUMP @7fe7c97fb24d +0 93010000 +[19c474ba62ae] jit-backend-dump} +[19c474ba66e1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f264 +0 A1010000 -[1ce3a9188a61] jit-backend-dump} -[1ce3a918907f] {jit-backend-dump +CODE_DUMP @7fe7c97fb264 +0 A1010000 +[19c474ba6f81] jit-backend-dump} +[19c474ba7727] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f2b8 +0 97010000 -[1ce3a91899d1] jit-backend-dump} -[1ce3a9189e52] {jit-backend-dump +CODE_DUMP @7fe7c97fb2b8 +0 97010000 +[19c474ba801d] jit-backend-dump} +[19c474ba844b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f2c6 +0 AE010000 -[1ce3a918a7bf] jit-backend-dump} -[1ce3a918acbd] {jit-backend-dump +CODE_DUMP @7fe7c97fb2c6 +0 AE010000 +[19c474ba8d0e] jit-backend-dump} +[19c474ba91df] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f2dd +0 E1010000 -[1ce3a918b62c] jit-backend-dump} -[1ce3a918baad] {jit-backend-dump +CODE_DUMP @7fe7c97fb2dd +0 E1010000 +[19c474ba9a8b] jit-backend-dump} +[19c474ba9ece] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f309 +0 DA010000 -[1ce3a918c467] jit-backend-dump} -[1ce3a918c8eb] {jit-backend-dump +CODE_DUMP @7fe7c97fb309 +0 DA010000 +[19c474baa811] jit-backend-dump} +[19c474baac68] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f31f +0 0E020000 -[1ce3a918d25e] jit-backend-dump} -[1ce3a918df82] jit-backend} -[1ce3a918f7df] {jit-log-opt-loop +CODE_DUMP @7fe7c97fb31f +0 0E020000 +[19c474bab57f] jit-backend-dump} +[19c474babe54] jit-backend} +[19c474bacfed] {jit-log-opt-loop # Loop 1 ( #9 LOAD_FAST) : loop with 77 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -259,34 +259,34 @@ +160: p13 = getarrayitem_gc(p9, 1, descr=) +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p16 = getfield_gc(p0, descr=) -+168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(139941277980368)) ++168: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, descr=TargetToken(140633495988760)) debug_merge_point(0, 0, ' #9 LOAD_FAST') -+240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] -+250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] -+268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] ++240: guard_value(i7, 1, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15] ++250: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, i5, p6, p13, p15] ++268: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p15] debug_merge_point(0, 0, ' #12 LOAD_CONST') -+278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] ++278: guard_value(p4, ConstPtr(ptr20), descr=) [p1, p0, p4, p2, p3, p6, p11, p15] debug_merge_point(0, 0, ' #15 COMPARE_OP') +297: i21 = getfield_gc_pure(p11, descr=) +301: i23 = int_lt(i21, 1103) -guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] +guard_true(i23, descr=) [p1, p0, p11, p2, p3, p6] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_GLOBAL') +314: p24 = getfield_gc(p0, descr=) -+318: guard_value(p24, ConstPtr(ptr25), descr=) [p1, p0, p24, p2, p3, p6, p11] ++318: guard_value(p24, ConstPtr(ptr25), descr=) [p1, p0, p24, p2, p3, p6, p11] +337: p26 = getfield_gc(p24, descr=) -+341: guard_value(p26, ConstPtr(ptr27), descr=) [p1, p0, p26, p24, p2, p3, p6, p11] -+360: guard_not_invalidated(descr=) [p1, p0, p24, p2, p3, p6, p11] ++341: guard_value(p26, ConstPtr(ptr27), descr=) [p1, p0, p26, p24, p2, p3, p6, p11] ++360: guard_not_invalidated(descr=) [p1, p0, p24, p2, p3, p6, p11] debug_merge_point(0, 0, ' #24 LOAD_FAST') debug_merge_point(0, 0, ' #27 CALL_FUNCTION') +360: p29 = call(ConstClass(getexecutioncontext), descr=) +424: p30 = getfield_gc(p29, descr=) +428: p31 = force_token() +431: p32 = getfield_gc(p29, descr=) -+435: guard_isnull(p32, descr=) [p1, p0, p29, p32, p2, p3, p6, p11, p30, p31] ++435: guard_isnull(p32, descr=) [p1, p0, p29, p32, p2, p3, p6, p11, p31, p30] +444: i33 = getfield_gc(p29, descr=) +448: i34 = int_is_zero(i33) -guard_true(i34, descr=) [p1, p0, p29, p2, p3, p6, p11, p30, p31] +guard_true(i34, descr=) [p1, p0, p29, p2, p3, p6, p11, p31, p30] debug_merge_point(1, 1, ' #0 LOAD_FAST') debug_merge_point(1, 1, ' #3 LOAD_CONST') debug_merge_point(1, 1, ' #6 BINARY_ADD') @@ -294,21 +294,21 @@ debug_merge_point(1, 1, ' #7 RETURN_VALUE') debug_merge_point(0, 0, ' #30 STORE_FAST') debug_merge_point(0, 0, ' #33 JUMP_ABSOLUTE') -+463: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36, None, None] ++463: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36, None, None] +463: i39 = getfield_raw(51804288, descr=) +471: i41 = int_lt(i39, 0) -guard_false(i41, descr=) [p1, p0, p2, p3, p6, i36, None, None] +guard_false(i41, descr=) [p1, p0, p2, p3, p6, i36, None, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') +481: p42 = same_as(ConstPtr(ptr27)) -+481: label(p0, p1, p2, p3, p6, i36, descr=TargetToken(139941277980456)) ++481: label(p0, p1, p2, p3, p6, i36, descr=TargetToken(140633495988848)) debug_merge_point(0, 0, ' #9 LOAD_FAST') debug_merge_point(0, 0, ' #12 LOAD_CONST') debug_merge_point(0, 0, ' #15 COMPARE_OP') +512: i43 = int_lt(i36, 1103) -guard_true(i43, descr=) [p1, p0, p2, p3, p6, i36] +guard_true(i43, descr=) [p1, p0, p2, p3, p6, i36] debug_merge_point(0, 0, ' #18 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #21 LOAD_GLOBAL') -+525: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36] ++525: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i36] debug_merge_point(0, 0, ' #24 LOAD_FAST') debug_merge_point(0, 0, ' #27 CALL_FUNCTION') +525: p44 = force_token() @@ -321,107 +321,107 @@ debug_merge_point(0, 0, ' #33 JUMP_ABSOLUTE') +529: i46 = getfield_raw(51804288, descr=) +537: i47 = int_lt(i46, 0) -guard_false(i47, descr=) [p1, p0, p2, p3, p6, i45, None] +guard_false(i47, descr=) [p1, p0, p2, p3, p6, i45, None] debug_merge_point(0, 0, ' #9 LOAD_FAST') -+547: jump(p0, p1, p2, p3, p6, i45, descr=TargetToken(139941277980456)) ++547: jump(p0, p1, p2, p3, p6, i45, descr=TargetToken(140633495988848)) +555: --end of the loop-- -[1ce3a91d8ed9] jit-log-opt-loop} -[1ce3a91f3c53] {jit-backend-dump +[19c474bf9fca] jit-log-opt-loop} +[19c474c0e8bc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f268 +0 E9C1010000 -[1ce3a91f56a9] jit-backend-dump} -[1ce3a91f5c6e] {jit-backend-dump +CODE_DUMP @7fe7c97fb268 +0 E9C1010000 +[19c474c103d6] jit-backend-dump} +[19c474c10960] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f2cf +0 E9C9010000 -[1ce3a91f6793] jit-backend-dump} -[1ce3a91f6bf6] {jit-backend-dump +CODE_DUMP @7fe7c97fb2cf +0 E9C9010000 +[19c474c1148a] jit-backend-dump} +[19c474c118f3] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f30d +0 E9FA010000 -[1ce3a91f761e] jit-backend-dump} -[1ce3a97dca13] {jit-backend -[1ce3a98bbdbb] {jit-backend-dump +CODE_DUMP @7fe7c97fb30d +0 E9FA010000 +[19c474c122f5] jit-backend-dump} +[19c47509a4c2] {jit-backend +[19c475193ba8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f668 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BB683100A1467F00004D8B3B4D8D770149BB683100A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89AD480100004C8B6E304C89BD500100004C898D580100004889BD600100004889956801000048898D700100004C89AD7801000049BB803100A1467F00004D8B2B498D4D0149BB803100A1467F000049890B4983F8030F85000000008138E82200000F85000000004C8B40104D85C00F8400000000488B48084D8B681041817D00685505000F85000000004D8B68084D8B4508498B5510498B7D184883F9000F8C000000004839F90F8D000000004989CD480FAFCA4D89C14901C8498D4D01488948084983FA000F85000000004883FB017206813B180C00000F850000000049BB380FA59E467F00004D39DC0F85000000004C8B63084983C4010F8000000000488B1C25807816034883FB000F8C000000004C89856001000049BB983100A1467F00004D8B03498D580149BB983100A1467F000049891B4839F90F8D000000004889CB480FAFCA4D89C84901C9488D4B01488948084C89E34983C4010F8000000000488B1C25807816034883FB000F8C000000004C898D600100004D89C1E996FFFFFF49BBA86E2E9E467F0000415349BB68F5179E467F0000415349BB00E0179E467F000041FFE349BB90882F9E467F0000415349BB78F5179E467F0000415349BB00E0179E467F000041FFE349BBA0872F9E467F0000415349BB88F5179E467F0000415349BB00E0179E467F000041FFE349BB28872F9E467F0000415349BB98F5179E467F0000415349BB00E0179E467F000041FFE349BBB0862F9E467F0000415349BBA8F5179E467F0000415349BB00E0179E467F000041FFE349BB38862F9E467F0000415349BBB8F5179E467F0000415349BB00E0179E467F000041FFE349BBC0852F9E467F0000415349BBC8F5179E467F0000415349BB00E0179E467F000041FFE349BB48852F9E467F0000415349BBD8F5179E467F0000415349BB00E0179E467F000041FFE349BBD0842F9E467F0000415349BBE8F5179E467F0000415349BB00E0179E467F000041FFE349BB58842F9E467F0000415349BBF8F5179E467F0000415349BB00E0179E467F000041FFE349BBE0832F9E467F0000415349BB08F6179E467F0000415349BB00E0179E467F000041FFE349BB68832F9E467F0000415349BB18F6179E467F0000415349BB00E0179E467F000041FFE349BBF0822F9E467F0000415349BB28F6179E467F0000415349BB00E0179E467F000041FFE349BB78822F9E467F0000415349BB38F6179E467F0000415349BB00E0179E467F000041FFE349BB00822F9E467F0000415349BB48F6179E467F0000415349BB00E0179E467F000041FFE349BB88812F9E467F0000415349BB58F6179E467F0000415349BB00E0179E467F000041FFE3 -[1ce3a98d2d3c] jit-backend-dump} -[1ce3a98d3611] {jit-backend-addr -Loop 2 ( #19 FOR_ITER) has address 0x7f469e17f6b8 to 0x7f469e17f898 (bootstrap 0x7f469e17f668) -[1ce3a98d4877] jit-backend-addr} -[1ce3a98d517f] {jit-backend-dump +CODE_DUMP @7fe7c97fb668 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6AB7FC9E77F000041FFD349BB68E167CCE77F00004D8B3B4D8D770149BB68E167CCE77F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89AD480100004C8B6E304C89BD500100004C898D580100004889BD600100004889956801000048898D700100004C89AD7801000049BB80E167CCE77F00004D8B2B498D4D0149BB80E167CCE77F000049890B4983F8030F85000000008138E82200000F85000000004C8B40104D85C00F8400000000488B48084D8B681041817D00685505000F85000000004D8B68084D8B4508498B5510498B7D184883F9000F8C000000004839F90F8D000000004989CD480FAFCA4D89C14901C8498D4D01488948084983FA000F85000000004883FB017206813B180C00000F850000000049BB38CF0CCAE77F00004D39DC0F85000000004C8B63084983C4010F8000000000488B1C25807816034883FB000F8C000000004C89856001000049BB98E167CCE77F00004D8B03498D580149BB98E167CCE77F000049891B4839F90F8D000000004889CB480FAFCA4D89C84901C9488D4B01488948084C89E34983C4010F8000000000488B1C25807816034883FB000F8C000000004C898D600100004D89C1E996FFFFFF49BBA8AE95C9E77F0000415349BB68B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB90E896C9E77F0000415349BB78B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA0E796C9E77F0000415349BB88B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB28E796C9E77F0000415349BB98B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBB0E696C9E77F0000415349BBA8B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB38E696C9E77F0000415349BBB8B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBC0E596C9E77F0000415349BBC8B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB48E596C9E77F0000415349BBD8B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD0E496C9E77F0000415349BBE8B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB58E496C9E77F0000415349BBF8B57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE0E396C9E77F0000415349BB08B67FC9E77F0000415349BB00A07FC9E77F000041FFE349BB68E396C9E77F0000415349BB18B67FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF0E296C9E77F0000415349BB28B67FC9E77F0000415349BB00A07FC9E77F000041FFE349BB78E296C9E77F0000415349BB38B67FC9E77F0000415349BB00A07FC9E77F000041FFE349BB00E296C9E77F0000415349BB48B67FC9E77F0000415349BB00A07FC9E77F000041FFE349BB88E196C9E77F0000415349BB58B67FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4751ab695] jit-backend-dump} +[19c4751ac131] {jit-backend-addr +Loop 2 ( #19 FOR_ITER) has address 0x7fe7c97fb6b8 to 0x7fe7c97fb898 (bootstrap 0x7fe7c97fb668) +[19c4751ad6bf] jit-backend-addr} +[19c4751ae020] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f76d +0 27010000 -[1ce3a98d60e6] jit-backend-dump} -[1ce3a98d672e] {jit-backend-dump +CODE_DUMP @7fe7c97fb76d +0 27010000 +[19c4751aef16] jit-backend-dump} +[19c4751af4c9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f779 +0 40010000 -[1ce3a98d7185] jit-backend-dump} -[1ce3a98d7577] {jit-backend-dump +CODE_DUMP @7fe7c97fb779 +0 40010000 +[19c4751aff5c] jit-backend-dump} +[19c4751b03b0] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f786 +0 58010000 -[1ce3a98d7f7c] jit-backend-dump} -[1ce3a98d8374] {jit-backend-dump +CODE_DUMP @7fe7c97fb786 +0 58010000 +[19c4751b0dcc] jit-backend-dump} +[19c4751b122c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f79c +0 67010000 -[1ce3a98d8c3a] jit-backend-dump} -[1ce3a98d903e] {jit-backend-dump +CODE_DUMP @7fe7c97fb79c +0 67010000 +[19c4751b1b28] jit-backend-dump} +[19c4751b2047] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f7b6 +0 72010000 -[1ce3a98d98f9] jit-backend-dump} -[1ce3a98d9ceb] {jit-backend-dump +CODE_DUMP @7fe7c97fb7b6 +0 72010000 +[19c4751b2928] jit-backend-dump} +[19c4751b2d6d] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f7bf +0 8E010000 -[1ce3a98da5d2] jit-backend-dump} -[1ce3a98da9c5] {jit-backend-dump +CODE_DUMP @7fe7c97fb7bf +0 8E010000 +[19c4751b36fb] jit-backend-dump} +[19c4751b3b61] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f7de +0 94010000 -[1ce3a98db297] jit-backend-dump} -[1ce3a98db69b] {jit-backend-dump +CODE_DUMP @7fe7c97fb7de +0 94010000 +[19c4751b440d] jit-backend-dump} +[19c4751b4852] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f7f0 +0 A7010000 -[1ce3a98dbf3e] jit-backend-dump} -[1ce3a98dc339] {jit-backend-dump +CODE_DUMP @7fe7c97fb7f0 +0 A7010000 +[19c4751b5192] jit-backend-dump} +[19c4751b55cc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f803 +0 B9010000 -[1ce3a98dcc7c] jit-backend-dump} -[1ce3a98dd103] {jit-backend-dump +CODE_DUMP @7fe7c97fb803 +0 B9010000 +[19c4751b5ead] jit-backend-dump} +[19c4751b6304] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f811 +0 D0010000 -[1ce3a98dd9cc] jit-backend-dump} -[1ce3a98ddf6e] {jit-backend-dump +CODE_DUMP @7fe7c97fb811 +0 D0010000 +[19c4751b6baa] jit-backend-dump} +[19c4751b71bc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f823 +0 08020000 -[1ce3a98de85e] jit-backend-dump} -[1ce3a98dec7c] {jit-backend-dump +CODE_DUMP @7fe7c97fb823 +0 08020000 +[19c4751b7aa9] jit-backend-dump} +[19c4751b7ec5] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f851 +0 FF010000 -[1ce3a98df51c] jit-backend-dump} -[1ce3a98df9cd] {jit-backend-dump +CODE_DUMP @7fe7c97fb851 +0 FF010000 +[19c4751b87ca] jit-backend-dump} +[19c4751b8c15] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f873 +0 02020000 -[1ce3a98e033f] jit-backend-dump} -[1ce3a98e08d8] {jit-backend-dump +CODE_DUMP @7fe7c97fb873 +0 02020000 +[19c4751b94d6] jit-backend-dump} +[19c4751b99a7] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f885 +0 3A020000 -[1ce3a98e1696] jit-backend-dump} -[1ce3a98e22f2] jit-backend} -[1ce3a98e35cc] {jit-log-opt-loop +CODE_DUMP @7fe7c97fb885 +0 3A020000 +[19c4751ba267] jit-backend-dump} +[19c4751bae3b] jit-backend} +[19c4751bbff8] {jit-log-opt-loop # Loop 2 ( #19 FOR_ITER) : loop with 74 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -438,48 +438,48 @@ +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p19 = getarrayitem_gc(p9, 4, descr=) +183: p20 = getfield_gc(p0, descr=) -+183: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, descr=TargetToken(139941277980984)) ++183: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, descr=TargetToken(140633495989376)) debug_merge_point(0, 0, ' #19 FOR_ITER') -+255: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19] -+265: guard_class(p15, 26177128, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++255: guard_value(i7, 3, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19] ++265: guard_class(p15, 26177128, descr=) [p1, p0, p15, p2, p3, p4, i5, p6, p11, p13, p17, p19] +277: p23 = getfield_gc(p15, descr=) -+281: guard_nonnull(p23, descr=) [p1, p0, p15, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++281: guard_nonnull(p23, descr=) [p1, p0, p15, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] +290: i24 = getfield_gc(p15, descr=) +294: p25 = getfield_gc(p23, descr=) -+298: guard_class(p25, 26517736, descr=) [p1, p0, p15, i24, p25, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] ++298: guard_class(p25, 26517736, descr=) [p1, p0, p15, i24, p25, p23, p2, p3, p4, i5, p6, p11, p13, p17, p19] +312: p27 = getfield_gc(p23, descr=) +316: i28 = getfield_gc_pure(p27, descr=) +320: i29 = getfield_gc_pure(p27, descr=) +324: i30 = getfield_gc_pure(p27, descr=) +328: i32 = int_lt(i24, 0) -guard_false(i32, descr=) [p1, p0, p15, i24, i30, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] +guard_false(i32, descr=) [p1, p0, p15, i24, i30, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] +338: i33 = int_ge(i24, i30) -guard_false(i33, descr=) [p1, p0, p15, i24, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] +guard_false(i33, descr=) [p1, p0, p15, i24, i29, i28, p2, p3, p4, i5, p6, p11, p13, p17, p19] +347: i34 = int_mul(i24, i29) +354: i35 = int_add(i28, i34) +360: i37 = int_add(i24, 1) +364: setfield_gc(p15, i37, descr=) -+368: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p19, i35] ++368: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p19, i35] debug_merge_point(0, 0, ' #22 STORE_FAST') debug_merge_point(0, 0, ' #25 LOAD_FAST') -+378: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, p6, p15, p19, i35] ++378: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p4, p6, p15, p19, i35] debug_merge_point(0, 0, ' #28 LOAD_CONST') -+396: guard_value(p4, ConstPtr(ptr40), descr=) [p1, p0, p4, p2, p3, p6, p11, p15, p19, i35] ++396: guard_value(p4, ConstPtr(ptr40), descr=) [p1, p0, p4, p2, p3, p6, p11, p15, p19, i35] debug_merge_point(0, 0, ' #31 INPLACE_ADD') +415: i41 = getfield_gc_pure(p11, descr=) +419: i43 = int_add_ovf(i41, 1) -guard_no_overflow(descr=) [p1, p0, p11, i43, p2, p3, p6, p15, i35] +guard_no_overflow(descr=) [p1, p0, p11, i43, p2, p3, p6, p15, i35] debug_merge_point(0, 0, ' #32 STORE_FAST') debug_merge_point(0, 0, ' #35 JUMP_ABSOLUTE') -+429: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i43, i35] ++429: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i43, i35] +429: i45 = getfield_raw(51804288, descr=) +437: i47 = int_lt(i45, 0) -guard_false(i47, descr=) [p1, p0, p2, p3, p6, p15, i43, i35] +guard_false(i47, descr=) [p1, p0, p2, p3, p6, p15, i43, i35] debug_merge_point(0, 0, ' #19 FOR_ITER') -+447: label(p0, p1, p2, p3, p6, i43, i35, p15, i37, i30, i29, i28, descr=TargetToken(139941277981072)) ++447: label(p0, p1, p2, p3, p6, i43, i35, p15, i37, i30, i29, i28, descr=TargetToken(140633495989464)) debug_merge_point(0, 0, ' #19 FOR_ITER') +484: i48 = int_ge(i37, i30) -guard_false(i48, descr=) [p1, p0, p15, i37, i29, i28, p2, p3, p6, i35, i43] +guard_false(i48, descr=) [p1, p0, p15, i37, i29, i28, p2, p3, p6, i35, i43] +493: i49 = int_mul(i37, i29) +500: i50 = int_add(i28, i49) +506: i51 = int_add(i37, 1) @@ -489,103 +489,103 @@ debug_merge_point(0, 0, ' #31 INPLACE_ADD') +510: setfield_gc(p15, i51, descr=) +514: i52 = int_add_ovf(i43, 1) -guard_no_overflow(descr=) [p1, p0, i52, p2, p3, p6, p15, i50, None, i43] +guard_no_overflow(descr=) [p1, p0, i52, p2, p3, p6, p15, i50, None, i43] debug_merge_point(0, 0, ' #32 STORE_FAST') debug_merge_point(0, 0, ' #35 JUMP_ABSOLUTE') -+527: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] ++527: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] +527: i54 = getfield_raw(51804288, descr=) +535: i55 = int_lt(i54, 0) -guard_false(i55, descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] +guard_false(i55, descr=) [p1, p0, p2, p3, p6, p15, i52, i50, None, None] debug_merge_point(0, 0, ' #19 FOR_ITER') -+545: jump(p0, p1, p2, p3, p6, i52, i50, p15, i51, i30, i29, i28, descr=TargetToken(139941277981072)) ++545: jump(p0, p1, p2, p3, p6, i52, i50, p15, i51, i30, i29, i28, descr=TargetToken(140633495989464)) +560: --end of the loop-- -[1ce3a992d953] jit-log-opt-loop} -[1ce3a9c745fd] {jit-backend -[1ce3a9d2ff07] {jit-backend-dump +[19c475204f61] jit-log-opt-loop} +[19c47566fb6c] {jit-backend +[19c47596b738] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fc08 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BBB03100A1467F00004D8B3B4D8D770149BBB03100A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD600100004889856801000048898D7001000049BBC83100A1467F0000498B0B488D410149BBC83100A1467F00004989034983F8020F85000000004883FA017206813A180C00000F85000000004983FA000F850000000049BBF00FA59E467F00004D39DC0F85000000004C8B62084981FC102700000F8D0000000049BB00000000000000804D39DC0F84000000004C89E0B9020000004889956001000048898568010000489948F7F94889D048C1FA3F41BC020000004921D44C01E04883F8000F85000000004883FB017206813B180C00000F8500000000488B43084883C0010F8000000000488B9D680100004883C3014C8B2425807816034983FC000F8C0000000049BBE03100A1467F00004D8B23498D54240149BBE03100A1467F00004989134881FB102700000F8D0000000049BB00000000000000804C39DB0F8400000000488985600100004889D8B90200000048898568010000489948F7F94889D048C1FA3FBB020000004821D34801D84883F8000F8500000000488B85600100004883C0010F8000000000488B9D680100004883C301488B1425807816034883FA000F8C00000000E957FFFFFF49BB80892F9E467F0000415349BBF8FA179E467F0000415349BB00E0179E467F000041FFE349BBE8992F9E467F0000415349BB08FB179E467F0000415349BB00E0179E467F000041FFE349BB70992F9E467F0000415349BB18FB179E467F0000415349BB00E0179E467F000041FFE349BBF8982F9E467F0000415349BB28FB179E467F0000415349BB00E0179E467F000041FFE349BB80982F9E467F0000415349BB38FB179E467F0000415349BB00E0179E467F000041FFE349BB08982F9E467F0000415349BB48FB179E467F0000415349BB00E0179E467F000041FFE349BB90972F9E467F0000415349BB58FB179E467F0000415349BB00E0179E467F000041FFE349BB18972F9E467F0000415349BB68FB179E467F0000415349BB00E0179E467F000041FFE349BBA0962F9E467F0000415349BB78FB179E467F0000415349BB00E0179E467F000041FFE349BB28962F9E467F0000415349BB88FB179E467F0000415349BB00E0179E467F000041FFE349BBB0952F9E467F0000415349BB98FB179E467F0000415349BB00E0179E467F000041FFE349BB38952F9E467F0000415349BBA8FB179E467F0000415349BB00E0179E467F000041FFE349BBC0942F9E467F0000415349BBB8FB179E467F0000415349BB00E0179E467F000041FFE349BB48942F9E467F0000415349BBC8FB179E467F0000415349BB00E0179E467F000041FFE349BBD0932F9E467F0000415349BBD8FB179E467F0000415349BB00E0179E467F000041FFE349BB58932F9E467F0000415349BBE8FB179E467F0000415349BB00E0179E467F000041FFE349BBE0922F9E467F0000415349BBF8FB179E467F0000415349BB00E0179E467F000041FFE3 -[1ce3a9d39fa9] jit-backend-dump} -[1ce3a9d3a740] {jit-backend-addr -Loop 3 ( #15 LOAD_FAST) has address 0x7f469e17fc58 to 0x7f469e17fe77 (bootstrap 0x7f469e17fc08) -[1ce3a9d3b798] jit-backend-addr} -[1ce3a9d3c01d] {jit-backend-dump +CODE_DUMP @7fe7c97fbc08 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6AB7FC9E77F000041FFD349BBB0E167CCE77F00004D8B3B4D8D770149BBB0E167CCE77F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89BD480100004C89AD500100004C898D580100004889BD600100004889856801000048898D7001000049BBC8E167CCE77F0000498B0B488D410149BBC8E167CCE77F00004989034983F8020F85000000004883FA017206813A180C00000F85000000004983FA000F850000000049BBF0CF0CCAE77F00004D39DC0F85000000004C8B62084981FC102700000F8D0000000049BB00000000000000804D39DC0F84000000004C89E0B9020000004889956001000048898568010000489948F7F94889D048C1FA3F41BC020000004921D44C01E04883F8000F85000000004883FB017206813B180C00000F8500000000488B43084883C0010F8000000000488B9D680100004883C3014C8B2425807816034983FC000F8C0000000049BBE0E167CCE77F00004D8B23498D54240149BBE0E167CCE77F00004989134881FB102700000F8D0000000049BB00000000000000804C39DB0F8400000000488985600100004889D8B90200000048898568010000489948F7F94889D048C1FA3FBB020000004821D34801D84883F8000F8500000000488B85600100004883C0010F8000000000488B9D680100004883C301488B1425807816034883FA000F8C00000000E957FFFFFF49BB80E996C9E77F0000415349BBF8BA7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE8F996C9E77F0000415349BB08BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB70F996C9E77F0000415349BB18BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF8F896C9E77F0000415349BB28BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB80F896C9E77F0000415349BB38BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB08F896C9E77F0000415349BB48BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB90F796C9E77F0000415349BB58BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB18F796C9E77F0000415349BB68BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA0F696C9E77F0000415349BB78BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB28F696C9E77F0000415349BB88BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBB0F596C9E77F0000415349BB98BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB38F596C9E77F0000415349BBA8BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBC0F496C9E77F0000415349BBB8BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB48F496C9E77F0000415349BBC8BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD0F396C9E77F0000415349BBD8BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB58F396C9E77F0000415349BBE8BB7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE0F296C9E77F0000415349BBF8BB7FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c475978b13] jit-backend-dump} +[19c47597933f] {jit-backend-addr +Loop 3 ( #15 LOAD_FAST) has address 0x7fe7c97fbc58 to 0x7fe7c97fbe77 (bootstrap 0x7fe7c97fbc08) +[19c47597a484] jit-backend-addr} +[19c47597acbc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd02 +0 71010000 -[1ce3a9d43248] jit-backend-dump} -[1ce3a9d43a6e] {jit-backend-dump +CODE_DUMP @7fe7c97fbd02 +0 71010000 +[19c475989294] jit-backend-dump} +[19c475989b43] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd14 +0 84010000 -[1ce3a9d4470f] jit-backend-dump} -[1ce3a9d44b3f] {jit-backend-dump +CODE_DUMP @7fe7c97fbd14 +0 84010000 +[19c47598a8c3] jit-backend-dump} +[19c47598ae17] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd1e +0 9F010000 -[1ce3a9d454c4] jit-backend-dump} -[1ce3a9d458d4] {jit-backend-dump +CODE_DUMP @7fe7c97fbd1e +0 9F010000 +[19c47598b818] jit-backend-dump} +[19c47598bc6c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd31 +0 B1010000 -[1ce3a9d4623b] jit-backend-dump} -[1ce3a9d46651] {jit-backend-dump +CODE_DUMP @7fe7c97fbd31 +0 B1010000 +[19c47598c665] jit-backend-dump} +[19c47598cacb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd42 +0 C5010000 -[1ce3a9d46fa0] jit-backend-dump} -[1ce3a9d473bc] {jit-backend-dump +CODE_DUMP @7fe7c97fbd42 +0 C5010000 +[19c47598d49a] jit-backend-dump} +[19c47598d8fa] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd55 +0 D7010000 -[1ce3a9d47cb2] jit-backend-dump} -[1ce3a9d480c5] {jit-backend-dump +CODE_DUMP @7fe7c97fbd55 +0 D7010000 +[19c47598e2a2] jit-backend-dump} +[19c47598e6f7] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd8d +0 C4010000 -[1ce3a9d489ac] jit-backend-dump} -[1ce3a9d48db9] {jit-backend-dump +CODE_DUMP @7fe7c97fbd8d +0 C4010000 +[19c47598f0d7] jit-backend-dump} +[19c47598f58b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fd9f +0 D7010000 -[1ce3a9d49691] jit-backend-dump} -[1ce3a9d49a95] {jit-backend-dump +CODE_DUMP @7fe7c97fbd9f +0 D7010000 +[19c47598ff0c] jit-backend-dump} +[19c475990358] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fdad +0 EE010000 -[1ce3a9d4a39a] jit-backend-dump} -[1ce3a9d4a9de] {jit-backend-dump +CODE_DUMP @7fe7c97fbdad +0 EE010000 +[19c475990cbc] jit-backend-dump} +[19c475991353] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fdca +0 1B020000 -[1ce3a9d4b2d1] jit-backend-dump} -[1ce3a9d4b70e] {jit-backend-dump +CODE_DUMP @7fe7c97fbdca +0 1B020000 +[19c475991cea] jit-backend-dump} +[19c47599220b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fdf6 +0 14020000 -[1ce3a9d4bfe0] jit-backend-dump} -[1ce3a9d4c3f3] {jit-backend-dump +CODE_DUMP @7fe7c97fbdf6 +0 14020000 +[19c475992b2e] jit-backend-dump} +[19c47599305b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fe09 +0 26020000 -[1ce3a9d4cd54] jit-backend-dump} -[1ce3a9d4d16d] {jit-backend-dump +CODE_DUMP @7fe7c97fbe09 +0 26020000 +[19c475993ac7] jit-backend-dump} +[19c475993f4b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fe40 +0 14020000 -[1ce3a9d4dad7] jit-backend-dump} -[1ce3a9d4ded5] {jit-backend-dump +CODE_DUMP @7fe7c97fbe40 +0 14020000 +[19c47599496a] jit-backend-dump} +[19c475994dad] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fe51 +0 28020000 -[1ce3a9d4e7a7] jit-backend-dump} -[1ce3a9d4ec37] {jit-backend-dump +CODE_DUMP @7fe7c97fbe51 +0 28020000 +[19c4759956f9] jit-backend-dump} +[19c475995c29] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fe6e +0 55020000 -[1ce3a9d4f51e] jit-backend-dump} -[1ce3a9d4fe32] jit-backend} -[1ce3a9d50c1a] {jit-log-opt-loop +CODE_DUMP @7fe7c97fbe6e +0 55020000 +[19c4759965b1] jit-backend-dump} +[19c4759972b1] jit-backend} +[19c475998fc1] {jit-log-opt-loop # Loop 3 ( #15 LOAD_FAST) : loop with 93 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -601,37 +601,37 @@ +164: p15 = getarrayitem_gc(p9, 2, descr=) +168: p17 = getarrayitem_gc(p9, 3, descr=) +172: p18 = getfield_gc(p0, descr=) -+172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(139941277981688)) ++172: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, descr=TargetToken(140633495990080)) debug_merge_point(0, 0, ' #15 LOAD_FAST') -+244: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] -+254: guard_nonnull_class(p13, ConstClass(W_IntObject), descr=) [p1, p0, p13, p2, p3, p4, i5, p6, p11, p15, p17] -+272: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] ++244: guard_value(i7, 2, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17] ++254: guard_nonnull_class(p13, ConstClass(W_IntObject), descr=) [p1, p0, p13, p2, p3, p4, i5, p6, p11, p15, p17] ++272: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p17] debug_merge_point(0, 0, ' #18 LOAD_CONST') -+282: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] ++282: guard_value(p4, ConstPtr(ptr22), descr=) [p1, p0, p4, p2, p3, p6, p11, p13, p17] debug_merge_point(0, 0, ' #21 COMPARE_OP') +301: i23 = getfield_gc_pure(p13, descr=) +305: i25 = int_lt(i23, 10000) -guard_true(i25, descr=) [p1, p0, p13, p2, p3, p6, p11] +guard_true(i25, descr=) [p1, p0, p13, p2, p3, p6, p11] debug_merge_point(0, 0, ' #24 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #27 LOAD_FAST') debug_merge_point(0, 0, ' #30 LOAD_CONST') debug_merge_point(0, 0, ' #33 BINARY_MODULO') +318: i27 = int_eq(i23, -9223372036854775808) -guard_false(i27, descr=) [p1, p0, p13, i23, p2, p3, p6, p11] +guard_false(i27, descr=) [p1, p0, p13, i23, p2, p3, p6, p11] +337: i29 = int_mod(i23, 2) +364: i31 = int_rshift(i29, 63) +371: i32 = int_and(2, i31) +380: i33 = int_add(i29, i32) debug_merge_point(0, 0, ' #34 POP_JUMP_IF_FALSE') +383: i34 = int_is_true(i33) -guard_false(i34, descr=) [p1, p0, p2, p3, p6, p11, p13, i33] +guard_false(i34, descr=) [p1, p0, p2, p3, p6, p11, p13, i33] debug_merge_point(0, 0, ' #53 LOAD_FAST') -+393: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p6, p13, None] ++393: guard_nonnull_class(p11, ConstClass(W_IntObject), descr=) [p1, p0, p11, p2, p3, p6, p13, None] debug_merge_point(0, 0, ' #56 LOAD_CONST') debug_merge_point(0, 0, ' #59 INPLACE_ADD') +411: i37 = getfield_gc_pure(p11, descr=) +415: i39 = int_add_ovf(i37, 1) -guard_no_overflow(descr=) [p1, p0, p11, i39, p2, p3, p6, p13, None] +guard_no_overflow(descr=) [p1, p0, p11, i39, p2, p3, p6, p13, None] debug_merge_point(0, 0, ' #60 STORE_FAST') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') @@ -639,35 +639,35 @@ +425: i41 = int_add(i23, 1) debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+436: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i39, i41, None] ++436: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i39, i41, None] +436: i43 = getfield_raw(51804288, descr=) +444: i45 = int_lt(i43, 0) -guard_false(i45, descr=) [p1, p0, p2, p3, p6, i39, i41, None] +guard_false(i45, descr=) [p1, p0, p2, p3, p6, i39, i41, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+454: label(p0, p1, p2, p3, p6, i39, i41, descr=TargetToken(139941277981776)) ++454: label(p0, p1, p2, p3, p6, i39, i41, descr=TargetToken(140633495990168)) debug_merge_point(0, 0, ' #15 LOAD_FAST') debug_merge_point(0, 0, ' #18 LOAD_CONST') debug_merge_point(0, 0, ' #21 COMPARE_OP') +485: i46 = int_lt(i41, 10000) -guard_true(i46, descr=) [p1, p0, p2, p3, p6, i39, i41] +guard_true(i46, descr=) [p1, p0, p2, p3, p6, i39, i41] debug_merge_point(0, 0, ' #24 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #27 LOAD_FAST') debug_merge_point(0, 0, ' #30 LOAD_CONST') debug_merge_point(0, 0, ' #33 BINARY_MODULO') +498: i47 = int_eq(i41, -9223372036854775808) -guard_false(i47, descr=) [p1, p0, i41, p2, p3, p6, i39, None] +guard_false(i47, descr=) [p1, p0, i41, p2, p3, p6, i39, None] +517: i48 = int_mod(i41, 2) +544: i49 = int_rshift(i48, 63) +551: i50 = int_and(2, i49) +559: i51 = int_add(i48, i50) debug_merge_point(0, 0, ' #34 POP_JUMP_IF_FALSE') +562: i52 = int_is_true(i51) -guard_false(i52, descr=) [p1, p0, p2, p3, p6, i51, i39, i41] +guard_false(i52, descr=) [p1, p0, p2, p3, p6, i51, i39, i41] debug_merge_point(0, 0, ' #53 LOAD_FAST') debug_merge_point(0, 0, ' #56 LOAD_CONST') debug_merge_point(0, 0, ' #59 INPLACE_ADD') +572: i53 = int_add_ovf(i39, 1) -guard_no_overflow(descr=) [p1, p0, i53, p2, p3, p6, None, i39, i41] +guard_no_overflow(descr=) [p1, p0, i53, p2, p3, p6, None, i39, i41] debug_merge_point(0, 0, ' #60 STORE_FAST') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') @@ -675,60 +675,60 @@ +589: i54 = int_add(i41, 1) debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+600: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i54, i53, None, None, None] ++600: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, i54, i53, None, None, None] +600: i55 = getfield_raw(51804288, descr=) +608: i56 = int_lt(i55, 0) -guard_false(i56, descr=) [p1, p0, p2, p3, p6, i54, i53, None, None, None] +guard_false(i56, descr=) [p1, p0, p2, p3, p6, i54, i53, None, None, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+618: jump(p0, p1, p2, p3, p6, i53, i54, descr=TargetToken(139941277981776)) ++618: jump(p0, p1, p2, p3, p6, i53, i54, descr=TargetToken(140633495990168)) +623: --end of the loop-- -[1ce3a9da8a39] jit-log-opt-loop} -[1ce3a9e66b10] {jit-backend -[1ce3a9ee434f] {jit-backend-dump +[19c4759ebff6] jit-log-opt-loop} +[19c475ad90fd] {jit-backend +[19c475b60e23] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180130 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBF000189E467F00004C891C2449BB75E2179E467F000041FFD349BBF83100A1467F00004D8B0B498D510149BBF83100A1467F0000498913488B95580100004C8B4A10488B4A1848C74010000000004883F9020F85000000004D85C90F85000000004C8B8D38010000498B4968488B0425484CB601488D7820483B3C25684CB601761B49BB2001189E467F00004C891C2449BBE3E9179E467F000041FFD348893C25484CB60148C700180C000041C6818D00000001488BBD5001000041F6410401740F415149BB2EE1179E467F000041FFD34989B980000000488BBD4801000041F6410401740F415149BB2EE1179E467F000041FFD34989795041F6410401740F415149BB2EE1179E467F000041FFD349BB380FA59E467F00004D89597041C6818E0000000049C741600000000049C741780200000049C741582A000000F6410481741678105149BB91E1179E467F000041FFD379048049FF01488941104C8D481049C701180C0000488BBD6001000049897908F6410481741678105149BB91E1179E467F000041FFD379048049FF014C89491848C741200000000048C741280000000048C74130000000004C8960084889455848C745108042EA0149BB306000A1467F00004C895D204889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB409C2F9E467F0000415349BB0001189E467F0000415349BB00E0179E467F000041FFE349BB9800EDA0467F0000415349BB1001189E467F0000415349BB00E0179E467F000041FFE3 -[1ce3a9eeacb9] jit-backend-dump} -[1ce3a9eeb70b] {jit-backend-dump +CODE_DUMP @7fe7c97fc130 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBF0C07FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBF8E167CCE77F00004D8B0B498D510149BBF8E167CCE77F0000498913488B95580100004C8B4A10488B4A1848C74010000000004883F9020F85000000004D85C90F85000000004C8B8D38010000498B4968488B0425484CB601488D7820483B3C25684CB601761B49BB20C17FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C700180C000041C6818D00000001488BBD5001000041F6410401740F415149BB2EA17FC9E77F000041FFD34989B980000000488BBD4801000041F6410401740F415149BB2EA17FC9E77F000041FFD34989795041F6410401740F415149BB2EA17FC9E77F000041FFD349BB38CF0CCAE77F00004D89597041C6818E0000000049C741600000000049C741780200000049C741582A000000F6410481741678105149BB91A17FC9E77F000041FFD379048049FF01488941104C8D481049C701180C0000488BBD6001000049897908F6410481741678105149BB91A17FC9E77F000041FFD379048049FF014C89491848C741200000000048C741280000000048C74130000000004C8960084889455848C745108042EA0149BB301068CCE77F00004C895D204889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB40FC96C9E77F0000415349BB00C17FC9E77F0000415349BB00A07FC9E77F000041FFE349BB986054CCE77F0000415349BB10C17FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c475b67831] jit-backend-dump} +[19c475b68364] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180134 +0 22000000 -[1ce3a9eec253] jit-backend-dump} -[1ce3a9eec730] {jit-backend-dump +CODE_DUMP @7fe7c97fc134 +0 22000000 +[19c475b68e8f] jit-backend-dump} +[19c475b693cb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18013f +0 22000000 -[1ce3a9eed097] jit-backend-dump} -[1ce3a9eed72f] {jit-backend-addr -bridge out of Guard 0x7f469e2f82f0 has address 0x7f469e180130 to 0x7f469e18033d -[1ce3a9eee408] jit-backend-addr} -[1ce3a9eee927] {jit-backend-dump +CODE_DUMP @7fe7c97fc13f +0 22000000 +[19c475b69e25] jit-backend-dump} +[19c475b6a3f6] {jit-backend-addr +bridge out of Guard 0x7fe7c996e2f0 has address 0x7fe7c97fc130 to 0x7fe7c97fc33d +[19c475b6b2b4] jit-backend-addr} +[19c475b6b864] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180199 +0 A0010000 -[1ce3a9eef2d2] jit-backend-dump} -[1ce3a9eef71a] {jit-backend-dump +CODE_DUMP @7fe7c97fc199 +0 A0010000 +[19c475b6c292] jit-backend-dump} +[19c475b6c766] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1801a2 +0 BC010000 -[1ce3a9eeffe7] jit-backend-dump} -[1ce3a9ef05ff] {jit-backend-dump +CODE_DUMP @7fe7c97fc1a2 +0 BC010000 +[19c475b6d09d] jit-backend-dump} +[19c475b6d7ac] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17f851 +0 DB080000 -[1ce3a9ef0eec] jit-backend-dump} -[1ce3a9ef16fa] jit-backend} -[1ce3a9ef225a] {jit-log-opt-bridge -# bridge out of Guard 0x7f469e2f82f0 with 28 ops +CODE_DUMP @7fe7c97fb851 +0 DB080000 +[19c475b6e130] jit-backend-dump} +[19c475b6ea53] jit-backend} +[19c475b6f6d9] {jit-log-opt-bridge +# bridge out of Guard 0x7fe7c996e2f0 with 28 ops [p0, p1, p2, i3, i4, i5, p6, p7, p8, i9, i10] debug_merge_point(0, 0, ' #38 POP_BLOCK') +76: p11 = getfield_gc_pure(p8, descr=) +87: i12 = getfield_gc_pure(p8, descr=) +91: setfield_gc(p2, ConstPtr(ptr13), descr=) -+99: guard_value(i12, 2, descr=) [p0, p1, i12, p6, p7, p11, i10, i9] ++99: guard_value(i12, 2, descr=) [p0, p1, i12, p6, p7, p11, i10, i9] debug_merge_point(0, 0, ' #39 LOAD_FAST') debug_merge_point(0, 0, ' #42 RETURN_VALUE') -+109: guard_isnull(p11, descr=) [p0, p1, p11, p6, p7, i10, i9] ++109: guard_isnull(p11, descr=) [p0, p1, p11, p6, p7, i10, i9] +118: p15 = getfield_gc(p1, descr=) +129: p16 = getfield_gc(p1, descr=) p18 = new_with_vtable(ConstClass(W_IntObject)) @@ -750,158 +750,158 @@ +448: setfield_gc(p18, i10, descr=) +452: finish(p18, descr=) +525: --end of the loop-- -[1ce3a9f131a1] jit-log-opt-bridge} -[1ce3aa3c4c80] {jit-backend -[1ce3aa535471] {jit-backend-dump +[19c475b92846] jit-log-opt-bridge} +[19c47608ae49] {jit-backend +[19c47620d562] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180568 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB8803189E467F00004C891C2449BB75E2179E467F000041FFD349BB103200A1467F0000498B034C8D780149BB103200A1467F00004D893B4C8BBD38010000498B470849BBC8009F9E467F00004C39D80F85000000004C8B701049BBA84EA49E467F00004D39DE0F850000000049BBC803189E467F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDE1179E467F000041FFD348C74520000000004C8B78504989EE4C8B68604D85ED0F85000000004C8B68404983FD000F85000000004C8B2C2500EFCE014981FDF0EED4010F85000000004C8B2C25807816034983FD000F8C000000004989ED48898570010000488B0425484CB601488DB840010000483B3C25684CB601761B49BB2804189E467F00004C891C2449BBE3E9179E467F000041FFD348893C25484CB60148C700407E0100488DB89000000048C707C800000048C74708050000004C8D673849C70424180C00004D8D54241049C702180C00004D8D4A1049C701E82200004D8D411849C70070400000498D701848C706C800000048C7460800000000488D5E1048C703180600004C8973084C8BB57001000041F6460401740F415649BB2EE1179E467F000041FFD349895E50488B9538010000F6420401740E5249BB2EE1179E467F000041FFD34C896A1849C7442408010000004C8967104C89571849BB60BFECA0467F00004D89580849C74010C01CF1014D89411049C74108010000004C894F204889786848C740780300000049BB80BFECA0467F00004C8958604C89783048C740581300000048897028C780880000001500000049BBC8009F9E467F00004C89580849BB380FA59E467F00004C89587049BB60F5179E467F0000498B3348898578010000488B3C25484CB6014889F84801F7483B3C25684CB601761B49BB3804189E467F00004C891C2449BBE3E9179E467F000041FFD348893C25484CB60148C7000800000049BB58F5179E467F0000498B334889705049BB58F5179E467F00004C895808488BB5780100004889B0380100004C89B04001000048899D8001000049BBA00CEFA0467F00004C895D184889C749BB5804189E467F00004C895D2049BB68F6179E467F000041FFD3F6450401740D49BBFDE1179E467F000041FFD348C7452000000000488178108042EA01743E4889C7488BB57801000049BB6804189E467F00004C895D2041BB908D080141FFD3F6450401740D49BBFDE1179E467F000041FFD348C7452000000000EB13488B957801000048C7421800000000488B405848837D10000F850000000048833C2500E61503000F8500000000488B9570010000488B72604885F60F8500000000488B72404C8BB57801000049C74650000000004883FE000F8500000000488B7250498B5E30490FB6BE8C000000F6420401740E5249BB2EE1179E467F000041FFD348895A504885FF0F8500000000488BBD8001000048C74708000000008138180C00000F8500000000488B7808488B95600100004801FA0F8000000000488BBD680100004883C7010F8000000000488B0425807816034883F8000F8C0000000049BB283200A1467F0000498B034C8D700149BB283200A1467F00004D89334881FF102700000F8D0000000049BB00000000000000804C39DF0F84000000004889F8B9020000004889956001000048898568010000489948F7F94889D048C1FA3FBF020000004821D74801F84883F8000F8500000000488B85600100004883C0010F8000000000488BBD680100004883C701488B1425807816034883FA000F8C000000004889FB49BBCEFD179E467F000041FFE349BB7802EDA0467F0000415349BB9803189E467F0000415349BB00E0179E467F000041FFE349BB5833EFA0467F0000415349BBA803189E467F0000415349BB00E0179E467F000041FFE349BBE032EFA0467F0000415349BBB803189E467F0000415349BB00E0179E467F000041FFE349BB6832EFA0467F0000415349BBD803189E467F0000415349BB00E0179E467F000041FFE349BBF031EFA0467F0000415349BBE803189E467F0000415349BB00E0179E467F000041FFE349BB7831EFA0467F0000415349BBF803189E467F0000415349BB00E0179E467F000041FFE349BB0031EFA0467F0000415349BB0804189E467F0000415349BB00E0179E467F000041FFE349BB8830EFA0467F0000415349BB1804189E467F0000415349BB00E0179E467F000041FFE349BBA00CEFA0467F0000415349BB4804189E467F0000415349BB85E0179E467F000041FFE349BB1030EFA0467F0000415349BB7804189E467F0000415349BB85E0179E467F000041FFE349BB982FEFA0467F0000415349BB8804189E467F0000415349BB00E0179E467F000041FFE349BB202FEFA0467F0000415349BB9804189E467F0000415349BB00E0179E467F000041FFE349BBA82EEFA0467F0000415349BBA804189E467F0000415349BB00E0179E467F000041FFE349BB302EEFA0467F0000415349BBB804189E467F0000415349BB00E0179E467F000041FFE349BBB82DEFA0467F0000415349BBC804189E467F0000415349BB00E0179E467F000041FFE349BB402DEFA0467F0000415349BBD804189E467F0000415349BB00E0179E467F000041FFE349BBC82CEFA0467F0000415349BBE804189E467F0000415349BB00E0179E467F000041FFE349BB502CEFA0467F0000415349BBF804189E467F0000415349BB00E0179E467F000041FFE349BBD82BEFA0467F0000415349BB0805189E467F0000415349BB00E0179E467F000041FFE349BB602BEFA0467F0000415349BB1805189E467F0000415349BB00E0179E467F000041FFE349BBE82AEFA0467F0000415349BB2805189E467F0000415349BB00E0179E467F000041FFE349BB702AEFA0467F0000415349BB3805189E467F0000415349BB00E0179E467F000041FFE349BBF829EFA0467F0000415349BB4805189E467F0000415349BB00E0179E467F000041FFE349BB8029EFA0467F0000415349BB5805189E467F0000415349BB00E0179E467F000041FFE3 -[1ce3aa54fb27] jit-backend-dump} -[1ce3aa550a05] {jit-backend-dump +CODE_DUMP @7fe7c97fc568 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88C37FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BB10E267CCE77F0000498B034C8D780149BB10E267CCE77F00004D893B4C8BBD38010000498B470849BBB00007CAE77F00004C39D80F85000000004C8B701049BB900E0CCAE77F00004D39DE0F850000000049BBC8C37FC9E77F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C74520000000004C8B78504989EE4C8B68604D85ED0F85000000004C8B68404983FD000F85000000004C8B2C2500EFCE014981FDF0EED4010F85000000004C8B2C25807816034983FD000F8C000000004989ED48898570010000488B0425484CB601488DB840010000483B3C25684CB601761B49BB28C47FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C700407E0100488DB89000000048C707C800000048C74708050000004C8D673849C70424180C00004D8D54241049C702180C00004D8D4A1049C701E82200004D8D411849C70070400000498D701848C706C800000048C7460800000000488D5E1048C703180600004C8973084C8BB57001000041F6460401740F415649BB2EA17FC9E77F000041FFD349895E50488B9538010000F6420401740E5249BB2EA17FC9E77F000041FFD34C896A1849C7442408010000004C8967104C89571849BB808554CCE77F00004D89580849C74010C01CF1014D89411049C74108010000004C894F204889786848C740780300000049BBA08554CCE77F00004C8958604C89783048C740581300000048897028C780880000001500000049BBB00007CAE77F00004C89580849BB38CF0CCAE77F00004C89587049BB60B57FC9E77F0000498B3348898578010000488B3C25484CB6014889F84801F7483B3C25684CB601761B49BB38C47FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C7000800000049BB58B57FC9E77F0000498B334889705049BB58B57FC9E77F00004C895808488BB5780100004889B0380100004C89B04001000048899D8001000049BB204C56CCE77F00004C895D184889C749BB58C47FC9E77F00004C895D2049BB68B67FC9E77F000041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C7452000000000488178108042EA01743E4889C7488BB57801000049BB68C47FC9E77F00004C895D2041BB908D080141FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C7452000000000EB13488B957801000048C7421800000000488B405848837D10000F850000000048833C2500E61503000F8500000000488B9570010000488B5A604885DB0F8500000000488B5A40488BB57801000048C74650000000004883FB000F8500000000488B5A504C8B7630480FB6BE8C000000F6420401740E5249BB2EA17FC9E77F000041FFD34C8972504885FF0F8500000000488BBD8001000048C74708000000008138180C00000F8500000000488B7808488B95600100004801FA0F8000000000488BBD680100004883C7010F8000000000488B0425807816034883F8000F8C0000000049BB28E267CCE77F0000498B03488D700149BB28E267CCE77F00004989334881FF102700000F8D0000000049BB00000000000000804C39DF0F84000000004889F8B9020000004889956001000048898568010000489948F7F94889D048C1FA3FBF020000004821D74801F84883F8000F8500000000488B85600100004883C0010F8000000000488BBD680100004883C701488B1425807816034883FA000F8C000000004889FB49BBCEBD7FC9E77F000041FFE349BB786254CCE77F0000415349BB98C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB587356CCE77F0000415349BBA8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE07256CCE77F0000415349BBB8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB687256CCE77F0000415349BBD8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF07156CCE77F0000415349BBE8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB787156CCE77F0000415349BBF8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB007156CCE77F0000415349BB08C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB887056CCE77F0000415349BB18C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB204C56CCE77F0000415349BB48C47FC9E77F0000415349BB85A07FC9E77F000041FFE349BB107056CCE77F0000415349BB78C47FC9E77F0000415349BB85A07FC9E77F000041FFE349BB986F56CCE77F0000415349BB88C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB206F56CCE77F0000415349BB98C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA86E56CCE77F0000415349BBA8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB306E56CCE77F0000415349BBB8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBB86D56CCE77F0000415349BBC8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB406D56CCE77F0000415349BBD8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBC86C56CCE77F0000415349BBE8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB506C56CCE77F0000415349BBF8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD86B56CCE77F0000415349BB08C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB606B56CCE77F0000415349BB18C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE86A56CCE77F0000415349BB28C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB706A56CCE77F0000415349BB38C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF86956CCE77F0000415349BB48C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB806956CCE77F0000415349BB58C57FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4762283c4] jit-backend-dump} +[19c476229554] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18056c +0 26000000 -[1ce3aa551990] jit-backend-dump} -[1ce3aa551ea8] {jit-backend-dump +CODE_DUMP @7fe7c97fc56c +0 26000000 +[19c47622a4ac] jit-backend-dump} +[19c47622a9be] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180577 +0 26000000 -[1ce3aa552915] jit-backend-dump} -[1ce3aa552df8] {jit-backend-addr -bridge out of Guard 0x7f469e2f9448 has address 0x7f469e180568 to 0x7f469e180a92 -[1ce3aa553bb9] jit-backend-addr} -[1ce3aa55430f] {jit-backend-dump +CODE_DUMP @7fe7c97fc577 +0 26000000 +[19c47622b445] jit-backend-dump} +[19c47622b967] {jit-backend-addr +bridge out of Guard 0x7fe7c996f448 has address 0x7fe7c97fc568 to 0x7fe7c97fca92 +[19c47622c725] jit-backend-addr} +[19c47622ce57] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1805ce +0 C0040000 -[1ce3aa554ca2] jit-backend-dump} -[1ce3aa5551e1] {jit-backend-dump +CODE_DUMP @7fe7c97fc5ce +0 C0040000 +[19c47622d7fc] jit-backend-dump} +[19c47622ddfa] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1805e5 +0 CE040000 -[1ce3aa555ad1] jit-backend-dump} -[1ce3aa556013] {jit-backend-dump +CODE_DUMP @7fe7c97fc5e5 +0 CE040000 +[19c47622e73d] jit-backend-dump} +[19c47622ed4f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18062b +0 D2040000 -[1ce3aa5569cd] jit-backend-dump} -[1ce3aa556e1f] {jit-backend-dump +CODE_DUMP @7fe7c97fc62b +0 D2040000 +[19c47622f6b6] jit-backend-dump} +[19c47622faf5] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180639 +0 E9040000 -[1ce3aa557771] jit-backend-dump} -[1ce3aa557bf5] {jit-backend-dump +CODE_DUMP @7fe7c97fc639 +0 E9040000 +[19c4762303fd] jit-backend-dump} +[19c476230872] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18064e +0 1E050000 -[1ce3aa5584ca] jit-backend-dump} -[1ce3aa5588f2] {jit-backend-dump +CODE_DUMP @7fe7c97fc64e +0 1E050000 +[19c476231192] jit-backend-dump} +[19c4762315d1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180660 +0 31050000 -[1ce3aa5591c4] jit-backend-dump} -[1ce3aa5595d4] {jit-backend-dump +CODE_DUMP @7fe7c97fc660 +0 31050000 +[19c476231eb5] jit-backend-dump} +[19c4762322c8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180918 +0 9E020000 -[1ce3aa559ee5] jit-backend-dump} -[1ce3aa55a2fe] {jit-backend-dump +CODE_DUMP @7fe7c97fc918 +0 9E020000 +[19c476232b8c] jit-backend-dump} +[19c476232fec] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180927 +0 B4020000 -[1ce3aa55abc7] jit-backend-dump} -[1ce3aa55b012] {jit-backend-dump +CODE_DUMP @7fe7c97fc927 +0 B4020000 +[19c476233926] jit-backend-dump} +[19c476233d6c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18093b +0 C5020000 -[1ce3aa55df15] jit-backend-dump} -[1ce3aa55e492] {jit-backend-dump +CODE_DUMP @7fe7c97fc93b +0 C5020000 +[19c476236834] jit-backend-dump} +[19c476236d7c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180958 +0 CD020000 -[1ce3aa55ee46] jit-backend-dump} -[1ce3aa55f26e] {jit-backend-dump +CODE_DUMP @7fe7c97fc958 +0 CD020000 +[19c47623773c] jit-backend-dump} +[19c476237b4c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180989 +0 C1020000 -[1ce3aa55fce6] jit-backend-dump} -[1ce3aa560111] {jit-backend-dump +CODE_DUMP @7fe7c97fc989 +0 C1020000 +[19c476238442] jit-backend-dump} +[19c476238835] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1809a4 +0 CB020000 -[1ce3aa5609ce] jit-backend-dump} -[1ce3aa560df3] {jit-backend-dump +CODE_DUMP @7fe7c97fc9a4 +0 CB020000 +[19c476239131] jit-backend-dump} +[19c476239535] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1809b8 +0 DC020000 -[1ce3aa561725] jit-backend-dump} -[1ce3aa561b3e] {jit-backend-dump +CODE_DUMP @7fe7c97fc9b8 +0 DC020000 +[19c476239e16] jit-backend-dump} +[19c47623a220] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1809c9 +0 F0020000 -[1ce3aa5623e9] jit-backend-dump} -[1ce3aa562e4d] {jit-backend-dump +CODE_DUMP @7fe7c97fc9c9 +0 F0020000 +[19c47623aae9] jit-backend-dump} +[19c47623b4a3] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1809db +0 28030000 -[1ce3aa563737] jit-backend-dump} -[1ce3aa563b44] {jit-backend-dump +CODE_DUMP @7fe7c97fc9db +0 28030000 +[19c47623bddb] jit-backend-dump} +[19c47623c1eb] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180a06 +0 22030000 -[1ce3aa564407] jit-backend-dump} -[1ce3aa564823] {jit-backend-dump +CODE_DUMP @7fe7c97fca06 +0 22030000 +[19c47623ca8a] jit-backend-dump} +[19c47623ce89] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180a19 +0 34030000 -[1ce3aa5650c9] jit-backend-dump} -[1ce3aa5654df] {jit-backend-dump +CODE_DUMP @7fe7c97fca19 +0 34030000 +[19c47623d73a] jit-backend-dump} +[19c47623db4a] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180a50 +0 22030000 -[1ce3aa565d76] jit-backend-dump} -[1ce3aa5661a6] {jit-backend-dump +CODE_DUMP @7fe7c97fca50 +0 22030000 +[19c47623e458] jit-backend-dump} +[19c47623e859] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180a61 +0 36030000 -[1ce3aa566a58] jit-backend-dump} -[1ce3aa566ed3] {jit-backend-dump +CODE_DUMP @7fe7c97fca61 +0 36030000 +[19c47623f149] jit-backend-dump} +[19c47623f5ac] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180a7e +0 63030000 -[1ce3aa5677a2] jit-backend-dump} -[1ce3aa567e34] {jit-backend-dump +CODE_DUMP @7fe7c97fca7e +0 63030000 +[19c47623fe90] jit-backend-dump} +[19c4762406c8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fe40 +0 24070000 -[1ce3aa56872d] jit-backend-dump} -[1ce3aa569310] jit-backend} -[1ce3aa56a308] {jit-log-opt-bridge -# bridge out of Guard 0x7f469e2f9448 with 137 ops +CODE_DUMP @7fe7c97fbe40 +0 24070000 +[19c476240faf] jit-backend-dump} +[19c476241c2f] jit-backend} +[19c476242fb5] {jit-log-opt-bridge +# bridge out of Guard 0x7fe7c996f448 with 137 ops [p0, p1, p2, p3, p4, i5, i6, i7] debug_merge_point(0, 0, ' #37 LOAD_FAST') debug_merge_point(0, 0, ' #40 LOAD_GLOBAL') +76: p8 = getfield_gc(p1, descr=) -+87: guard_value(p8, ConstPtr(ptr9), descr=) [p0, p1, p8, p2, p3, p4, i6, i7] ++87: guard_value(p8, ConstPtr(ptr9), descr=) [p0, p1, p8, p2, p3, p4, i6, i7] +106: p10 = getfield_gc(p8, descr=) -+110: guard_value(p10, ConstPtr(ptr11), descr=) [p0, p1, p10, p8, p2, p3, p4, i6, i7] -+129: guard_not_invalidated(descr=) [p0, p1, p8, p2, p3, p4, i6, i7] ++110: guard_value(p10, ConstPtr(ptr11), descr=) [p0, p1, p10, p8, p2, p3, p4, i6, i7] ++129: guard_not_invalidated(descr=) [p0, p1, p8, p2, p3, p4, i6, i7] debug_merge_point(0, 0, ' #43 CALL_FUNCTION') +129: p13 = call(ConstClass(getexecutioncontext), descr=) +179: p14 = getfield_gc(p13, descr=) +183: p15 = force_token() +186: p16 = getfield_gc(p13, descr=) -+190: guard_isnull(p16, descr=) [p0, p1, p13, p16, p2, p3, p4, p14, p15, i6, i7] ++190: guard_isnull(p16, descr=) [p0, p1, p13, p16, p2, p3, p4, p14, p15, i6, i7] +199: i17 = getfield_gc(p13, descr=) +203: i18 = int_is_zero(i17) -guard_true(i18, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] +guard_true(i18, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] debug_merge_point(1, 1, ' #0 LOAD_CONST') debug_merge_point(1, 1, ' #3 STORE_FAST') debug_merge_point(1, 1, ' #6 SETUP_LOOP') debug_merge_point(1, 1, ' #9 LOAD_GLOBAL') -+213: guard_not_invalidated(descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] ++213: guard_not_invalidated(descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] +213: p20 = getfield_gc(ConstPtr(ptr19), descr=) -+221: guard_value(p20, ConstPtr(ptr21), descr=) [p0, p1, p13, p20, p2, p3, p4, p14, p15, i6, i7] ++221: guard_value(p20, ConstPtr(ptr21), descr=) [p0, p1, p13, p20, p2, p3, p4, p14, p15, i6, i7] debug_merge_point(1, 1, ' #12 LOAD_CONST') debug_merge_point(1, 1, ' #15 CALL_FUNCTION') debug_merge_point(1, 1, ' #18 GET_ITER') @@ -914,7 +914,7 @@ debug_merge_point(1, 1, ' #35 JUMP_ABSOLUTE') +234: i23 = getfield_raw(51804288, descr=) +242: i25 = int_lt(i23, 0) -guard_false(i25, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] +guard_false(i25, descr=) [p0, p1, p13, p2, p3, p4, p14, p15, i6, i7] debug_merge_point(1, 1, ' #19 FOR_ITER') +252: p26 = force_token() p28 = new_with_vtable(26266048) @@ -946,63 +946,63 @@ +602: setfield_gc(p28, ConstPtr(ptr9), descr=) +616: setfield_gc(p28, ConstPtr(ptr54), descr=) p55 = call_assembler(p28, p13, descr=) -guard_not_forced(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i6, i7] +guard_not_forced(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i6, i7] +948: keepalive(p28) -+948: guard_no_exception(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i6, i7] ++948: guard_no_exception(descr=) [p0, p1, p13, p28, p55, p42, p2, p3, p4, i6, i7] +963: p56 = getfield_gc(p13, descr=) -+974: guard_isnull(p56, descr=) [p0, p1, p55, p13, p28, p56, p42, p2, p3, p4, i6, i7] ++974: guard_isnull(p56, descr=) [p0, p1, p55, p13, p28, p56, p42, p2, p3, p4, i6, i7] +983: i57 = getfield_gc(p13, descr=) +987: setfield_gc(p28, ConstPtr(ptr58), descr=) +1002: i59 = int_is_true(i57) -guard_false(i59, descr=) [p0, p1, p55, p28, p13, p42, p2, p3, p4, i6, i7] +guard_false(i59, descr=) [p0, p1, p55, p28, p13, p42, p2, p3, p4, i6, i7] +1012: p60 = getfield_gc(p13, descr=) +1016: p61 = getfield_gc(p28, descr=) +1020: i62 = getfield_gc(p28, descr=) setfield_gc(p13, p61, descr=) -+1052: guard_false(i62, descr=) [p0, p1, p55, p60, p28, p13, p42, p2, p3, p4, i6, i7] ++1052: guard_false(i62, descr=) [p0, p1, p55, p60, p28, p13, p42, p2, p3, p4, i6, i7] debug_merge_point(0, 0, ' #46 INPLACE_ADD') +1061: setfield_gc(p42, ConstPtr(ptr63), descr=) -+1076: guard_class(p55, ConstClass(W_IntObject), descr=) [p0, p1, p55, p2, p3, p4, i6, i7] ++1076: guard_class(p55, ConstClass(W_IntObject), descr=) [p0, p1, p55, p2, p3, p4, i6, i7] +1088: i65 = getfield_gc_pure(p55, descr=) +1092: i66 = int_add_ovf(i6, i65) -guard_no_overflow(descr=) [p0, p1, p55, i66, p2, p3, p4, i6, i7] +guard_no_overflow(descr=) [p0, p1, p55, i66, p2, p3, p4, i6, i7] debug_merge_point(0, 0, ' #47 STORE_FAST') debug_merge_point(0, 0, ' #50 JUMP_FORWARD') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') debug_merge_point(0, 0, ' #69 INPLACE_ADD') +1108: i68 = int_add_ovf(i7, 1) -guard_no_overflow(descr=) [p0, p1, i68, p2, p3, p4, i66, None, i7] +guard_no_overflow(descr=) [p0, p1, i68, p2, p3, p4, i66, None, i7] debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+1125: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] ++1125: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] +1125: i71 = getfield_raw(51804288, descr=) +1133: i73 = int_lt(i71, 0) -guard_false(i73, descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] +guard_false(i73, descr=) [p0, p1, p2, p3, p4, i68, i66, None, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+1143: label(p1, p0, p2, p3, p4, i66, i68, descr=TargetToken(139941324358104)) ++1143: label(p1, p0, p2, p3, p4, i66, i68, descr=TargetToken(140633495991488)) debug_merge_point(0, 0, ' #18 LOAD_CONST') debug_merge_point(0, 0, ' #21 COMPARE_OP') +1173: i75 = int_lt(i68, 10000) -guard_true(i75, descr=) [p0, p1, p2, p3, p4, i66, i68] +guard_true(i75, descr=) [p0, p1, p2, p3, p4, i66, i68] debug_merge_point(0, 0, ' #24 POP_JUMP_IF_FALSE') debug_merge_point(0, 0, ' #27 LOAD_FAST') debug_merge_point(0, 0, ' #30 LOAD_CONST') debug_merge_point(0, 0, ' #33 BINARY_MODULO') +1186: i77 = int_eq(i68, -9223372036854775808) -guard_false(i77, descr=) [p0, p1, i68, p2, p3, p4, i66, None] +guard_false(i77, descr=) [p0, p1, i68, p2, p3, p4, i66, None] +1205: i79 = int_mod(i68, 2) +1232: i81 = int_rshift(i79, 63) +1239: i82 = int_and(2, i81) +1247: i83 = int_add(i79, i82) debug_merge_point(0, 0, ' #34 POP_JUMP_IF_FALSE') +1250: i84 = int_is_true(i83) -guard_false(i84, descr=) [p0, p1, p2, p3, p4, i83, i66, i68] +guard_false(i84, descr=) [p0, p1, p2, p3, p4, i83, i66, i68] debug_merge_point(0, 0, ' #53 LOAD_FAST') debug_merge_point(0, 0, ' #56 LOAD_CONST') debug_merge_point(0, 0, ' #59 INPLACE_ADD') +1260: i86 = int_add_ovf(i66, 1) -guard_no_overflow(descr=) [p0, p1, i86, p2, p3, p4, None, i66, i68] +guard_no_overflow(descr=) [p0, p1, i86, p2, p3, p4, None, i66, i68] debug_merge_point(0, 0, ' #60 STORE_FAST') debug_merge_point(0, 0, ' #63 LOAD_FAST') debug_merge_point(0, 0, ' #66 LOAD_CONST') @@ -1010,150 +1010,150 @@ +1277: i88 = int_add(i68, 1) debug_merge_point(0, 0, ' #70 STORE_FAST') debug_merge_point(0, 0, ' #73 JUMP_ABSOLUTE') -+1288: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] ++1288: guard_not_invalidated(descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] +1288: i90 = getfield_raw(51804288, descr=) +1296: i92 = int_lt(i90, 0) -guard_false(i92, descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] +guard_false(i92, descr=) [p0, p1, p2, p3, p4, i86, i88, None, None, None] debug_merge_point(0, 0, ' #15 LOAD_FAST') -+1306: jump(p1, p0, p2, p3, p4, i86, i88, descr=TargetToken(139941277981776)) ++1306: jump(p1, p0, p2, p3, p4, i86, i88, descr=TargetToken(140633495990168)) +1322: --end of the loop-- -[1ce3aa5e579f] jit-log-opt-bridge} -[1ce3aa7e0c3a] {jit-backend-dump +[19c4762c0a61] jit-log-opt-bridge} +[19c476497d1a] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fdbc +0 E903020000 -[1ce3aa7e555a] jit-backend-dump} -[1ce3aa7e5d06] {jit-backend-dump +CODE_DUMP @7fe7c97fbdbc +0 E903020000 +[19c47649be73] jit-backend-dump} +[19c47649c3b8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e17fe60 +0 E93D020000 -[1ce3aa7e6960] jit-backend-dump} -[1ce3aa7e6d8e] {jit-backend-dump +CODE_DUMP @7fe7c97fbe60 +0 E93D020000 +[19c47649ce6f] jit-backend-dump} +[19c47649d42e] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1805e9 +0 E9EE040000 -[1ce3aa7e7803] jit-backend-dump} -[1ce3aa7e7e36] {jit-backend-dump +CODE_DUMP @7fe7c97fc5e9 +0 E9EE040000 +[19c47649e0fb] jit-backend-dump} +[19c47649e5b2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18063d +0 E909050000 -[1ce3aa7e885b] jit-backend-dump} -[1ce3aa7e8cd6] {jit-backend-dump +CODE_DUMP @7fe7c97fc63d +0 E909050000 +[19c47649efa7] jit-backend-dump} +[19c47649f437] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1809cd +0 E910030000 -[1ce3aa7e962e] jit-backend-dump} -[1ce3aa7e9a26] {jit-backend-dump +CODE_DUMP @7fe7c97fc9cd +0 E910030000 +[19c47649fddf] jit-backend-dump} +[19c4764a029c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180a70 +0 E94B030000 -[1ce3aa7ea378] jit-backend-dump} -[1ce3aac76e4f] {jit-backend -[1ce3aad31fe8] {jit-backend-dump +CODE_DUMP @7fe7c97fca70 +0 E94B030000 +[19c4764a0c44] jit-backend-dump} +[19c476926513] {jit-backend +[19c4769db8ef] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e180fb0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BB403200A1467F00004D8B3B4D8D770149BB403200A1467F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E284C89AD480100004C8B6E304C89AD500100004C8B6E3848899558010000488B564048898D60010000488B4E484C89BD680100004C898D700100004889BD7801000048899D80010000488985880100004C89AD900100004889959801000048898DA001000049BB583200A1467F0000498B0B488D510149BB583200A1467F00004989134983F8050F85000000004C8B8550010000418138E82200000F8500000000498B50104885D20F8400000000498B48084C8B6A1041817D00685505000F85000000004C8B6A08498B5508498B4510498B5D184883F9000F8C000000004839D90F8D000000004989CD480FAFC84889D74801CA498D4D01498948084983FA000F850000000049BBA810A59E467F00004D39DC0F85000000004D8B660849BBC8009F9E467F00004D39DC0F85000000004D8B54241049BBA84EA49E467F00004D39DA0F85000000004C8B242500EFCE014981FCF0EED4010F8500000000488985380100004889957801000048898D800100004C89B5900100004889BD980100004889D749BBE00E189E467F00004C895D2041BB5050250141FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488BBD600100004C8B771041813E489303000F85000000004C8B7708498B4E08488D5101488985A801000048898DB00100004C89B5B80100004C89F74889D649BB100F189E467F00004C895D2041BBB05F730041FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488B95B80100004C8B7210488BBDB0010000488B8DA801000041F646048174227811415649BB91E1179E467F000041FFD3790F4989FB49C1EB074983F3F84D0FAB1E49894CFE10488B0C25807816034883F9000F8C0000000049BB703200A1467F0000498B0B488D790149BB703200A1467F000049893B48399D800100000F8D00000000488BBD80010000480FAFBD38010000488B8D980100004801F9488BBD800100004883C7014C8BB55001000049897E084889957801000048898D800100004889BDA80100004889CF49BB600F189E467F00004C895D2041BB5050250141FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488BBD78010000488B4F084C8D710148898DB0010000488985B80100004C89F649BB800F189E467F00004C895D2041BBB05F730041FFD3F6450401740D49BBFDE1179E467F000041FFD348C745200000000048833C2500E61503000F8500000000488B8578010000488B48104C8BB5B0010000488BBDB8010000F6410481742178105149BB91E1179E467F000041FFD3790F4D89F349C1EB074983F3F84C0FAB194A897CF110488B3C25807816034883FF000F8C000000004C8B9D800100004C899D780100004C8B9DA80100004C899D800100004889C2E971FEFFFF49BBF878F0A0467F0000415349BB200E189E467F0000415349BB00E0179E467F000041FFE349BB7871F0A0467F0000415349BB300E189E467F0000415349BB00E0179E467F000041FFE349BB986FF0A0467F0000415349BB400E189E467F0000415349BB00E0179E467F000041FFE349BB0071F0A0467F0000415349BB500E189E467F0000415349BB00E0179E467F000041FFE349BB8078F0A0467F0000415349BB600E189E467F0000415349BB00E0179E467F000041FFE349BB0878F0A0467F0000415349BB700E189E467F0000415349BB00E0179E467F000041FFE349BB9077F0A0467F0000415349BB800E189E467F0000415349BB00E0179E467F000041FFE349BBA076F0A0467F0000415349BB900E189E467F0000415349BB00E0179E467F000041FFE349BBB075F0A0467F0000415349BBA00E189E467F0000415349BB00E0179E467F000041FFE349BB3875F0A0467F0000415349BBB00E189E467F0000415349BB00E0179E467F000041FFE349BB4874F0A0467F0000415349BBC00E189E467F0000415349BB00E0179E467F000041FFE349BB5873F0A0467F0000415349BBD00E189E467F0000415349BB00E0179E467F000041FFE349BBE072F0A0467F0000415349BBF00E189E467F0000415349BB85E0179E467F000041FFE349BB1070F0A0467F0000415349BB000F189E467F0000415349BB00E0179E467F000041FFE349BB6872F0A0467F0000415349BB200F189E467F0000415349BB85E0179E467F000041FFE349BBF071F0A0467F0000415349BB300F189E467F0000415349BB00E0179E467F000041FFE349BB506CF0A0467F0000415349BB400F189E467F0000415349BB00E0179E467F000041FFE349BB0869F0A0467F0000415349BB500F189E467F0000415349BB00E0179E467F000041FFE349BBD033EFA0467F0000415349BB700F189E467F0000415349BB85E0179E467F000041FFE349BBE879F0A0467F0000415349BB900F189E467F0000415349BB85E0179E467F000041FFE349BB607AF0A0467F0000415349BBA00F189E467F0000415349BB00E0179E467F000041FFE3 -[1ce3aad4eb07] jit-backend-dump} -[1ce3aad4f6d8] {jit-backend-addr -Loop 4 ( #13 FOR_ITER) has address 0x7f469e181000 to 0x7f469e181487 (bootstrap 0x7f469e180fb0) -[1ce3aad50b8d] jit-backend-addr} -[1ce3aad51292] {jit-backend-dump +CODE_DUMP @7fe7c97fcfb0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6AB7FC9E77F000041FFD349BB40E267CCE77F00004D8B3B4D8D770149BB40E267CCE77F00004D89334C8BB5380100004D8BBE800000004D8B6E504D8B66704D0FB6968E0000004D8B4E604D8B4678498B7E58498B7668488B5E10488B5618488B4620488B4E2848899548010000488B563048899550010000488B563848898D58010000488B4E404C89BD600100004C8B7E484C89AD680100004C898D700100004889BD7801000048899D80010000488985880100004889959001000048898D980100004C89BDA001000049BB58E267CCE77F00004D8B3B498D4F0149BB58E267CCE77F000049890B4983F8050F85000000004C8B8550010000418138E82200000F8500000000498B48104885C90F84000000004D8B7808488B5110813A685505000F8500000000488B5108488B4A08488B4210488B5A184983FF000F8C000000004939DF0F8D000000004C89FA4C0FAFF84889CF4C01F94C8D7A014D8978084983FA000F850000000049BBA8D00CCAE77F00004D39DC0F85000000004D8B660849BBB00007CAE77F00004D39DC0F85000000004D8B54241049BB900E0CCAE77F00004D39DA0F85000000004C8B242500EFCE014981FCF0EED4010F8500000000488985380100004C89B5780100004889BD8001000048898D900100004889CF49BBE0CE7FC9E77F00004C895D2041BB5050250141FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C745200000000048833C2500E61503000F8500000000488B8D580100004C8B4110418138489303000F85000000004C8B4108498B78084C8D7701488985980100004C8985A80100004889BDB00100004C89C74C89F649BB10CF7FC9E77F00004C895D2041BBB05F730041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C745200000000048833C2500E61503000F8500000000488BBDA80100004C8B4710488B85B00100004C8BB59801000041F640048174227811415049BB91A17FC9E77F000041FFD3790F4989C349C1EB074983F3F84D0FAB184D8974C0104C8B3425807816034983FE000F8C0000000049BB70E267CCE77F00004D8B33498D460149BB70E267CCE77F00004989034939DF0F8D000000004C89F84C0FAFBD380100004C8BB5800100004D01FE4C8D7801488B85500100004C8978084889BD900100004C89F749BB60CF7FC9E77F00004C895D2041BB5050250141FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C745200000000048833C2500E61503000F8500000000488BBD900100004C8B4708498D4801488985980100004C8985A80100004889CE49BB80CF7FC9E77F00004C895D2041BBB05F730041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C745200000000048833C2500E61503000F8500000000488BBD90010000488B4F104C8B85A8010000488B8598010000F6410481742178105149BB91A17FC9E77F000041FFD3790F4D89C349C1EB074983F3F84C0FAB194A8944C110488B0425807816034883F8000F8C000000004C89B590010000E9A6FEFFFF49BBF8D857CCE77F0000415349BB20CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB10D057CCE77F0000415349BB30CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB88D057CCE77F0000415349BB40CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB98CF57CCE77F0000415349BB50CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB80D857CCE77F0000415349BB60CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB08D857CCE77F0000415349BB70CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB90D757CCE77F0000415349BB80CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA0D657CCE77F0000415349BB90CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBB0D557CCE77F0000415349BBA0CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB38D557CCE77F0000415349BBB0CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB48D457CCE77F0000415349BBC0CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB58D357CCE77F0000415349BBD0CE7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE0D257CCE77F0000415349BBF0CE7FC9E77F0000415349BB85A07FC9E77F000041FFE349BB00D157CCE77F0000415349BB00CF7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB68D257CCE77F0000415349BB20CF7FC9E77F0000415349BB85A07FC9E77F000041FFE349BBF0D157CCE77F0000415349BB30CF7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB50CC57CCE77F0000415349BB40CF7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB08C957CCE77F0000415349BB50CF7FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD07356CCE77F0000415349BB70CF7FC9E77F0000415349BB85A07FC9E77F000041FFE349BBE8D957CCE77F0000415349BB90CF7FC9E77F0000415349BB85A07FC9E77F000041FFE349BB60DA57CCE77F0000415349BBA0CF7FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4769f7c0c] jit-backend-dump} +[19c4769f86fe] {jit-backend-addr +Loop 4 ( #13 FOR_ITER) has address 0x7fe7c97fd000 to 0x7fe7c97fd449 (bootstrap 0x7fe7c97fcfb0) +[19c4769f9afa] jit-backend-addr} +[19c4769fa4b7] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1810e4 +0 9F030000 -[1ce3aad520a4] jit-backend-dump} -[1ce3aad526f7] {jit-backend-dump +CODE_DUMP @7fe7c97fd0e4 +0 61030000 +[19c4769fb2d8] jit-backend-dump} +[19c4769fb916] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1810f8 +0 B0030000 -[1ce3aad53178] jit-backend-dump} -[1ce3aad53597] {jit-backend-dump +CODE_DUMP @7fe7c97fd0f8 +0 72030000 +[19c4769fc368] jit-backend-dump} +[19c4769fc7d1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181105 +0 C8030000 -[1ce3aad53f07] jit-backend-dump} -[1ce3aad54317] {jit-backend-dump +CODE_DUMP @7fe7c97fd105 +0 8A030000 +[19c4769fd141] jit-backend-dump} +[19c4769fd58f] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18111b +0 D7030000 -[1ce3aad54c16] jit-backend-dump} -[1ce3aad5503e] {jit-backend-dump +CODE_DUMP @7fe7c97fd119 +0 9B030000 +[19c4769fdf05] jit-backend-dump} +[19c4769fe36b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181135 +0 E2030000 -[1ce3aad55901] jit-backend-dump} -[1ce3aad55d1d] {jit-backend-dump +CODE_DUMP @7fe7c97fd133 +0 A6030000 +[19c4769fec55] jit-backend-dump} +[19c4769ff071] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18113e +0 FE030000 -[1ce3aad565ba] jit-backend-dump} -[1ce3aad569ca] {jit-backend-dump +CODE_DUMP @7fe7c97fd13c +0 C2030000 +[19c4769ff94f] jit-backend-dump} +[19c4769ffd80] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18115d +0 04040000 -[1ce3aad57293] jit-backend-dump} -[1ce3aad576a6] {jit-backend-dump +CODE_DUMP @7fe7c97fd15b +0 C8030000 +[19c476a006ea] jit-backend-dump} +[19c476a00b26] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181170 +0 16040000 -[1ce3aad57f84] jit-backend-dump} -[1ce3aad5838b] {jit-backend-dump +CODE_DUMP @7fe7c97fd16e +0 DA030000 +[19c476a01413] jit-backend-dump} +[19c476a0183b] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181187 +0 24040000 -[1ce3aad58c2e] jit-backend-dump} -[1ce3aad59059] {jit-backend-dump +CODE_DUMP @7fe7c97fd185 +0 E8030000 +[19c476a0210a] jit-backend-dump} +[19c476a02535] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18119f +0 31040000 -[1ce3aad59955] jit-backend-dump} -[1ce3aad59f8a] {jit-backend-dump +CODE_DUMP @7fe7c97fd19d +0 F5030000 +[19c476a02dba] jit-backend-dump} +[19c476a0345e] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1811b4 +0 66040000 -[1ce3aad5a898] jit-backend-dump} -[1ce3aad5acd2] {jit-backend-dump +CODE_DUMP @7fe7c97fd1b2 +0 2A040000 +[19c476a03d83] jit-backend-dump} +[19c476a041c6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18121b +0 24040000 -[1ce3aad5b5b3] jit-backend-dump} -[1ce3aad5b9e9] {jit-backend-dump +CODE_DUMP @7fe7c97fd212 +0 EF030000 +[19c476a04af7] jit-backend-dump} +[19c476a04fe6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181233 +0 31040000 -[1ce3aad5c2a1] jit-backend-dump} -[1ce3aad5c6b4] {jit-backend-dump +CODE_DUMP @7fe7c97fd22a +0 FC030000 +[19c476a058d0] jit-backend-dump} +[19c476a05cf8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18129b +0 EE030000 -[1ce3aad5d083] jit-backend-dump} -[1ce3aad603b3] {jit-backend-dump +CODE_DUMP @7fe7c97fd292 +0 B9030000 +[19c476a06592] jit-backend-dump} +[19c476a069d4] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1812f4 +0 BA030000 -[1ce3aad60f25] jit-backend-dump} -[1ce3aad61355] {jit-backend-dump +CODE_DUMP @7fe7c97fd2eb +0 85030000 +[19c476a096d4] jit-backend-dump} +[19c476a09f21] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18131f +0 B4030000 -[1ce3aad61c3c] jit-backend-dump} -[1ce3aad620e4] {jit-backend-dump +CODE_DUMP @7fe7c97fd312 +0 83030000 +[19c476a0a999] jit-backend-dump} +[19c476a0aeb2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1813a7 +0 76030000 -[1ce3aad629e3] jit-backend-dump} -[1ce3aad62de7] {jit-backend-dump +CODE_DUMP @7fe7c97fd381 +0 5E030000 +[19c476a0b824] jit-backend-dump} +[19c476a0bc29] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181408 +0 3A030000 -[1ce3aad636a1] jit-backend-dump} -[1ce3aad63ac6] {jit-backend-dump +CODE_DUMP @7fe7c97fd3e2 +0 22030000 +[19c476a0c4e6] jit-backend-dump} +[19c476a0c908] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18145f +0 08030000 -[1ce3aad643f5] jit-backend-dump} -[1ce3aad6551f] jit-backend} -[1ce3aad66ac2] {jit-log-opt-loop +CODE_DUMP @7fe7c97fd439 +0 F0020000 +[19c476a0d199] jit-backend-dump} +[19c476a0dc73] jit-backend} +[19c476a0eef1] {jit-log-opt-loop # Loop 4 ( #13 FOR_ITER) : loop with 101 ops [p0, p1] +110: p2 = getfield_gc(p0, descr=) @@ -1173,617 +1173,617 @@ +194: p23 = getarrayitem_gc(p9, 6, descr=) +205: p25 = getarrayitem_gc(p9, 7, descr=) +216: p26 = getfield_gc(p0, descr=) -+216: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, descr=TargetToken(139941324359072)) ++216: label(p0, p1, p2, p3, p4, i5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, descr=TargetToken(140633495992456)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+302: guard_value(i7, 5, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19, p21, p23, p25] -+312: guard_class(p19, 26177128, descr=) [p1, p0, p19, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++302: guard_value(i7, 5, descr=) [i7, p1, p0, p2, p3, p4, i5, p6, i8, p11, p13, p15, p17, p19, p21, p23, p25] ++312: guard_class(p19, 26177128, descr=) [p1, p0, p19, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +332: p29 = getfield_gc(p19, descr=) -+336: guard_nonnull(p29, descr=) [p1, p0, p19, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++336: guard_nonnull(p29, descr=) [p1, p0, p19, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] +345: i30 = getfield_gc(p19, descr=) +349: p31 = getfield_gc(p29, descr=) -+353: guard_class(p31, 26517736, descr=) [p1, p0, p19, i30, p31, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] -+367: p33 = getfield_gc(p29, descr=) -+371: i34 = getfield_gc_pure(p33, descr=) -+375: i35 = getfield_gc_pure(p33, descr=) -+379: i36 = getfield_gc_pure(p33, descr=) -+383: i38 = int_lt(i30, 0) -guard_false(i38, descr=) [p1, p0, p19, i30, i36, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] -+393: i39 = int_ge(i30, i36) -guard_false(i39, descr=) [p1, p0, p19, i30, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] -+402: i40 = int_mul(i30, i35) -+409: i41 = int_add(i34, i40) -+415: i43 = int_add(i30, 1) -+419: setfield_gc(p19, i43, descr=) -+423: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p17, p19, p23, p25, i41] ++353: guard_class(p31, 26517736, descr=) [p1, p0, p19, i30, p31, p29, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++365: p33 = getfield_gc(p29, descr=) ++369: i34 = getfield_gc_pure(p33, descr=) ++373: i35 = getfield_gc_pure(p33, descr=) ++377: i36 = getfield_gc_pure(p33, descr=) ++381: i38 = int_lt(i30, 0) +guard_false(i38, descr=) [p1, p0, p19, i30, i36, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++391: i39 = int_ge(i30, i36) +guard_false(i39, descr=) [p1, p0, p19, i30, i35, i34, p2, p3, p4, i5, p6, p11, p13, p15, p17, p21, p23, p25] ++400: i40 = int_mul(i30, i35) ++407: i41 = int_add(i34, i40) ++413: i43 = int_add(i30, 1) ++417: setfield_gc(p19, i43, descr=) ++421: guard_value(i5, 0, descr=) [i5, p1, p0, p2, p3, p4, p6, p11, p13, p15, p17, p19, p23, p25, i41] debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_GLOBAL') -+433: guard_value(p4, ConstPtr(ptr45), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] -+452: p46 = getfield_gc(p0, descr=) -+456: guard_value(p46, ConstPtr(ptr47), descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] -+475: p48 = getfield_gc(p46, descr=) -+480: guard_value(p48, ConstPtr(ptr49), descr=) [p1, p0, p48, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] -+499: guard_not_invalidated(descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] -+499: p51 = getfield_gc(ConstPtr(ptr50), descr=) -+507: guard_value(p51, ConstPtr(ptr52), descr=) [p1, p0, p51, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++431: guard_value(p4, ConstPtr(ptr45), descr=) [p1, p0, p4, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++450: p46 = getfield_gc(p0, descr=) ++454: guard_value(p46, ConstPtr(ptr47), descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++473: p48 = getfield_gc(p46, descr=) ++478: guard_value(p48, ConstPtr(ptr49), descr=) [p1, p0, p48, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++497: guard_not_invalidated(descr=) [p1, p0, p46, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] ++497: p51 = getfield_gc(ConstPtr(ptr50), descr=) ++505: guard_value(p51, ConstPtr(ptr52), descr=) [p1, p0, p51, p2, p3, p6, p13, p15, p17, p19, p23, p25, i41] debug_merge_point(0, 0, ' #22 LOAD_FAST') debug_merge_point(0, 0, ' #25 CALL_FUNCTION') -+520: p54 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i41, descr=) -+608: guard_no_exception(descr=) [p1, p0, p54, p2, p3, p6, p13, p15, p17, p19, p25, i41] ++518: p54 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i41, descr=) ++599: guard_no_exception(descr=) [p1, p0, p54, p2, p3, p6, p13, p15, p17, p19, p25, i41] debug_merge_point(0, 0, ' #28 LIST_APPEND') -+623: p55 = getfield_gc(p17, descr=) -+634: guard_class(p55, 26402504, descr=) [p1, p0, p55, p17, p2, p3, p6, p13, p15, p19, p25, p54, i41] -+647: p57 = getfield_gc(p17, descr=) -+651: i58 = getfield_gc(p57, descr=) -+655: i60 = int_add(i58, 1) -+659: p61 = getfield_gc(p57, descr=) -+659: i62 = arraylen_gc(p61, descr=) -+659: call(ConstClass(_ll_list_resize_ge_trampoline__v1053___simple_call__function_), p57, i60, descr=) -+736: guard_no_exception(descr=) [p1, p0, i58, p54, p57, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] -+751: p65 = getfield_gc(p57, descr=) ++614: p55 = getfield_gc(p17, descr=) ++625: guard_class(p55, 26402504, descr=) [p1, p0, p55, p17, p2, p3, p6, p13, p15, p19, p25, p54, i41] ++638: p57 = getfield_gc(p17, descr=) ++642: i58 = getfield_gc(p57, descr=) ++646: i60 = int_add(i58, 1) ++650: p61 = getfield_gc(p57, descr=) ++650: i62 = arraylen_gc(p61, descr=) ++650: call(ConstClass(_ll_list_resize_ge_trampoline__v1053___simple_call__function_), p57, i60, descr=) ++727: guard_no_exception(descr=) [p1, p0, i58, p54, p57, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] ++742: p65 = getfield_gc(p57, descr=) setarrayitem_gc(p65, i58, p54, descr=) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+822: i67 = getfield_raw(51804288, descr=) -+830: i69 = int_lt(i67, 0) -guard_false(i69, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] ++813: i67 = getfield_raw(51804288, descr=) ++821: i69 = int_lt(i67, 0) +guard_false(i69, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, None, i41] debug_merge_point(0, 0, ' #13 FOR_ITER') -+840: p70 = same_as(ConstPtr(ptr49)) -+840: label(p0, p1, p2, p3, p6, i41, p13, p15, p17, p19, p25, i43, i36, i35, i34, p57, descr=TargetToken(139941324358984)) ++831: p70 = same_as(ConstPtr(ptr49)) ++831: label(p0, p1, p2, p3, p6, i41, p13, p15, p17, p19, p25, i43, i36, i35, i34, p57, descr=TargetToken(140633495992368)) debug_merge_point(0, 0, ' #13 FOR_ITER') -+870: i71 = int_ge(i43, i36) -guard_false(i71, descr=) [p1, p0, p19, i43, i35, i34, p2, p3, p6, p13, p15, p17, p25, i41] -+883: i72 = int_mul(i43, i35) -+898: i73 = int_add(i34, i72) -+908: i74 = int_add(i43, 1) ++861: i71 = int_ge(i43, i36) +guard_false(i71, descr=) [p1, p0, p19, i43, i35, i34, p2, p3, p6, p13, p15, p17, p25, i41] ++870: i72 = int_mul(i43, i35) ++881: i73 = int_add(i34, i72) ++891: i74 = int_add(i43, 1) debug_merge_point(0, 0, ' #16 STORE_FAST') debug_merge_point(0, 0, ' #19 LOAD_GLOBAL') -+919: setfield_gc(p19, i74, descr=) -+930: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++895: setfield_gc(p19, i74, descr=) ++906: guard_not_invalidated(descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] debug_merge_point(0, 0, ' #22 LOAD_FAST') debug_merge_point(0, 0, ' #25 CALL_FUNCTION') -+930: p75 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i73, descr=) -+1004: guard_no_exception(descr=) [p1, p0, p75, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++906: p75 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i73, descr=) ++966: guard_no_exception(descr=) [p1, p0, p75, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] debug_merge_point(0, 0, ' #28 LIST_APPEND') -+1019: i76 = getfield_gc(p57, descr=) -+1030: i77 = int_add(i76, 1) -+1034: p78 = getfield_gc(p57, descr=) -+1034: i79 = arraylen_gc(p78, descr=) -+1034: call(ConstClass(_ll_list_resize_ge_trampoline__v1053___simple_call__function_), p57, i77, descr=) -+1101: guard_no_exception(descr=) [p1, p0, i76, p75, p57, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] -+1116: p80 = getfield_gc(p57, descr=) ++981: i76 = getfield_gc(p57, descr=) ++992: i77 = int_add(i76, 1) ++996: p78 = getfield_gc(p57, descr=) ++996: i79 = arraylen_gc(p78, descr=) ++996: call(ConstClass(_ll_list_resize_ge_trampoline__v1053___simple_call__function_), p57, i77, descr=) ++1063: guard_no_exception(descr=) [p1, p0, i76, p75, p57, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++1078: p80 = getfield_gc(p57, descr=) setarrayitem_gc(p80, i76, p75, descr=) debug_merge_point(0, 0, ' #31 JUMP_ABSOLUTE') -+1185: i81 = getfield_raw(51804288, descr=) -+1193: i82 = int_lt(i81, 0) -guard_false(i82, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] ++1147: i81 = getfield_raw(51804288, descr=) ++1155: i82 = int_lt(i81, 0) +guard_false(i82, descr=) [p1, p0, p2, p3, p6, p13, p15, p17, p19, p25, i73, None] debug_merge_point(0, 0, ' #13 FOR_ITER') -+1203: jump(p0, p1, p2, p3, p6, i73, p13, p15, p17, p19, p25, i74, i36, i35, i34, p57, descr=TargetToken(139941324358984)) -+1239: --end of the loop-- -[1ce3aade160f] jit-log-opt-loop} -[1ce3ab299257] {jit-backend -[1ce3ab32a8f2] {jit-backend-dump ++1165: jump(p0, p1, p2, p3, p6, i73, p13, p15, p17, p19, p25, i74, i36, i35, i34, p57, descr=TargetToken(140633495992368)) ++1177: --end of the loop-- +[19c476a8c8cf] jit-log-opt-loop} +[19c476f1a146] {jit-backend +[19c476fb0eb9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e1817b0 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6EB179E467F000041FFD349BB883200A1467F00004D8B3B4D8D770149BB883200A1467F00004D89334C8BB5400100004D8B7E404C8BAD380100004F0FB6642F184983FC330F85000000004D8D65014D89661849C74620000000004D896E2848C745580100000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBF0C2F1A0467F0000415349BBA017189E467F0000415349BB00E0179E467F000041FFE3 -[1ce3ab32f473] jit-backend-dump} -[1ce3ab32fb31] {jit-backend-addr -Loop 5 (re StrLiteralSearch at 11/51 [17, 8, 3, 1, 1, 1, 1, 51, 0, 19, 51, 1]) has address 0x7f469e181800 to 0x7f469e18189b (bootstrap 0x7f469e1817b0) -[1ce3ab330ae0] jit-backend-addr} -[1ce3ab331277] {jit-backend-dump +CODE_DUMP @7fe7c97fd778 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC2488000000488B0425B07916034829E0483B0425109F0103760D49BBD6AB7FC9E77F000041FFD349BB88E267CCE77F00004D8B3B4D8D770149BB88E267CCE77F00004D89334C8BB5400100004D8B7E404C8BAD380100004F0FB6642F184983FC330F85000000004D8D65014D89661849C74620000000004D896E2848C745580100000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBF00259CCE77F0000415349BB68D77FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c476fb8acd] jit-backend-dump} +[19c476fb9501] {jit-backend-addr +Loop 5 (re StrLiteralSearch at 11/51 [17, 8, 3, 1, 1, 1, 1, 51, 0, 19, 51, 1]) has address 0x7fe7c97fd7c8 to 0x7fe7c97fd863 (bootstrap 0x7fe7c97fd778) +[19c476fbab8f] jit-backend-addr} +[19c476fbb7bf] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18183c +0 5B000000 -[1ce3ab331f7d] jit-backend-dump} -[1ce3ab3328a3] jit-backend} -[1ce3ab333848] {jit-log-opt-loop +CODE_DUMP @7fe7c97fd804 +0 5B000000 +[19c476fbc83d] jit-backend-dump} +[19c476fbd4b4] jit-backend} +[19c476fbec53] {jit-log-opt-loop # Loop 5 (re StrLiteralSearch at 11/51 [17, 8, 3, 1, 1, 1, 1, 51, 0, 19, 51, 1]) : entry bridge with 10 ops [i0, p1] debug_merge_point(0, 0, 're StrLiteralSearch at 11/51 [17. 8. 3. 1. 1. 1. 1. 51. 0. 19. 51. 1]') +110: p2 = getfield_gc_pure(p1, descr=) +121: i3 = strgetitem(p2, i0) +134: i5 = int_eq(i3, 51) -guard_true(i5, descr=) [i0, p1] +guard_true(i5, descr=) [i0, p1] +144: i7 = int_add(i0, 1) +148: setfield_gc(p1, i7, descr=) +152: setfield_gc(p1, ConstPtr(ptr8), descr=) +160: setfield_gc(p1, i0, descr=) +164: finish(1, descr=) +235: --end of the loop-- -[1ce3ab341165] jit-log-opt-loop} -[1ce3ab52c24e] {jit-backend -[1ce3ab568dd2] {jit-backend-dump +[19c476fd6fb4] jit-log-opt-loop} +[19c477229d40] {jit-backend +[19c47726a154] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181900 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBC018189E467F00004C891C2449BB75E2179E467F000041FFD349BBA03200A1467F00004D8B3B4D8D670149BBA03200A1467F00004D89234D8D65014D8B6E084D39EC0F8D000000004D8B7E404F0FB65427184983FA330F84000000004D8D5424014D39EA0F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB80C9F1A0467F0000415349BBD018189E467F0000415349BB00E0179E467F000041FFE349BBD8CBF1A0467F0000415349BBE018189E467F0000415349BB00E0179E467F000041FFE349BB60CBF1A0467F0000415349BBF018189E467F0000415349BB00E0179E467F000041FFE3 -[1ce3ab576f80] jit-backend-dump} -[1ce3ab577b98] {jit-backend-dump +CODE_DUMP @7fe7c97fd8c8 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88D87FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBA0E267CCE77F00004D8B3B4D8D670149BBA0E267CCE77F00004D89234D8D65014D8B6E084D39EC0F8D000000004D8B7E404F0FB65427184983FA330F84000000004D8D5424014D39EA0F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB800959CCE77F0000415349BB98D87FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD80B59CCE77F0000415349BBA8D87FC9E77F0000415349BB00A07FC9E77F000041FFE349BB600B59CCE77F0000415349BBB8D87FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c47727826a] jit-backend-dump} +[19c477278fc6] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181904 +0 1C000000 -[1ce3ab5788e2] jit-backend-dump} -[1ce3ab578d57] {jit-backend-dump +CODE_DUMP @7fe7c97fd8cc +0 1C000000 +[19c477279d40] jit-backend-dump} +[19c47727a217] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18190f +0 1C000000 -[1ce3ab579662] jit-backend-dump} -[1ce3ab579b66] {jit-backend-addr -bridge out of Guard 0x7f46a0f1c2f0 has address 0x7f469e181900 to 0x7f469e1819c6 -[1ce3ab57ab4c] jit-backend-addr} -[1ce3ab57b132] {jit-backend-dump +CODE_DUMP @7fe7c97fd8d7 +0 1C000000 +[19c47727ab6f] jit-backend-dump} +[19c47727b0b4] {jit-backend-addr +bridge out of Guard 0x7fe7cc5902f0 has address 0x7fe7c97fd8c8 to 0x7fe7c97fd98e +[19c47727be22] jit-backend-addr} +[19c47727c513] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181959 +0 69000000 -[1ce3ab57baa8] jit-backend-dump} -[1ce3ab57bf96] {jit-backend-dump +CODE_DUMP @7fe7c97fd921 +0 69000000 +[19c47727ce56] jit-backend-dump} +[19c47727d5d9] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18196d +0 7A000000 -[1ce3ab57c86f] jit-backend-dump} -[1ce3ab57cd72] {jit-backend-dump +CODE_DUMP @7fe7c97fd935 +0 7A000000 +[19c47727deef] jit-backend-dump} +[19c47727e32c] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18197b +0 91000000 -[1ce3ab57d633] jit-backend-dump} -[1ce3ab57df9d] {jit-backend-dump +CODE_DUMP @7fe7c97fd943 +0 91000000 +[19c47727ec22] jit-backend-dump} +[19c47727f5b2] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18183c +0 C0000000 -[1ce3ab57e966] jit-backend-dump} -[1ce3ab57f2de] jit-backend} -[1ce3ab57fe83] {jit-log-opt-bridge -# bridge out of Guard 0x7f46a0f1c2f0 with 13 ops +CODE_DUMP @7fe7c97fd804 +0 C0000000 +[19c47727fecc] jit-backend-dump} +[19c477280917] jit-backend} +[19c4772814a7] {jit-log-opt-bridge +# bridge out of Guard 0x7fe7cc5902f0 with 13 ops [i0, p1] +76: i3 = int_add(i0, 1) +80: i4 = getfield_gc_pure(p1, descr=) +84: i5 = int_lt(i3, i4) -guard_true(i5, descr=) [i3, p1] +guard_true(i5, descr=) [i3, p1] debug_merge_point(0, 0, 're StrLiteralSearch at 11/51 [17. 8. 3. 1. 1. 1. 1. 51. 0. 19. 51. 1]') +93: p6 = getfield_gc_pure(p1, descr=) +97: i7 = strgetitem(p6, i3) +103: i9 = int_eq(i7, 51) -guard_false(i9, descr=) [i3, p1] +guard_false(i9, descr=) [i3, p1] +113: i11 = int_add(i3, 1) +118: i12 = int_lt(i11, i4) -guard_false(i12, descr=) [i11, p1] +guard_false(i12, descr=) [i11, p1] +127: finish(0, descr=) +198: --end of the loop-- -[1ce3ab58ce5c] jit-log-opt-bridge} -[1ce3ab8db05d] {jit-backend -[1ce3ab910a09] {jit-backend-dump +[19c47728e83a] jit-log-opt-bridge} +[19c4775d7810] {jit-backend +[19c47760e455] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181a68 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB381A189E467F00004C891C2449BB75E2179E467F000041FFD349BBB83200A1467F00004D8B3B4D8D6F0149BBB83200A1467F00004D892B4D8B6E404F0FB67C15184983FF330F84000000004D8D7A014D8B56084D39D70F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBC8CCF1A0467F0000415349BB481A189E467F0000415349BB00E0179E467F000041FFE349BB30CEF1A0467F0000415349BB581A189E467F0000415349BB00E0179E467F000041FFE3 -[1ce3ab9149b1] jit-backend-dump} -[1ce3ab9151fd] {jit-backend-dump +CODE_DUMP @7fe7c97fda30 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB00DA7FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBB8E267CCE77F00004D8B3B4D8D6F0149BBB8E267CCE77F00004D892B4D8B6E404F0FB67C15184983FF330F84000000004D8D7A014D8B56084D39D70F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBC80C59CCE77F0000415349BB10DA7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB300E59CCE77F0000415349BB20DA7FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4776123ca] jit-backend-dump} +[19c477612cb4] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181a6c +0 1C000000 -[1ce3ab915c34] jit-backend-dump} -[1ce3ab916091] {jit-backend-dump +CODE_DUMP @7fe7c97fda34 +0 1C000000 +[19c47761382f] jit-backend-dump} +[19c477613ce8] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181a77 +0 1C000000 -[1ce3ab9169ba] jit-backend-dump} -[1ce3ab916eb2] {jit-backend-addr -bridge out of Guard 0x7f46a0f1cb60 has address 0x7f469e181a68 to 0x7f469e181b20 -[1ce3ab9179d9] jit-backend-addr} -[1ce3ab918208] {jit-backend-dump +CODE_DUMP @7fe7c97fda3f +0 1C000000 +[19c477614643] jit-backend-dump} +[19c477614b8b] {jit-backend-addr +bridge out of Guard 0x7fe7cc590b60 has address 0x7fe7c97fda30 to 0x7fe7c97fdae8 +[19c477615712] jit-backend-addr} +[19c477615cd1] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181ac4 +0 58000000 -[1ce3ab918b10] jit-backend-dump} -[1ce3ab918f70] {jit-backend-dump +CODE_DUMP @7fe7c97fda8c +0 58000000 +[19c4776165af] jit-backend-dump} +[19c477616a53] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181ad5 +0 6C000000 -[1ce3ab919842] jit-backend-dump} -[1ce3ab919e10] {jit-backend-dump +CODE_DUMP @7fe7c97fda9d +0 6C000000 +[19c477617334] jit-backend-dump} +[19c477617970] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e18197b +0 E9000000 -[1ce3ab91a744] jit-backend-dump} -[1ce3ab91af29] jit-backend} -[1ce3ab91b95d] {jit-log-opt-bridge -# bridge out of Guard 0x7f46a0f1cb60 with 10 ops +CODE_DUMP @7fe7c97fd943 +0 E9000000 +[19c4776182ec] jit-backend-dump} +[19c477618b2c] jit-backend} +[19c47761952e] {jit-log-opt-bridge +# bridge out of Guard 0x7fe7cc590b60 with 10 ops [i0, p1] debug_merge_point(0, 0, 're StrLiteralSearch at 11/51 [17. 8. 3. 1. 1. 1. 1. 51. 0. 19. 51. 1]') +76: p2 = getfield_gc_pure(p1, descr=) +80: i3 = strgetitem(p2, i0) +86: i5 = int_eq(i3, 51) -guard_false(i5, descr=) [i0, p1] +guard_false(i5, descr=) [i0, p1] +96: i7 = int_add(i0, 1) +100: i8 = getfield_gc_pure(p1, descr=) +104: i9 = int_lt(i7, i8) -guard_false(i9, descr=) [i7, p1] +guard_false(i9, descr=) [i7, p1] +113: finish(0, descr=) +184: --end of the loop-- -[1ce3ab92be89] jit-log-opt-bridge} -[1ce3abcdacf4] {jit-backend -[1ce3abce675d] {jit-backend-dump +[19c47762a4d8] jit-log-opt-bridge} +[19c4779ba3b5] {jit-backend +[19c4779c4e23] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181b80 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB701B189E467F00004C891C2449BB75E2179E467F000041FFD349BBD03200A1467F00004D8B334D8D660149BBD03200A1467F00004D892348C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[1ce3abce942b] jit-backend-dump} -[1ce3abce9b2b] {jit-backend-dump +CODE_DUMP @7fe7c97fdb48 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB38DB7FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBD0E267CCE77F00004D8B334D8D660149BBD0E267CCE77F00004D892348C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c4779c7a68] jit-backend-dump} +[19c4779c8077] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181b84 +0 1C000000 -[1ce3abcea520] jit-backend-dump} -[1ce3abcea954] {jit-backend-dump +CODE_DUMP @7fe7c97fdb4c +0 1C000000 +[19c4779c8a6c] jit-backend-dump} +[19c4779c8ecc] {jit-backend-dump BACKEND x86_64 SYS_EXECUTABLE python -CODE_DUMP @7f469e181b8f +0 1C000000 -[1ce3abceb206] jit-backend-dump} -[1ce3abceb64e] {jit-backend-addr -bridge out of Guard 0x7f46a0f1c980 has address 0x7f469e181b80 to 0x7f469e181c13 From noreply at buildbot.pypy.org Wed Mar 20 21:33:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Mar 2013 21:33:10 +0100 (CET) Subject: [pypy-commit] pypy default: Inline this artificial method again, now that the flow objspace no Message-ID: <20130320203310.66DE11C019F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62569:d49d2c9928f0 Date: 2013-03-20 13:32 -0700 http://bitbucket.org/pypy/pypy/changeset/d49d2c9928f0/ Log: Inline this artificial method again, now that the flow objspace no longer subclasses this class anyway. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -755,18 +755,6 @@ return obj interp_w._annspecialcase_ = 'specialize:arg(1)' - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): - """ - This method should NOT be called unless you are really sure about - it. It is used inside the implementation of end_finally() in - pyopcode.py, and it's there so that it can be overridden by the - FlowObjSpace. - """ - if self.is_w(w_obj, self.w_None): - return True - obj = self.interpclass_w(w_obj) - return isinstance(obj, RequiredClass) - def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable into a real (interpreter-level) list. diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -604,11 +604,12 @@ # item (unlike CPython which can have 1, 2 or 3 items): # [wrapped subclass of SuspendedUnroller] w_top = self.popvalue() - # the following logic is a mess for the flow objspace, - # so we hide it specially in the space :-/ - if self.space._check_constant_interp_w_or_w_None(SuspendedUnroller, w_top): - # case of a finally: block - unroller = self.space.interpclass_w(w_top) + if self.space.is_w(w_top, self.space.w_None): + # case of a finally: block with no exception + return None + unroller = self.space.interpclass_w(w_top) + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block with a suspended unroller return unroller else: # case of an except: block. We popped the exception type From noreply at buildbot.pypy.org Wed Mar 20 21:36:19 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:36:19 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, armin, fijal): removed unused fset Message-ID: <20130320203619.18CE01C03A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62570:ce33600acfcf Date: 2013-03-20 13:36 -0700 http://bitbucket.org/pypy/pypy/changeset/ce33600acfcf/ Log: (alex, armin, fijal): removed unused fset diff --git a/rpython/tool/algo/fset.py b/rpython/tool/algo/fset.py deleted file mode 100644 --- a/rpython/tool/algo/fset.py +++ /dev/null @@ -1,244 +0,0 @@ -__all__ = ['FSet', 'emptyset'] - -# Reference: -# "Implementing sets efficiently in a functional language" -# http://swiss.csail.mit.edu/~adams/BB/ -# See BB.sml in the current directory. - - -class FSet(object): - """Functional Set. - Behaves like a frozenset from Python 2.4 (incomplete, though). - This version is meant to have a better complexity than frozenset for - operations involving a lot of single-element adds and unions. - For example, a long chain of 'set.union([x]).union([y]).union([z])...' - takes quadratic time with frozensets, but only n*log(n) with FSets. - """ - __slots__ = ['_left', '_value', '_right', '_count'] - - def __new__(cls, items=()): - if isinstance(items, FSet): - return items - items = list(items) - if len(items) == 1: - return node(emptyset, items[0], emptyset) - if not items: - return emptyset - items.sort() - any = items[0] - items = [x for i, x in enumerate(items) if x != items[i-1]] - if not items: - items.append(any) - def maketree(start, stop): - if start == stop: - return emptyset - else: - mid = (start+stop)//2 - return node(maketree(start, mid), items[mid], - maketree(mid+1, stop)) - return maketree(0, len(items)) - - def __len__(self): - return self._count - - def __repr__(self): - return '{%s}' % (', '.join([repr(n) for n in self]),) - - def __iter__(self): - return treeiter(self) - - def union(self, other): - return uniontree(self, FSet(other)) - - def __or__(self, other): - if not isinstance(other, FSet): - return NotImplemented - return uniontree(self, other) - - def __eq__(self, other): - if not isinstance(other, FSet): - return NotImplemented - if self is other: - return True - if eqtree(self, other): - other._left = self._left - other._value = self._value - other._right = self._right - return True - return False - - def __ne__(self, other): - res = self.__eq__(other) - if res is NotImplemented: - return NotImplemented - return not res - - def __hash__(self): - return hash(tuple(self)) ^ 1043498183 - - def __contains__(self, value): - return contains(self, value) - -emptyset = object.__new__(FSet) -emptyset._count = 0 - -# ____________________________________________________________ -# creation and balancing stuff - -WEIGHT = 3 - -def node(left, value, right): - result = object.__new__(FSet) - result._left = left - result._value = value - result._right = right - result._count = left._count + right._count + 1 - return result - -def node_balance_fast(left, value, right): - # used when an original tree was balanced, and changed by at most - # one element (as in adding or deleting one item). - ln = left._count - rn = right._count - if ln <= 1 and rn <= 1: - return node(left, value, right) - elif rn > WEIGHT * ln: # right too big - if right._left._count < right._right._count: - return single_L(left, value, right) - else: - return double_L(left, value, right) - elif ln > WEIGHT * rn: # left too big - if left._right._count < left._left._count: - return single_R(left, value, right) - else: - return double_R(left, value, right) - else: - return node(left, value, right) - -def node_balance(left, value, right): - if left is emptyset: - return add(right, value) - elif right is emptyset: - return add(left, value) - elif WEIGHT * left._count < right._count: - t = node_balance(left, value, right._left) - return node_balance_fast(t, right._value, right._right) - elif WEIGHT * right._count < left._count: - t = node_balance(left._right, value, right) - return node_balance_fast(left._left, left._value, t) - else: - return node(left, value, right) - -def add(tree, value): - if tree is emptyset: - return node(emptyset, value, emptyset) - elif value < tree._value: - t = add(tree._left, value) - return node_balance_fast(t, tree._value, tree._right) - elif value == tree._value: - return tree - else: - t = add(tree._right, value) - return node_balance_fast(tree._left, tree._value, t) - -def single_L(left, value, right): - return node(node(left, value, right._left), right._value, right._right) - -def single_R(left, value, right): - return node(left._left, left._value, node(left._right, value, right)) - -def double_L(left, value, right): - rl = right._left - n1 = node(left, value, rl._left) - n2 = node(rl._right, right._value, right._right) - return node(n1, rl._value, n2) - -def double_R(left, value, right): - lr = left._right - n1 = node(left._left, left._value, lr._left) - n2 = node(lr._right, value, right) - return node(n1, lr._value, n2) - -# ____________________________________________________________ -# union - -def uniontree(tree1, tree2): - if tree2._count <= 1: - if tree2 is emptyset: - return tree1 - else: - return add(tree1, tree2._value) - elif tree1._count <= 1: - if tree1 is emptyset: - return tree2 - else: - return add(tree2, tree1._value) - else: - left2, right2 = splittree(tree2, tree1._value) - return node_balance(uniontree(tree1._left, left2), tree1._value, - uniontree(tree1._right, right2)) - -def splittree(tree, value): - if tree is emptyset: - return emptyset, emptyset - elif tree._value < value: - t1, t2 = splittree(tree._right, value) - return node_balance(tree._left, tree._value, t1), t2 - elif tree._value == value: - return tree._left, tree._right - else: - t1, t2 = splittree(tree._left, value) - return t1, node_balance(t2, tree._value, tree._right) - -# ____________________________________________________________ -# utilities - -def treeiter(tree): - if tree is emptyset: - return - path = [] - while True: - while tree._left is not emptyset: - path.append(tree) - tree = tree._left - yield tree._value - tree = tree._right - while tree is emptyset: - if not path: - return - tree = path.pop() - yield tree._value - tree = tree._right - -def eqtree(tree1, tree2): - if tree1 is tree2: - return True - if tree1._count != tree2._count: - return False - assert tree1 is not emptyset and tree2 is not emptyset - left2, right2 = splittree(tree2, tree1._value) - if left2._count + right2._count == tree2._count: - return False # _value was not in tree2 - return eqtree(tree1._left, left2) and eqtree(tree1._right, right2) - -def contains(tree, value): - while tree is not emptyset: - if value < tree._value: - tree = tree._left - elif value == tree._value: - return True - else: - tree = tree._right - return False - - -_no = object() -def checktree(tree, bmin=_no, bmax=_no): - if tree is not emptyset: - if bmin is not _no: - assert bmin < tree._value - if bmax is not _no: - assert tree._value < bmax - assert tree._count == tree._left._count + tree._right._count + 1 - checktree(tree._left, bmin, tree._value) - checktree(tree._right, tree._value, bmax) diff --git a/rpython/tool/algo/test/test_fset.py b/rpython/tool/algo/test/test_fset.py deleted file mode 100644 --- a/rpython/tool/algo/test/test_fset.py +++ /dev/null @@ -1,76 +0,0 @@ -from rpython.tool.algo.fset import FSet, checktree, emptyset -import random - - -def test_empty(): - assert FSet() is FSet([]) is emptyset - assert len(emptyset) == 0 - assert list(emptyset) == [] - checktree(emptyset) - -def test_iter(): - s = FSet(range(42)) - assert len(s) == 42 - assert list(s) == range(42) - checktree(s) - -def test_new(): - s = FSet(range(6, 42) + range(13)) - assert len(s) == 42 - assert list(s) == range(42) - assert FSet(s) is s - checktree(s) - -def test_union(): - s1 = FSet([1, 10, 100, 1000]) - assert list(s1.union([])) == [1, 10, 100, 1000] - assert list(s1.union([100])) == [1, 10, 100, 1000] - assert list(s1.union([3, 4, 5])) == [1, 3, 4, 5, 10, 100, 1000] - assert list(s1.union([1000, 1200, 1400])) == [1, 10, 100, 1000, 1200, 1400] - assert list(s1.union(s1)) == [1, 10, 100, 1000] - -def test_or(): - s1 = FSet([0, 3, 6]) - s2 = FSet([1, 3]) - assert list(s1 | s2) == [0, 1, 3, 6] - -def test_eq(): - assert FSet([0, 3]) == FSet([0, 3]) - assert FSet([]) == emptyset - assert FSet(range(42)) == FSet(range(42)) - assert FSet([]) != FSet([5]) - assert FSet(range(42)) != FSet(range(43)) - -def test_hash(): - assert hash(emptyset) != hash(FSet([1])) != hash(FSet([1, 2])) - assert hash(FSet([1, 2])) == hash(FSet([1]) | FSet([2])) - -def test_len(): - assert len(FSet([1, 2]) | FSet([2, 3])) == 3 - -def test_reasonable_speed(N=1000): - d = emptyset - for i in range(N): - d |= FSet([i]) - checktree(d) - assert list(d) == range(N) - d = emptyset - for i in range(N-1, -1, -1): - d |= FSet([i]) - checktree(d) - assert list(d) == range(N) - d = emptyset - lst = range(N) - random.shuffle(lst) - for i in lst: - d |= FSet([i]) - checktree(d) - assert list(d) == range(N) - -def test_contains(): - assert 5 not in emptyset - lst = range(0, 20, 2) - random.shuffle(lst) - d = FSet(lst) - for x in range(20): - assert (x in d) == (x in lst) From noreply at buildbot.pypy.org Wed Mar 20 21:37:07 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:37:07 +0100 (CET) Subject: [pypy-commit] pypy default: Removed weird SML file. Message-ID: <20130320203707.DB27C1C03A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62571:96061fd83094 Date: 2013-03-20 13:36 -0700 http://bitbucket.org/pypy/pypy/changeset/96061fd83094/ Log: Removed weird SML file. diff --git a/rpython/tool/algo/BB.sml b/rpython/tool/algo/BB.sml deleted file mode 100644 --- a/rpython/tool/algo/BB.sml +++ /dev/null @@ -1,287 +0,0 @@ -(* - Copyright 1992-1996 Stephen Adams. - - This software may be used freely provided that: - 1. This copyright notice is attached to any copy, derived work, - or work including all or part of this software. - 2. Any derived work must contain a prominent notice stating that - it has been altered from the original. - -*) - -(* Address: Electronics & Computer Science - University of Southampton - Southampton SO9 5NH - Great Britian - E-mail: sra at ecs.soton.ac.uk - - Comments: - - 1. The implementation is based on Binary search trees of Bounded - Balance, similar to Nievergelt & Reingold, SIAM J. Computing - 2(1), March 1973. The main advantage of these trees is that - they keep the size of the tree in the node, giving a constant - time size operation. - - 2. The bounded balance criterion is simpler than N&R's alpha. - Simply, one subtree must not have more than `weight' times as - many elements as the opposite subtree. Rebalancing is - guaranteed to reinstate the criterion for weight>2.23, but - the occasional incorrect behaviour for weight=2 is not - detrimental to performance. - - 3. There are two implementations of union. The default, - hedge_union, is much more complex and usually 20% faster. I - am not sure that the performance increase warrants the - complexity (and time it took to write), but I am leaving it - in for the competition. It is derived from the original - union by replacing the split_lt(gt) operations with a lazy - version. The `obvious' version is called old_union. -*) - -structure B (*: INTSET*) = - struct - - local - - type T = int - val lt : T*T->bool = op < - - (* weight is a parameter to the rebalancing process. *) - val weight:int = 3 - - datatype Set = E | T of T * int * Set * Set - - fun size E = 0 - | size (T(_,n,_,_)) = n - - (*fun N(v,l,r) = T(v,1+size(l)+size(r),l,r)*) - fun N(v,E, E) = T(v,1,E,E) - | N(v,E, r as T(_,n,_,_)) = T(v,n+1,E,r) - | N(v,l as T(_,n,_,_),E) = T(v,n+1,l,E) - | N(v,l as T(_,n,_,_),r as T(_,m,_,_)) = T(v,n+m+1,l,r) - - fun single_L (a,x,T(b,_,y,z)) = N(b,N(a,x,y),z) - | single_L _ = raise Match - fun single_R (b,T(a,_,x,y),z) = N(a,x,N(b,y,z)) - | single_R _ = raise Match - fun double_L (a,w,T(c,_,T(b,_,x,y),z)) = N(b,N(a,w,x),N(c,y,z)) - | double_L _ = raise Match - fun double_R (c,T(a,_,w,T(b,_,x,y)),z) = N(b,N(a,w,x),N(c,y,z)) - | double_R _ = raise Match - - fun T' (v,E,E) = T(v,1,E,E) - | T' (v,E,r as T(_,_,E,E)) = T(v,2,E,r) - | T' (v,l as T(_,_,E,E),E) = T(v,2,l,E) - - | T' (p as (_,E,T(_,_,T(_,_,_,_),E))) = double_L p - | T' (p as (_,T(_,_,E,T(_,_,_,_)),E)) = double_R p - - (* these cases almost never happen with small weight*) - | T' (p as (_,E,T(_,_,T(_,ln,_,_),T(_,rn,_,_)))) = - if lnrn then single_R p else double_R p - - | T' (p as (_,E,T(_,_,E,_))) = single_L p - | T' (p as (_,T(_,_,_,E),E)) = single_R p - - | T' (p as (v,l as T(lv,ln,ll,lr),r as T(rv,rn,rl,rr))) = - if rn>=weight*ln then (*right is too big*) - let val rln = size rl - val rrn = size rr - in - if rln < rrn then single_L p else double_L p - end - - else if ln>=weight*rn then (*left is too big*) - let val lln = size ll - val lrn = size lr - in - if lrn < lln then single_R p else double_R p - end - - else - T(v,ln+rn+1,l,r) - - fun add (E,x) = T(x,1,E,E) - | add (set as T(v,_,l,r),x) = - if lt(x,v) then T'(v,add(l,x),r) - else if lt(v,x) then T'(v,l,add(r,x)) - else set - - fun concat3 (E,v,r) = add(r,v) - | concat3 (l,v,E) = add(l,v) - | concat3 (l as T(v1,n1,l1,r1), v, r as T(v2,n2,l2,r2)) = - if weight*n1 < n2 then T'(v2,concat3(l,v,l2),r2) - else if weight*n2 < n1 then T'(v1,l1,concat3(r1,v,r)) - else N(v,l,r) - - fun split_lt (E,x) = E - | split_lt (t as T(v,_,l,r),x) = - if lt(x,v) then split_lt(l,x) - else if lt(v,x) then concat3(l,v,split_lt(r,x)) - else l - - fun split_gt (E,x) = E - | split_gt (t as T(v,_,l,r),x) = - if lt(v,x) then split_gt(r,x) - else if lt(x,v) then concat3(split_gt(l,x),v,r) - else r - - fun min (T(v,_,E,_)) = v - | min (T(v,_,l,_)) = min l - | min _ = raise Match - - and delete' (E,r) = r - | delete' (l,E) = l - | delete' (l,r) = let val min_elt = min r in - T'(min_elt,l,delmin r) - end - and delmin (T(_,_,E,r)) = r - | delmin (T(v,_,l,r)) = T'(v,delmin l,r) - | delmin _ = raise Match - - fun concat (E, s2) = s2 - | concat (s1, E) = s1 - | concat (t1 as T(v1,n1,l1,r1), t2 as T(v2,n2,l2,r2)) = - if weight*n1 < n2 then T'(v2,concat(t1,l2),r2) - else if weight*n2 < n1 then T'(v1,l1,concat(r1,t2)) - else T'(min t2,t1, delmin t2) - - fun fold(f,base,set) = - let fun fold'(base,E) = base - | fold'(base,T(v,_,l,r)) = fold'(f(v,fold'(base,r)),l) - in - fold'(base,set) - end - - in - - val empty = E - - fun singleton x = T(x,1,E,E) - - - local - fun trim (lo,hi,E) = E - | trim (lo,hi,s as T(v,_,l,r)) = - if lt(lo,v) then - if lt(v,hi) then s - else trim(lo,hi,l) - else trim(lo,hi,r) - - - fun uni_bd (s,E,lo,hi) = s - | uni_bd (E,T(v,_,l,r),lo,hi) = - concat3(split_gt(l,lo),v,split_lt(r,hi)) - | uni_bd (T(v,_,l1,r1), s2 as T(v2,_,l2,r2),lo,hi) = - concat3(uni_bd(l1,trim(lo,v,s2),lo,v), - v, - uni_bd(r1,trim(v,hi,s2),v,hi)) - (* inv: lo < v < hi *) - - (*all the other versions of uni and trim are - specializations of the above two functions with - lo=-infinity and/or hi=+infinity *) - - fun trim_lo (_ ,E) = E - | trim_lo (lo,s as T(v,_,_,r)) = - if lt(lo,v) then s else trim_lo(lo,r) - fun trim_hi (_ ,E) = E - | trim_hi (hi,s as T(v,_,l,_)) = - if lt(v,hi) then s else trim_hi(hi,l) - - fun uni_hi (s,E,hi) = s - | uni_hi (E,T(v,_,l,r),hi) = - concat3(l,v,split_lt(r,hi)) - | uni_hi (T(v,_,l1,r1), s2 as T(v2,_,l2,r2),hi) = - concat3(uni_hi(l1,trim_hi(v,s2),v), - v, - uni_bd(r1,trim(v,hi,s2),v,hi)) - - fun uni_lo (s,E,lo) = s - | uni_lo (E,T(v,_,l,r),lo) = - concat3(split_gt(l,lo),v,r) - | uni_lo (T(v,_,l1,r1), s2 as T(v2,_,l2,r2),lo) = - concat3(uni_bd(l1,trim(lo,v,s2),lo,v), - v, - uni_lo(r1,trim_lo(v,s2),v)) - - fun uni (s,E) = s - | uni (E,s as T(v,_,l,r)) = s - | uni (T(v,_,l1,r1), s2 as T(v2,_,l2,r2)) = - concat3(uni_hi(l1,trim_hi(v,s2),v), - v, - uni_lo(r1,trim_lo(v,s2),v)) - - in - val hedge_union = uni - end - - - fun old_union (E,s2) = s2 - | old_union (s1,E) = s1 - | old_union (s1 as T(v,_,l,r),s2) = - let val l2 = split_lt(s2,v) - val r2 = split_gt(s2,v) - in - concat3(old_union(l,l2),v,old_union(r,r2)) - end - - (* The old_union version is about 20% slower than - hedge_union in most cases *) - - val union = hedge_union - (*val union = old_union*) - - val add = add - - fun difference (E,s) = E - | difference (s,E) = s - | difference (s, T(v,_,l,r)) = - let val l2 = split_lt(s,v) - val r2 = split_gt(s,v) - in - concat(difference(l2,l),difference(r2,r)) - end - - fun member (x,set) = - let fun mem E = false - | mem (T(v,_,l,r)) = - if lt(x,v) then mem l else if lt(v,x) then mem r else true - in mem set end - - (*fun intersection (a,b) = difference(a,difference(a,b))*) - - fun intersection (E,_) = E - | intersection (_,E) = E - | intersection (s, T(v,_,l,r)) = - let val l2 = split_lt(s,v) - val r2 = split_gt(s,v) - in - if member(v,s) then - concat3(intersection(l2,l),v,intersection(r2,r)) - else - concat(intersection(l2,l),intersection(r2,r)) - end - - fun members set = fold(op::,[],set) - - fun cardinality E = 0 - | cardinality (T(_,n,_,_)) = n - - fun delete (E,x) = E - | delete (set as T(v,_,l,r),x) = - if lt(x,v) then T'(v,delete(l,x),r) - else if lt(v,x) then T'(v,l,delete(r,x)) - else delete'(l,r) - - fun fromList l = List.fold (fn(x,y)=>add(y,x)) l E - - type intset = Set - - end - end - -structure IntSet : INTSET =B; From noreply at buildbot.pypy.org Wed Mar 20 21:37:44 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 21:37:44 +0100 (CET) Subject: [pypy-commit] pypy default: Removed unused MultiWeakDict Message-ID: <20130320203744.910A61C03A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62572:44a31f735006 Date: 2013-03-20 13:37 -0700 http://bitbucket.org/pypy/pypy/changeset/44a31f735006/ Log: Removed unused MultiWeakDict diff --git a/rpython/tool/algo/multiweakdict.py b/rpython/tool/algo/multiweakdict.py deleted file mode 100644 --- a/rpython/tool/algo/multiweakdict.py +++ /dev/null @@ -1,45 +0,0 @@ -import weakref -import UserDict - - -class MultiWeakKeyDictionary(UserDict.DictMixin): - - def __init__(self): - self._bylength = {} - - def __getitem__(self, key): - key = (len(key),) + key - d = self._bylength - for step in key: - d = d[step] - return d - - def __setitem__(self, key, value): - key = (len(key),) + key - d = self._bylength - for step in key[:-1]: - try: - d = d[step] - except KeyError: - d[step] = newd = weakref.WeakKeyDictionary() - d = newd - d[key[-1]] = value - - def __delitem__(self, key): - key = (len(key),) + key - d = self._bylength - for step in key[:-1]: - d = d[step] - del d[key[-1]] - - def keys(self): - result = [] - def enumkeys(initialkey, d, result): - if len(initialkey) == length: - result.append(initialkey) - else: - for key, value in d.iteritems(): - enumkeys(initialkey + (key,), value, result) - for length, d in self._bylength.iteritems(): - enumkeys((), d, result) - return result diff --git a/rpython/tool/algo/test/test_multiweakdict.py b/rpython/tool/algo/test/test_multiweakdict.py deleted file mode 100644 --- a/rpython/tool/algo/test/test_multiweakdict.py +++ /dev/null @@ -1,52 +0,0 @@ -import py, gc -from rpython.tool.algo.multiweakdict import MultiWeakKeyDictionary - - -class A(object): - pass - - -def test_simple(): - d = MultiWeakKeyDictionary() - a1 = A() - a2 = A() - a3 = A() - d[a1, a2] = 12 - d[a1,] = 1 - d[a2,] = 2 - d[a2, a1] = 21 - d[a2, a2] = 22 - d[()] = 0 - assert d[a1, a2] == 12 - assert d[a1,] == 1 - assert d[a2,] == 2 - assert d[a2, a1] == 21 - assert d[a2, a2] == 22 - assert d[()] == 0 - assert dict.fromkeys(d.keys()) == {(a1, a2): None, - (a1,): None, - (a2,): None, - (a2, a1): None, - (a2, a2): None, - (): None} - del d[a2,] - assert dict.fromkeys(d.keys()) == {(a1, a2): None, - (a1,): None, - (a2, a1): None, - (a2, a2): None, - (): None} - assert d[a1, a2] == 12 - assert d[a1,] == 1 - assert d[a2, a1] == 21 - assert d[a2, a2] == 22 - assert d[()] == 0 - py.test.raises(KeyError, "d[a2,]") - - del a1 - locals() # obscure fix for CPython -- make sure a1 is no longer in - # the cached f_locals of the frame - gc.collect() # less obscure fix for other Python implementations - assert dict.fromkeys(d.keys()) == {(a2, a2): None, - (): None} - assert d[a2, a2] == 22 - assert d[()] == 0 From noreply at buildbot.pypy.org Wed Mar 20 21:49:15 2013 From: noreply at buildbot.pypy.org (tilarids) Date: Wed, 20 Mar 2013 21:49:15 +0100 (CET) Subject: [pypy-commit] pypy default: Updated getting-started-dev.rst doc and fixed some broken links Message-ID: <20130320204915.11FF61C03A7@cobra.cs.uni-duesseldorf.de> Author: Sergey Kishchenko Branch: Changeset: r62573:47be70673d5d Date: 2013-03-20 01:19 +0200 http://bitbucket.org/pypy/pypy/changeset/47be70673d5d/ Log: Updated getting-started-dev.rst doc and fixed some broken links * Docs for several RPython env vars were added * translatorshell.py sets sys.path correctly now * Broken extradoc link was fixed diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -107,8 +107,7 @@ There is a small-to-medium demo showing the translator and the annotator:: - cd demo - ../rpython/translator/goal/translate.py --view --annotate bpnn.py + python bin/rpython --view --annotate translator/goal/bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,7 +118,7 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../rpython/translator/goal/translate.py bpnn.py + python bin/rpython translator/goal/bpnn.py Translating Full Programs @@ -129,8 +128,7 @@ ``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd rpython/translator/goal - python translate.py targetrpystonedalone + python bin/rpython translator/goal/targetrpystonedalone This will produce the executable "targetrpystonedalone-c". @@ -138,6 +136,17 @@ interpreter`_. There is also an FAQ about how to set up this process for `your own interpreters`_. +There are several environment variables you can find useful while playing with the RPython: + +``PYPY_USESSION_DIR`` + RPython uses temporary session directories to store files that are generated during the + translation process(e.g., translated C files). ``PYPY_USESSION_DIR`` serves as a base directory for these session + dirs. The default value for this variable is the systems temporary dir. + +``PYPY_USESSION_KEEP`` + By default RPython keeps only last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. + Increase this value if you want your C files to preserve (useful when producing lots of lldebug builds) + .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters .. _`start reading sources`: diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -13,7 +13,7 @@ implemented. It's helpful to have an understanding of how the `RPython translation toolchain`_ works before digging into the sources. -Almost all JIT specific code is found in pypy/jit subdirectories. Translation +Almost all JIT specific code is found in rpython/jit subdirectories. Translation time code is in the codewriter directory. The metainterp directory holds platform independent code including the the tracer and the optimizer. Code in the backend directory is responsible for generating machine code. @@ -175,7 +175,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf +.. __: https://bitbucket.org/pypy/extradoc/src/tip/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -25,6 +25,8 @@ """ import os, sys +sys.path.insert(0, os.path.dirname(os.path.dirname( + os.path.dirname(os.path.realpath(__file__))))) from rpython.translator.interactive import Translation from rpython.rtyper.rtyper import * diff --git a/rpython/translator/goal/bpnn.py b/rpython/translator/goal/bpnn.py --- a/rpython/translator/goal/bpnn.py +++ b/rpython/translator/goal/bpnn.py @@ -27,7 +27,6 @@ import math import time -import autopath from rpython.rlib import rrandom PRINT_IT = True From noreply at buildbot.pypy.org Wed Mar 20 21:49:16 2013 From: noreply at buildbot.pypy.org (tilarids) Date: Wed, 20 Mar 2013 21:49:16 +0100 (CET) Subject: [pypy-commit] pypy default: Applied reviewer's comments Message-ID: <20130320204916.3D61F1C03A7@cobra.cs.uni-duesseldorf.de> Author: Sergey Kishchenko Branch: Changeset: r62574:6833c40c351c Date: 2013-03-20 01:39 +0200 http://bitbucket.org/pypy/pypy/changeset/6833c40c351c/ Log: Applied reviewer's comments diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -141,11 +141,11 @@ ``PYPY_USESSION_DIR`` RPython uses temporary session directories to store files that are generated during the translation process(e.g., translated C files). ``PYPY_USESSION_DIR`` serves as a base directory for these session - dirs. The default value for this variable is the systems temporary dir. + dirs. The default value for this variable is the system's temporary dir. ``PYPY_USESSION_KEEP`` By default RPython keeps only last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. - Increase this value if you want your C files to preserve (useful when producing lots of lldebug builds) + Increase this value if you want to preserve C files longer (useful when producing lots of lldebug builds). .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters diff --git a/rpython/tool/udir.py b/rpython/tool/udir.py --- a/rpython/tool/udir.py +++ b/rpython/tool/udir.py @@ -12,7 +12,7 @@ # # $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-$USER # -# The default value for $PYPY_USESSION_DIR is the system tmp. +# The default value for $PYPY_USESSION_DIR is the system's tmp. # The default value for $PYPY_USESSION_BASENAME is the name # of the current Mercurial branch. # From noreply at buildbot.pypy.org Wed Mar 20 21:49:17 2013 From: noreply at buildbot.pypy.org (tilarids) Date: Wed, 20 Mar 2013 21:49:17 +0100 (CET) Subject: [pypy-commit] pypy default: One last touch on getting-started-dev.rst Message-ID: <20130320204917.7374D1C03A7@cobra.cs.uni-duesseldorf.de> Author: Sergey Kishchenko Branch: Changeset: r62575:d3873f354cb1 Date: 2013-03-20 01:46 +0200 http://bitbucket.org/pypy/pypy/changeset/d3873f354cb1/ Log: One last touch on getting-started-dev.rst diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -144,7 +144,7 @@ dirs. The default value for this variable is the system's temporary dir. ``PYPY_USESSION_KEEP`` - By default RPython keeps only last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. + By default RPython keeps only the last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. Increase this value if you want to preserve C files longer (useful when producing lots of lldebug builds). .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters From noreply at buildbot.pypy.org Wed Mar 20 21:49:18 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 20 Mar 2013 21:49:18 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in tilarids/pypy (pull request #140) Message-ID: <20130320204918.A81071C03A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62576:cc4bf5491933 Date: 2013-03-20 13:49 -0700 http://bitbucket.org/pypy/pypy/changeset/cc4bf5491933/ Log: Merged in tilarids/pypy (pull request #140) Updated getting-started- dev.rst doc and fixed some broken links diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -107,8 +107,7 @@ There is a small-to-medium demo showing the translator and the annotator:: - cd demo - ../rpython/translator/goal/translate.py --view --annotate bpnn.py + python bin/rpython --view --annotate translator/goal/bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,7 +118,7 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../rpython/translator/goal/translate.py bpnn.py + python bin/rpython translator/goal/bpnn.py Translating Full Programs @@ -129,8 +128,7 @@ ``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd rpython/translator/goal - python translate.py targetrpystonedalone + python bin/rpython translator/goal/targetrpystonedalone This will produce the executable "targetrpystonedalone-c". @@ -138,6 +136,17 @@ interpreter`_. There is also an FAQ about how to set up this process for `your own interpreters`_. +There are several environment variables you can find useful while playing with the RPython: + +``PYPY_USESSION_DIR`` + RPython uses temporary session directories to store files that are generated during the + translation process(e.g., translated C files). ``PYPY_USESSION_DIR`` serves as a base directory for these session + dirs. The default value for this variable is the system's temporary dir. + +``PYPY_USESSION_KEEP`` + By default RPython keeps only the last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. + Increase this value if you want to preserve C files longer (useful when producing lots of lldebug builds). + .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters .. _`start reading sources`: diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -13,7 +13,7 @@ implemented. It's helpful to have an understanding of how the `RPython translation toolchain`_ works before digging into the sources. -Almost all JIT specific code is found in pypy/jit subdirectories. Translation +Almost all JIT specific code is found in rpython/jit subdirectories. Translation time code is in the codewriter directory. The metainterp directory holds platform independent code including the the tracer and the optimizer. Code in the backend directory is responsible for generating machine code. @@ -175,7 +175,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf +.. __: https://bitbucket.org/pypy/extradoc/src/tip/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -25,6 +25,8 @@ """ import os, sys +sys.path.insert(0, os.path.dirname(os.path.dirname( + os.path.dirname(os.path.realpath(__file__))))) from rpython.translator.interactive import Translation from rpython.rtyper.rtyper import * diff --git a/rpython/tool/udir.py b/rpython/tool/udir.py --- a/rpython/tool/udir.py +++ b/rpython/tool/udir.py @@ -12,7 +12,7 @@ # # $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-$USER # -# The default value for $PYPY_USESSION_DIR is the system tmp. +# The default value for $PYPY_USESSION_DIR is the system's tmp. # The default value for $PYPY_USESSION_BASENAME is the name # of the current Mercurial branch. # diff --git a/rpython/translator/goal/bpnn.py b/rpython/translator/goal/bpnn.py --- a/rpython/translator/goal/bpnn.py +++ b/rpython/translator/goal/bpnn.py @@ -27,7 +27,6 @@ import math import time -import autopath from rpython.rlib import rrandom PRINT_IT = True From noreply at buildbot.pypy.org Wed Mar 20 21:54:59 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 21:54:59 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: add test cases for STL iterators Message-ID: <20130320205459.B52691C03A7@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62577:d2d32efce5d9 Date: 2013-03-20 11:17 -0700 http://bitbucket.org/pypy/pypy/changeset/d2d32efce5d9/ Log: add test cases for STL iterators diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py --- a/pypy/module/cppyy/test/test_stltypes.py +++ b/pypy/module/cppyy/test/test_stltypes.py @@ -430,3 +430,40 @@ a = stl_like_class(int)() assert a["some string" ] == 'string' assert a[3.1415] == 'double' + + +class AppTestSTLMAP: + spaceconfig = dict(usemodules=['cppyy', 'itertools']) + + def setup_class(cls): + cls.w_test_dct = cls.space.wrap(test_dct) + cls.w_stlstring = cls.space.appexec([], """(): + import cppyy, sys + return cppyy.load_reflection_info(%r)""" % (test_dct, )) + + def test01_builtin_vector_iterators(self): + """Test iterator comparison with operator== reflected""" + + import cppyy + from cppyy.gbl import std + + v = std.vector(int)() + v.resize(1) + + b1, e1 = v.begin(), v.end() + b2, e2 = v.begin(), v.end() + + assert b1 == b2 + assert not b1 != b2 + + assert e1 == e2 + assert not e1 != e2 + + assert not b1 == e1 + assert b1 != e1 + + b1.__preinc__() + assert not b1 == b2 + assert b1 == e2 + assert b1 != b2 + assert b1 == e2 From noreply at buildbot.pypy.org Wed Mar 20 21:55:01 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 21:55:01 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: o) finalize stl tests Message-ID: <20130320205501.2C73F1C03A7@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62578:071dc7ce6101 Date: 2013-03-20 13:11 -0700 http://bitbucket.org/pypy/pypy/changeset/071dc7ce6101/ Log: o) finalize stl tests o) allow pointers to unknown classes to execute as void* diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py --- a/pypy/module/cppyy/executor.py +++ b/pypy/module/cppyy/executor.py @@ -259,7 +259,7 @@ pass # 2) drop '&': by-ref is pretty much the same as by-value, python-wise - if compound and compound[len(compound)-1] == "&": + if compound and compound[len(compound)-1] == '&': # TODO: this does not actually work with Reflex (?) try: return _executors[clean_name](space, None) @@ -273,17 +273,18 @@ # type check for the benefit of the annotator from pypy.module.cppyy.interp_cppyy import W_CPPClass cppclass = space.interp_w(W_CPPClass, cppclass, can_be_None=False) - if compound == "": + if compound == '': return InstanceExecutor(space, cppclass) - elif compound == "*" or compound == "&": + elif compound == '*' or compound == '&': return InstancePtrExecutor(space, cppclass) - elif compound == "**" or compound == "*&": + elif compound == '**' or compound == '*&': return InstancePtrPtrExecutor(space, cppclass) elif capi.c_is_enum(clean_name): return _executors['unsigned int'](space, None) # 4) additional special cases - # ... none for now + if compound == '*': + return _executors['void*'](space, None) # allow at least passing of the pointer # currently used until proper lazy instantiation available in interp_cppyy return FunctionExecutor(space, None) diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py --- a/pypy/module/cppyy/pythonify.py +++ b/pypy/module/cppyy/pythonify.py @@ -318,15 +318,17 @@ # global == and != for its iterators are reflected, which is a hassle ... if not 'vector' in pyclass.__name__[:11] and \ ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__): - # TODO: check return type of begin() and end() for existence - def __iter__(self): - iter = self.begin() - while iter != self.end(): - yield iter.__deref__() - iter.__preinc__() - iter.destruct() - raise StopIteration - pyclass.__iter__ = __iter__ + if cppyy._scope_byname(pyclass.__name__+'::iterator') or \ + cppyy._scope_byname(pyclass.__name__+'::const_iterator'): + def __iter__(self): + i = self.begin() + while i != self.end(): + yield i.__deref__() + i.__preinc__() + i.destruct() + raise StopIteration + pyclass.__iter__ = __iter__ + # else: rely on numbered iteration # combine __getitem__ and __len__ to make a pythonized __getitem__ if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: diff --git a/pypy/module/cppyy/test/test_fragile.py b/pypy/module/cppyy/test/test_fragile.py --- a/pypy/module/cppyy/test/test_fragile.py +++ b/pypy/module/cppyy/test/test_fragile.py @@ -49,7 +49,7 @@ assert fragile.B == fragile.B assert fragile.B().check() == ord('B') - raises(TypeError, fragile.B().gime_no_such) + raises(AttributeError, getattr, fragile.B().gime_no_such(), "_cpp_proxy") assert fragile.C == fragile.C assert fragile.C().check() == ord('C') diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py --- a/pypy/module/cppyy/test/test_stltypes.py +++ b/pypy/module/cppyy/test/test_stltypes.py @@ -431,8 +431,20 @@ assert a["some string" ] == 'string' assert a[3.1415] == 'double' + def test06_STL_like_class_iterators(self): + """Test the iterator protocol mapping for an STL like class""" -class AppTestSTLMAP: + import cppyy + stl_like_class = cppyy.gbl.stl_like_class + + a = stl_like_class(int)() + for i in a: + pass + + assert i == 3 + + +class AppTestSTLITERATOR: spaceconfig = dict(usemodules=['cppyy', 'itertools']) def setup_class(cls): From noreply at buildbot.pypy.org Wed Mar 20 21:55:02 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 21:55:02 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: do not remove "const" in template parameters Message-ID: <20130320205502.57B311C03A7@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62579:3b0d430e7067 Date: 2013-03-20 13:54 -0700 http://bitbucket.org/pypy/pypy/changeset/3b0d430e7067/ Log: do not remove "const" in template parameters diff --git a/pypy/module/cppyy/helper.py b/pypy/module/cppyy/helper.py --- a/pypy/module/cppyy/helper.py +++ b/pypy/module/cppyy/helper.py @@ -3,7 +3,12 @@ #- type name manipulations -------------------------------------------------- def _remove_const(name): - return "".join(rstring.split(name, "const")) # poor man's replace + tmplt_start = name.find("<") + if 0 <= tmplt_start: + # only replace const within the class name, not in the template parameters + return "".join(rstring.split(name[:tmplt_start], "const"))+name[tmplt_start:] + else: + return "".join(rstring.split(name, "const")) def remove_const(name): return _remove_const(name).strip(' ') From noreply at buildbot.pypy.org Wed Mar 20 22:25:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 22:25:37 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: talk at invitae Message-ID: <20130320212537.22CEA1C03A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4962:c78170433833 Date: 2013-03-20 14:25 -0700 http://bitbucket.org/pypy/extradoc/changeset/c78170433833/ Log: talk at invitae diff --git a/talk/sftour2013/invitae/Makefile b/talk/sftour2013/invitae/Makefile new file mode 100644 --- /dev/null +++ b/talk/sftour2013/invitae/Makefile @@ -0,0 +1,16 @@ +# you can find rst2beamer.py and inkscapeslide.py here: +# http://bitbucket.org/antocuni/env/src/619f486c4fad/bin/rst2beamer.py +# http://bitbucket.org/antocuni/env/src/619f486c4fad/bin/inkscapeslide.py + + +talk.pdf: talk.rst author.latex stylesheet.latex + rst2beamer --input-encoding=utf8 --output-encoding=utf8 --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit + sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit + #sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit + pdflatex talk.latex || exit + +view: talk.pdf + evince talk.pdf & + +xpdf: talk.pdf + xpdf talk.pdf & diff --git a/talk/sftour2013/invitae/author.latex b/talk/sftour2013/invitae/author.latex new file mode 100644 --- /dev/null +++ b/talk/sftour2013/invitae/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[Writing fast Python programs]{Writing fast Python programs} +\author[arigo, fijal] +{Armin Rigo \\ Maciej Fijałkowski} + +\institute{InVitae 2013} +\date{March 20 2013} diff --git a/talk/sftour2013/invitae/beamerdefs.txt b/talk/sftour2013/invitae/beamerdefs.txt new file mode 100644 --- /dev/null +++ b/talk/sftour2013/invitae/beamerdefs.txt @@ -0,0 +1,108 @@ +.. colors +.. =========================== + +.. role:: green +.. role:: red + + +.. general useful commands +.. =========================== + +.. |pause| raw:: latex + + \pause + +.. |small| raw:: latex + + {\small + +.. |end_small| raw:: latex + + } + +.. |scriptsize| raw:: latex + + {\scriptsize + +.. |end_scriptsize| raw:: latex + + } + +.. |strike<| raw:: latex + + \sout{ + +.. closed bracket +.. =========================== + +.. |>| raw:: latex + + } + + +.. example block +.. =========================== + +.. |example<| raw:: latex + + \begin{exampleblock}{ + + +.. |end_example| raw:: latex + + \end{exampleblock} + + + +.. alert block +.. =========================== + +.. |alert<| raw:: latex + + \begin{alertblock}{ + + +.. |end_alert| raw:: latex + + \end{alertblock} + + + +.. columns +.. =========================== + +.. |column1| raw:: latex + + \begin{columns} + \begin{column}{0.45\textwidth} + +.. |column2| raw:: latex + + \end{column} + \begin{column}{0.45\textwidth} + + +.. |end_columns| raw:: latex + + \end{column} + \end{columns} + + + +.. |snake| image:: ../../img/py-web-new.png + :scale: 15% + + + +.. nested blocks +.. =========================== + +.. |nested| raw:: latex + + \begin{columns} + \begin{column}{0.85\textwidth} + +.. |end_nested| raw:: latex + + \end{column} + \end{columns} diff --git a/talk/sftour2013/invitae/stylesheet.latex b/talk/sftour2013/invitae/stylesheet.latex new file mode 100644 --- /dev/null +++ b/talk/sftour2013/invitae/stylesheet.latex @@ -0,0 +1,11 @@ +\usetheme{Boadilla} +\usecolortheme{whale} +\setbeamercovered{transparent} +\setbeamertemplate{navigation symbols}{} + +\definecolor{darkgreen}{rgb}{0, 0.5, 0.0} +\newcommand{\docutilsrolegreen}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\docutilsrolered}[1]{\color{red}#1\normalcolor} + +\newcommand{\green}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\red}[1]{\color{red}#1\normalcolor} diff --git a/talk/sftour2013/invitae/talk.rst b/talk/sftour2013/invitae/talk.rst new file mode 100644 --- /dev/null +++ b/talk/sftour2013/invitae/talk.rst @@ -0,0 +1,65 @@ +.. include:: beamerdefs.txt + +============================ +Writing fast Python programs +============================ + +who we are +---------- + +* Maciej Fijałkowski + +* Armin Rigo + +what we're going to talk about +------------------------------ + +* the problem of fast python + +* cython, numpy, weave, etc + +* PyPy and our approach + +* promise to keep it short + +python language +--------------- + +* expressive + +* concise + +* performance characteristics not 100% clear + +classic solutions +----------------- + +* use numpy, but your algorithms have to be vectorized + +|pause| + +* use cython, but you have to write down your types + +|pause| + +* don't use python, just call C + +demo +---- + +... + +pypy approach +------------- + +* make language fast enough for algorithms + +* make numpy compatible enough to reuse it + +* more algorithms less pipeline building + +more +---- + +* pypy.org + From noreply at buildbot.pypy.org Wed Mar 20 22:32:21 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 22:32:21 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup and DCE Message-ID: <20130320213221.975BE1C019F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62580:900232e06270 Date: 2013-03-20 14:32 -0700 http://bitbucket.org/pypy/pypy/changeset/900232e06270/ Log: cleanup and DCE diff --git a/rpython/translator/llsupport/__init__.py b/rpython/translator/llsupport/__init__.py deleted file mode 100644 diff --git a/rpython/translator/llsupport/test/__init__.py b/rpython/translator/llsupport/test/__init__.py deleted file mode 100644 diff --git a/rpython/translator/platform/distutils_platform.py b/rpython/translator/platform/distutils_platform.py --- a/rpython/translator/platform/distutils_platform.py +++ b/rpython/translator/platform/distutils_platform.py @@ -89,7 +89,7 @@ data = '' try: saved_environ = os.environ.copy() - c = stdoutcapture.Capture(mixed_out_err = True) + c = stdoutcapture.Capture(mixed_out_err=True) try: self._build() finally: diff --git a/rpython/translator/tool/taskengine.py b/rpython/translator/tool/taskengine.py --- a/rpython/translator/tool/taskengine.py +++ b/rpython/translator/tool/taskengine.py @@ -1,7 +1,4 @@ - - class SimpleTaskEngine(object): - def __init__(self): self._plan_cache = {} @@ -32,7 +29,7 @@ if dep.startswith('??'): # optional dep = dep[2:] if dep not in goals: - continue + continue if dep.startswith('?'): # suggested dep = dep[1:] if dep in skip: @@ -40,7 +37,7 @@ yield dep seen = {} - + def consider(subgoal): if subgoal in seen: return @@ -71,7 +68,7 @@ else: break else: - raise RuntimeError, "circular dependecy" + raise RuntimeError("circular dependecy") plan.append(cand) for constr in constraints: @@ -93,6 +90,7 @@ def _depending_on_closure(self, goal): d = {} + def track(goal): if goal in d: return @@ -127,10 +125,6 @@ def _event(self, kind, goal, func): pass - + def _error(self, goal): pass - - - - diff --git a/rpython/translator/tool/tracer.py b/rpython/translator/tool/tracer.py deleted file mode 100644 --- a/rpython/translator/tool/tracer.py +++ /dev/null @@ -1,42 +0,0 @@ -import types, sys -from rpython.annotator.model import SomeValue, debugname -from rpython.annotator.annset import AnnotationSet -from rpython.annotator.annrpython import RPythonAnnotator - -indent1 = [''] - -def show(n): - if isinstance(n, AnnotationSet): - return 'heap' - elif isinstance(n, RPythonAnnotator): - return 'rpyann' - else: - return repr(n) - -def trace(o): - if isinstance(o, types.ClassType): - for key, value in o.__dict__.items(): - o.__dict__[key] = trace(value) - elif isinstance(o, types.FunctionType): - d = {'o': o, 'show': show, 'indent1': indent1, 'stderr': sys.stderr} - exec """ -def %s(*args, **kwds): - indent, = indent1 - rargs = [show(a) for a in args] - for kw, value in kwds.items(): - rargs.append('%%s=%%r' %% (kw, value)) - print >> stderr, indent + %r + '(%%s)' %% ', '.join(rargs) - indent1[0] += '| ' - try: - result = o(*args, **kwds) - except Exception, e: - indent1[0] = indent - print >> stderr, indent + '+--> %%s: %%s' %% (e.__class__.__name__, e) - raise - indent1[0] = indent - if result is not None: - print >> stderr, indent + '+-->', show(result) - return result -result = %s -""" % (o.__name__, o.__name__, o.__name__) in d - return d['result'] From noreply at buildbot.pypy.org Wed Mar 20 22:45:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Mar 2013 22:45:04 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: fix stuff, add pdf Message-ID: <20130320214504.7DC201C03A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4963:7bb26582f0c7 Date: 2013-03-20 14:44 -0700 http://bitbucket.org/pypy/extradoc/changeset/7bb26582f0c7/ Log: fix stuff, add pdf diff --git a/talk/sftour2013/invitae/Makefile b/talk/sftour2013/invitae/Makefile --- a/talk/sftour2013/invitae/Makefile +++ b/talk/sftour2013/invitae/Makefile @@ -4,11 +4,14 @@ talk.pdf: talk.rst author.latex stylesheet.latex - rst2beamer --input-encoding=utf8 --output-encoding=utf8 --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit + rst2beamer --input-encoding=utf8 --output-encoding=utf8 --stylesheet=stylesheet.latex --overlaybullets=False --theme=Boadilla --documentoptions=14pt talk.rst talk.latex || exit sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit - #sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit + sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit pdflatex talk.latex || exit +clean: + rm talk.pdf talk.latex + view: talk.pdf evince talk.pdf & diff --git a/talk/sftour2013/invitae/stylesheet.latex b/talk/sftour2013/invitae/stylesheet.latex --- a/talk/sftour2013/invitae/stylesheet.latex +++ b/talk/sftour2013/invitae/stylesheet.latex @@ -1,4 +1,3 @@ -\usetheme{Boadilla} \usecolortheme{whale} \setbeamercovered{transparent} \setbeamertemplate{navigation symbols}{} diff --git a/talk/sftour2013/invitae/talk.pdf b/talk/sftour2013/invitae/talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8cc70917b710790411e934850ab9478901d4c649 GIT binary patch [cut] From noreply at buildbot.pypy.org Wed Mar 20 22:53:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Mar 2013 22:53:57 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: hg merge default Message-ID: <20130320215357.77A211C019F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: remove-list-smm Changeset: r62581:d5abc22c1b69 Date: 2013-03-20 13:43 -0700 http://bitbucket.org/pypy/pypy/changeset/d5abc22c1b69/ Log: hg merge default diff too long, truncating to 2000 out of 91457 lines diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -12,6 +12,10 @@ import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from itertools import imap as _imap +try: + from __pypy__ import newdict +except ImportError: + newdict = lambda _ : {} try: from thread import get_ident as _get_ident @@ -326,8 +330,11 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = newdict('module') + namespace['OrderedDict'] = OrderedDict + namespace['_property'] = property + namespace['_tuple'] = tuple + namespace['__name__'] = 'namedtuple_%s' % typename try: exec template in namespace except SyntaxError, e: diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py --- a/pypy/doc/test/test_whatsnew.py +++ b/pypy/doc/test/test_whatsnew.py @@ -1,6 +1,6 @@ import py import pypy -from commands import getoutput +from commands import getoutput, getstatusoutput ROOT = py.path.local(pypy.__file__).dirpath().dirpath() @@ -20,6 +20,9 @@ return startrev, branches def get_merged_branches(path, startrev, endrev): + if getstatusoutput('hg root')[0]: + py.test.skip('no Mercurial repo') + # X = take all the merges which are descendants of startrev and are on default # revset = all the parents of X which are not on default # ===> 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 @@ -20,16 +20,22 @@ .. branch: numpypy-longdouble Long double support for numpypy + .. branch: numpypy-disable-longdouble Since r_longdouble support is missing, disable all longdouble and derivative dtypes using ENABLED_LONG_DOUBLE = False + .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality + .. branch: indexing-by-array Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. +.. branch: str-dtype-improvement +Allow concatenation of str and numeric arrays + .. branch: signatures Improved RPython typing @@ -48,6 +54,7 @@ .. branch: fix-version-tool .. branch: popen2-removal .. branch: pickle-dumps +.. branch: scalar_get_set .. branch: release-2.0-beta1 diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -755,18 +755,6 @@ return obj interp_w._annspecialcase_ = 'specialize:arg(1)' - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): - """ - This method should NOT be called unless you are really sure about - it. It is used inside the implementation of end_finally() in - pyopcode.py, and it's there so that it can be overridden by the - FlowObjSpace. - """ - if self.is_w(w_obj, self.w_None): - return True - obj = self.interpclass_w(w_obj) - return isinstance(obj, RequiredClass) - def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable into a real (interpreter-level) list. diff --git a/pypy/interpreter/callbench/bltn04.py b/pypy/interpreter/callbench/bltn04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn04.py +++ /dev/null @@ -1,40 +0,0 @@ -from sup import run - -def w(N, start): - c = chr - - start() - i = 0 - while i < N: - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltn_instantiate.py b/pypy/interpreter/callbench/bltn_instantiate.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn_instantiate.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - o = object - start() - i = 0 - while i < N: - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna1.py b/pypy/interpreter/callbench/bltna1.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna1.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - while i < N: - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna2.py b/pypy/interpreter/callbench/bltna2.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna2.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - z = l.__init__ - while i < N: - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bm14.py b/pypy/interpreter/callbench/bm14.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bm14.py +++ /dev/null @@ -1,51 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f0(self): - pass - def f1(self, a): - pass - def f2(self, a, b): - pass - def f3(self, a, b, c): - pass - def f4(self, a, b, c, d): - pass - - a = A() - f0 = a.f0 - f1 = a.f1 - f2 = a.f2 - f3 = a.f3 - f4 = a.f4 - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f1(1) - f2(1, 2) - f2(1, 2) - f2(1, 2) - f3(1, 2, 3) - f3(1, 2, 3) - f4(1, 2, 3, 4) - - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f2(1, 2) - - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmabvararg.py b/pypy/interpreter/callbench/bmabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmabvararg.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f(self, a, b, *args): - pass - - a = A() - f = a.f - z = (3, 4, 5) - - start() - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmfilter.py b/pypy/interpreter/callbench/bmfilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmfilter.py +++ /dev/null @@ -1,20 +0,0 @@ -from sup import run - -def w(N, start): - x = range(50) - class A(object): - def f1(self, a): - return False - - x = range(50) - a = A() - f1 = a.f1 - flt = filter - - start() - i = 0 - while i < N: - flt(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/bmmore.py b/pypy/interpreter/callbench/bmmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmmore.py +++ /dev/null @@ -1,30 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f4(self, a, b, c, d): - pass - def f5(self, a, b, c, d, e): - pass - a = A() - f4 = a.f4 - f5 = a.f5 - - start() - i = 0 - while i < N: - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/compare.py b/pypy/interpreter/callbench/compare.py deleted file mode 100644 --- a/pypy/interpreter/callbench/compare.py +++ /dev/null @@ -1,22 +0,0 @@ -# compare.py - -import sys - -def main(cur, ref): - cur = open(cur, 'rU') - ref = open(ref, 'rU') - try: - while True: - cur_line = cur.next() - ref_line = ref.next() - cur_name, cur_t = cur_line.split() - ref_name, ref_t = ref_line.split() - assert cur_name == ref_name - cur_t = float(cur_t) - ref_t = float(ref_t) - print "%-16s %.06g (x%.02f)" % (cur_name, cur_t, cur_t/ref_t) - except StopIteration: - pass - -if __name__ == '__main__': - main(sys.argv[1], sys.argv[2]) diff --git a/pypy/interpreter/callbench/f04.py b/pypy/interpreter/callbench/f04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/f04.py +++ /dev/null @@ -1,39 +0,0 @@ -from sup import run - -def w(N, start): - def f0(): - pass - def f1(a): - pass - def f2(a, b): - pass - def f3(a, b, c): - pass - def f4(a, b, c, d): - pass - def f5(a, b, c, d, e): - pass - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fabvararg.py b/pypy/interpreter/callbench/fabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fabvararg.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - def f(a, b, *args): - pass - - z = (3, 4, 5) - start() - - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/ffilter.py b/pypy/interpreter/callbench/ffilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffilter.py +++ /dev/null @@ -1,14 +0,0 @@ -from sup import run - -def w(N, start): - def f1(a): - return False - x = range(50) - - start() - i = 0 - while i < N: - filter(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/ffunccall.py b/pypy/interpreter/callbench/ffunccall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffunccall.py +++ /dev/null @@ -1,36 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def foo(self, x): - pass - - __add__ = foo - - a = A() - a1 = A() - - start() - i = 0 - while i < N: - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fmore.py b/pypy/interpreter/callbench/fmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fmore.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - def f5(a, b, c, d, e): - pass - def f6(a, b, c, d, e, f): - pass - - start() - - i = 0 - while i < N: - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/inst.py b/pypy/interpreter/callbench/inst.py deleted file mode 100644 --- a/pypy/interpreter/callbench/inst.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def __init__(self): - pass - - class B(object): - def __init__(self, x, y): - pass - - start() - i = 0 - while i < N: - A() - A() - A() - A() - A() - B(1, 2) - B(1, 2) - B(1, 2) - B(1, 2) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/inst_no_init.py b/pypy/interpreter/callbench/inst_no_init.py deleted file mode 100644 --- a/pypy/interpreter/callbench/inst_no_init.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - pass - - start() - i = 0 - while i < N: - A() - A() - A() - A() - A() - A() - A() - A() - A() - A() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/instcall.py b/pypy/interpreter/callbench/instcall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/instcall.py +++ /dev/null @@ -1,35 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def __call__(self): - pass - - a = A() - - start() - i = 0 - while i < N: - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/sup.py b/pypy/interpreter/callbench/sup.py deleted file mode 100644 --- a/pypy/interpreter/callbench/sup.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys, time - -def ref(N, start): - start() - i = 0 - while i < N: - i+=1 - - -def run(func, n): - n *= int(sys.argv[1]) - st = [None] - t = time.time - - def start(): - st[0] = t() - - ref(n, start) - elapsed_ref1 = t() - st[0] - ref(n, start) - elapsed_ref2 = t() - st[0] - ref(n, start) - elapsed_ref3 = t() - st[0] - elapsed_ref = min(elapsed_ref1, elapsed_ref2, elapsed_ref3) - - func(n, start) - elapsed1 = t() - st[0] - func(n, start) - elapsed2 = t() - st[0] - func(n, start) - elapsed3 = t() - st[0] - elapsed = min(elapsed1, elapsed2, elapsed3) - - #if elapsed < elapsed_ref*10: - # print "not enough meat", elapsed, elapsed_ref - - print sys.argv[0].replace('.py', ''), elapsed-elapsed_ref - - diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -604,11 +604,12 @@ # item (unlike CPython which can have 1, 2 or 3 items): # [wrapped subclass of SuspendedUnroller] w_top = self.popvalue() - # the following logic is a mess for the flow objspace, - # so we hide it specially in the space :-/ - if self.space._check_constant_interp_w_or_w_None(SuspendedUnroller, w_top): - # case of a finally: block - unroller = self.space.interpclass_w(w_top) + if self.space.is_w(w_top, self.space.w_None): + # case of a finally: block with no exception + return None + unroller = self.space.interpclass_w(w_top) + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block with a suspended unroller return unroller else: # case of an except: block. We popped the exception type diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -49,8 +49,8 @@ return shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy() - loop.setslice(shape, self, impl) + impl = impl.copy(space) + loop.setslice(space, shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -82,6 +82,10 @@ return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) + def set_real(self, space, orig_array, w_value): + tmp = self.get_real(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() @@ -98,6 +102,10 @@ impl.fill(self.dtype.box(0)) return impl + def set_imag(self, space, orig_array, w_value): + tmp = self.get_imag(orig_array) + tmp.setslice(space, convert_to_array(space, w_value)) + # -------------------- applevel get/setitem ----------------------- @jit.unroll_safe @@ -237,12 +245,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self): + def copy(self, space): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.get_shape(), impl, self) + return loop.setslice(space, self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -273,7 +281,11 @@ def astype(self, space, dtype): new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) + if dtype.is_str_or_unicode(): + raise OperationError(space.w_NotImplementedError, space.wrap( + "astype(%s) not implemented yet" % self.dtype)) + else: + loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -1,6 +1,6 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.base import W_NDimArray, convert_to_array from pypy.module.micronumpy import support from pypy.interpreter.error import OperationError @@ -38,6 +38,9 @@ def get_strides(self): return [] + def get_backstrides(self): + return [] + def create_iter(self, shape=None, backward_broadcast=False): return ScalarIterator(self) @@ -47,7 +50,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self): + def copy(self, space): scalar = Scalar(self.dtype) scalar.value = self.value return scalar @@ -58,6 +61,55 @@ def transpose(self, _): return self + def get_real(self, orig_array): + if self.dtype.is_complex_type(): + scalar = Scalar(self.dtype.float_type) + scalar.value = self.value.convert_real_to(scalar.dtype) + return scalar + return self + + def set_real(self, space, orig_array, w_val): + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type or self.dtype + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + if self.dtype.is_complex_type(): + self.value = self.dtype.itemtype.composite( + w_arr.get_scalar_value().convert_to(dtype), + self.value.convert_imag_to(dtype)) + else: + self.value = w_arr.get_scalar_value() + + def get_imag(self, orig_array): + if self.dtype.is_complex_type(): + scalar = Scalar(self.dtype.float_type) + scalar.value = self.value.convert_imag_to(scalar.dtype) + return scalar + scalar = Scalar(self.dtype) + if self.dtype.is_flexible_type(): + scalar.value = self.value + else: + scalar.value = scalar.dtype.itemtype.box(0) + return scalar + + def set_imag(self, space, orig_array, w_val): + #Only called on complex dtype + assert self.dtype.is_complex_type() + w_arr = convert_to_array(space, w_val) + dtype = self.dtype.float_type + if len(w_arr.get_shape()) > 0: + raise OperationError(space.w_ValueError, space.wrap( + "could not broadcast input array from shape " + + "(%s) into shape ()" % ( + ','.join([str(x) for x in w_arr.get_shape()],)))) + self.value = self.dtype.itemtype.composite( + self.value.convert_real_to(dtype), + w_arr.get_scalar_value().convert_to(dtype), + ) + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,12 +116,21 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + a_dt = arr.get_dtype() + if dtype.is_record_type() and a_dt.is_record_type(): + #Record types must match + for f in dtype.fields: + if f not in a_dt.fields or \ + dtype.fields[f] != a_dt.fields[f]: + raise OperationError(space.w_TypeError, + space.wrap("record type mismatch")) + elif dtype.is_record_type() or a_dt.is_record_type(): + raise OperationError(space.w_TypeError, + space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -277,6 +277,10 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) + def convert_to(self, dtype): + # if we reach here, the record fields are guarenteed to match. + return self + class W_CharacterBox(W_FlexibleBox): pass @@ -290,10 +294,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.StringType) - return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -307,11 +307,6 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.UnicodeType) - return self - class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -71,7 +71,8 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) - + def build_and_convert(self, space, box): + return self.itemtype.build_and_convert(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -76,7 +76,7 @@ base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) arr = convert_to_array(space, w_value) - loop.flatiter_setitem(self.base, arr, start, step, length) + loop.flatiter_setitem(space, self.base, arr, start, step, length) def descr_iter(self): return self diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -258,30 +258,25 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy()) + return W_NDimArray(self.implementation.copy(space)) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - if ret: - return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, - space.wrap('imag not implemented for this dtype')) + return W_NDimArray(ret) def descr_set_real(self, space, w_value): # copy (broadcast) values into self - tmp = self.implementation.get_real(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_real(space, self, w_value) def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) - tmp = self.implementation.get_imag(self) - tmp.setslice(space, convert_to_array(space, w_value)) + self.implementation.set_imag(space, self, w_value) def descr_reshape(self, space, args_w): """reshape(...) 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind: + if dt1.kind == dt2.kind and not dt2.is_flexible_type(): return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,7 +434,23 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - else: + elif dt2.is_flexible_type(): + # For those operations that get here (concatenate, stack), + # flexible types take precedence over numeric type + if dt2.is_record_type(): + return dt2 + if dt1.is_str_or_unicode(): + if dt2.num == 18: + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + return dt2 + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -65,12 +65,19 @@ obj_iter.next() return out -setslice_driver = jit.JitDriver(name='numpy_setslice', +setslice_driver1 = jit.JitDriver(name='numpy_setslice1', greens = ['shapelen', 'dtype'], - reds = ['target', 'source', 'target_iter', - 'source_iter']) + reds = 'auto') +setslice_driver2 = jit.JitDriver(name='numpy_setslice2', + greens = ['shapelen', 'dtype'], + reds = 'auto') -def setslice(shape, target, source): +def setslice(space, shape, target, source): + if target.dtype.is_str_or_unicode(): + return setslice_build_and_convert(space, shape, target, source) + return setslice_to(space, shape, target, source) + +def setslice_to(space, shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -78,15 +85,26 @@ dtype = target.dtype shapelen = len(shape) while not target_iter.done(): - setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, - target=target, source=source, - target_iter=target_iter, - source_iter=source_iter) + setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +def setslice_build_and_convert(space, shape, target, source): + # note that unlike everything else, target and source here are + # array implementations, not arrays + target_iter = target.create_iter(shape) + source_iter = source.create_iter(shape) + dtype = target.dtype + shapelen = len(shape) + while not target_iter.done(): + setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem())) + target_iter.next() + source_iter.next() + return target + reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], @@ -358,17 +376,27 @@ ri.next() return res -flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', +flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1', greens = ['dtype'], reds = 'auto') -def flatiter_setitem(arr, val, start, step, length): +flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2', + greens = ['dtype'], + reds = 'auto') + +def flatiter_setitem(space, arr, val, start, step, length): + dtype = arr.get_dtype() + if dtype.is_str_or_unicode(): + return flatiter_setitem_build_and_convert(space, arr, val, start, step, length) + return flatiter_setitem_to(space, arr, val, start, step, length) + +def flatiter_setitem_to(space, arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver.jit_merge_point(dtype=dtype) + flatiter_setitem_driver1.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -377,6 +405,21 @@ # WTF numpy? val_iter.reset() +def flatiter_setitem_build_and_convert(space, arr, val, start, step, length): + dtype = arr.get_dtype() + arr_iter = arr.create_iter() + val_iter = val.create_iter() + arr_iter.next_skip_x(start) + while length > 0: + flatiter_setitem_driver2.jit_merge_point(dtype=dtype) + arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem())) + # need to repeat i_nput values until all assignments are done + arr_iter.next_skip_x(step) + length -= 1 + val_iter.next() + # WTF numpy? + val_iter.reset() + fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], reds = 'auto') @@ -461,18 +504,6 @@ val_arr.descr_getitem(space, w_idx)) iter.next() -copy_from_to_driver = jit.JitDriver(greens = ['dtype'], - reds = 'auto') - -def copy_from_to(from_, to, dtype): - from_iter = from_.create_iter() - to_iter = to.create_iter() - while not from_iter.done(): - copy_from_to_driver.jit_merge_point(dtype=dtype) - to_iter.setitem(from_iter.getitem().convert_to(dtype)) - to_iter.next() - from_iter.next() - byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') 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 @@ -140,25 +140,25 @@ def test_fmax(self): from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') - a = array((complex(ninf, 10), complex(10, ninf), + a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), 5+5j, 5-5j, -5+5j, -5-5j, 0+5j, 0-5j, 5, -5, complex(nan, 0), complex(0, nan)), dtype = complex) b = [ninf]*a.size - res = [a[0 ], a[1 ], a[2 ], a[3 ], + res = [a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ], a[8 ], a[9 ], a[10], a[11], b[12], b[13]] assert (fmax(a, b) == res).all() b = [inf]*a.size - res = [b[0 ], b[1 ], a[2 ], b[3 ], + res = [b[0 ], b[1 ], a[2 ], b[3 ], b[4 ], b[5 ], b[6 ], b[7 ], b[8 ], b[9 ], b[10], b[11], b[12], b[13]] assert (fmax(a, b) == res).all() b = [0]*a.size - res = [b[0 ], a[1 ], a[2 ], a[3 ], + res = [b[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], b[6 ], b[7 ], a[8 ], b[9 ], a[10], b[11], b[12], b[13]] @@ -167,25 +167,25 @@ def test_fmin(self): from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') - a = array((complex(ninf, 10), complex(10, ninf), + a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), 5+5j, 5-5j, -5+5j, -5-5j, 0+5j, 0-5j, 5, -5, complex(nan, 0), complex(0, nan)), dtype = complex) b = [inf]*a.size - res = [a[0 ], a[1 ], b[2 ], a[3 ], + res = [a[0 ], a[1 ], b[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ], a[8 ], a[9 ], a[10], a[11], b[12], b[13]] assert (fmin(a, b) == res).all() b = [ninf]*a.size - res = [b[0 ], b[1 ], b[2 ], b[3 ], + res = [b[0 ], b[1 ], b[2 ], b[3 ], b[4 ], b[5 ], b[6 ], b[7 ], b[8 ], b[9 ], b[10], b[11], b[12], b[13]] assert (fmin(a, b) == res).all() b = [0]*a.size - res = [a[0 ], b[1 ], b[2 ], b[3 ], + res = [a[0 ], b[1 ], b[2 ], b[3 ], b[4 ], b[5 ], a[6 ], a[7 ], b[8 ], a[9 ], b[10], a[11], b[12], b[13]] @@ -205,17 +205,17 @@ pass # no longdouble yet inf = float('inf') nan = float('nan') - #complex - orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, - complex(inf, 3), complex(inf, -3), complex(inf, -inf), + #complex + orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, + complex(inf, 3), complex(inf, -3), complex(inf, -inf), complex(nan, 3), 0+0j, 0-0j] a2 = 2.**2 + 4.**2 r = 2. / a2 i = 4. / a2 cnan = complex(nan, nan) - expected = [complex(r, -i), complex(-r, -i), complex(r, i), - complex(-r, i), - -0j, 0j, cnan, + expected = [complex(r, -i), complex(-r, -i), complex(r, i), + complex(-r, i), + -0j, 0j, cnan, cnan, cnan, cnan] for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) @@ -225,7 +225,7 @@ def test_floorceiltrunc(self): from numpypy import array, floor, ceil, trunc - a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) + a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) @@ -270,11 +270,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res[0]) - t2 = float(b[i].real) + t1 = float(res[0]) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res[1]) - t2 = float(b[i].imag) + t1 = float(res[1]) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_expm1(self): @@ -310,11 +310,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): @@ -330,16 +330,16 @@ raises(TypeError, logaddexp, complex(1, 1), complex(3, 3)) raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3)) raises(TypeError, arctan2, complex(1, 1), complex(3, 3)) - raises (TypeError, fmod, complex(90,90), 3) + raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): from numpypy import isnan, isinf, array - assert (isnan(array([0.2+2j, complex(float('inf'),0), + assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ [False, False, False, True, True]).all() - assert (isinf(array([0.2+2j, complex(float('inf'),0), + assert (isinf(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ [False, True, True, False, False]).all() @@ -374,7 +374,7 @@ b = power(a, p) for i in range(len(a)): try: - r = self.c_pow((float(a[i].real), float(a[i].imag)), + r = self.c_pow((float(a[i].real), float(a[i].imag)), (float(p.real), float(p.imag))) except ZeroDivisionError: r = (nan, nan) @@ -384,10 +384,10 @@ r = (nan, nan) msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ (c,a[i], p, b[i], r) - t1 = float(r[0]) - t2 = float(b[i].real) + t1 = float(r[0]) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(r[1]) + t1 = float(r[1]) t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) @@ -445,11 +445,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7)): b = log1p(array(a,dtype=c)) @@ -465,11 +465,11 @@ (c,a[i], b[i], res) # cast untranslated boxed results to float, # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) + t1 = float(res.real) + t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) + t1 = float(res.imag) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): @@ -520,7 +520,30 @@ assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real + b[0] = 1024 + assert a[0].real == 1024 assert b.dtype == dtype(float) + a = array(complex(3.0, 4.0)) + b = a.real + assert b == array(3) + assert a.imag == array(4) + a.real = 1024 + a.imag = 2048 + assert a.real == 1024 and a.imag == 2048 + assert b.dtype == dtype(float) + a = array(4.0) + b = a.imag + assert b == 0 + assert b.dtype == dtype(float) + exc = raises(TypeError, 'a.imag = 1024') + assert str(exc.value).startswith("array does not have imaginary") + exc = raises(ValueError, 'a.real = [1, 3]') + assert str(exc.value) == \ + "could not broadcast input array from shape (2) into shape ()" + a = array('abc') + assert str(a.real) == 'abc' + # numpy imag for flexible types returns self + assert str(a.imag) == 'abc' for complex_ in complex_dtypes: O = complex(0, 0) @@ -547,12 +570,12 @@ assert add(c1, c2) == complex_(complex(4, 6)) assert add(c1, c2) == complex(4, 6) - + assert sub(c0, c0) == sub(c1, c1) == 0 assert sub(c1, c2) == complex(-2, -2) assert negative(complex(1,1)) == complex(-1, -1) assert negative(complex(0, 0)) == 0 - + assert multiply(1, c1) == c1 assert multiply(2, c2) == complex(6, 8) @@ -590,8 +613,10 @@ assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' # numpy actually raises an AttributeError, # but numpypy raises a TypeError - raises((TypeError, AttributeError), 'c2.real = 10.') - raises((TypeError, AttributeError), 'c2.imag = 10.') + exc = raises((TypeError, AttributeError), 'c2.real = 10.') + assert str(exc.value) == "readonly attribute" + exc = raises((TypeError, AttributeError), 'c2.imag = 10.') + assert str(exc.value) == "readonly attribute" assert(real(c2) == 3.0) assert(imag(c2) == 4.0) @@ -610,7 +635,7 @@ for complex_, abs_err, testcases in (\ (np.complex128, 5e-323, self.testcases128), - # (np.complex64, 5e-32, self.testcases64), + # (np.complex64, 5e-32, self.testcases64), ): for id, fn, ar, ai, er, ei, flags in testcases: arg = complex_(complex(ar, ai)) @@ -648,7 +673,7 @@ ) % (id, fn, complex_, ar, ai, expected[0], expected[1], actual[0], actual[1]) - + # since rAlmostEqual is a wrapped function, # convert arguments to avoid boxed values rAlmostEqual(float(expected[0]), float(actual[0]), 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 @@ -1480,6 +1480,32 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() + a = concatenate((array([1]), array(['abc']))) + assert str(a.dtype) == '|S3' + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' + a = concatenate((['abcdef'], ['abc'])) + assert a[0] == 'abcdef' + assert str(a.dtype) == '|S6' + + def test_record_concatenate(self): + # only an exact match can succeed + from numpypy import zeros, concatenate + a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), + zeros((2,),dtype=[('x', int), ('y', float)]))) + assert a.shape == (4,) + exc = raises(TypeError, concatenate, + (zeros((2,), dtype=[('x', int), ('y', float)]), + (zeros((2,), dtype=[('x', float), ('y', float)])))) + assert str(exc.value).startswith('record type mismatch') + exc = raises(TypeError, concatenate, ([1], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + exc = raises(TypeError, concatenate, (['abc'], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + + def test_std(self): from numpypy import array @@ -1650,6 +1676,12 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 + # scalar vs. array + try: + a = array([1, 2, 3.14156]).astype('S3').dtype + assert a.itemsize == 3 + except NotImplementedError: + skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array @@ -1955,7 +1987,7 @@ assert (a.transpose() == b).all() def test_flatiter(self): - from numpypy import array, flatiter, arange + from numpypy import array, flatiter, arange, zeros a = array([[10, 30], [40, 60]]) f_iter = a.flat assert f_iter.next() == 10 @@ -1971,6 +2003,9 @@ a = arange(10).reshape(5, 2) raises(IndexError, 'a.flat[(1, 2)]') assert a.flat.base is a + m = zeros((2,2), dtype='S3') + m.flat[1] = 1 + assert m[0,1] == '1' def test_flatiter_array_conv(self): from numpypy import array, dot 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 @@ -1150,6 +1150,14 @@ return rfloat.NAN, rfloat.NAN return rfloat.INFINITY, rfloat.INFINITY + @specialize.argtype(1) + def composite(self, v1, v2): + assert isinstance(v1, self.ComponentBoxType) + assert isinstance(v2, self.ComponentBoxType) + real = v1.value + imag = v2.value + return self.box_complex(real, imag) + @complex_unary_op def pos(self, v): return v @@ -1627,6 +1635,7 @@ def get_size(self): return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1634,7 +1643,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) @@ -1675,6 +1684,20 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) + def build_and_convert(self, space, mydtype, box): + if box.get_dtype(space).is_str_or_unicode(): + arg = box.get_dtype(space).itemtype.to_str(box) + else: + w_arg = box.descr_str(space) + arg = space.str_w(space.str(w_arg)) + arr = VoidBoxStorage(self.size, mydtype) + i = 0 + for i in range(min(len(arg), self.size)): + arr.storage[i] = arg[i] + for j in range(i + 1, self.size): + arr.storage[j] = '\x00' + return interp_boxes.W_StringBox(arr, 0, arr.dtype) + class VoidType(BaseType, BaseStringType): T = lltype.Char diff --git a/pypy/objspace/proxy.py b/pypy/objspace/proxy.py deleted file mode 100644 --- a/pypy/objspace/proxy.py +++ /dev/null @@ -1,23 +0,0 @@ -from pypy.interpreter.baseobjspace import ObjSpace - -# __________________________________________________________________________ - -def get_operations(): - return [r[0] for r in ObjSpace.MethodTable] + ObjSpace.IrregularOpTable - -def patch_space_in_place(space, proxyname, proxymaker, operations=None): - """Patches the supplied space.""" - - if operations is None: - operations = get_operations() - - for name in operations: - parentfn = getattr(space, name) - proxy = proxymaker(space, name, parentfn) - if proxy: - setattr(space, name, proxy) - - prevrepr = repr(space) - space._this_space_repr_ = '%s(%s)' % (proxyname, prevrepr) - -# __________________________________________________________________________ diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -106,19 +106,16 @@ for w_k, w_v in list_pairs_w: w_self.setitem(w_k, w_v) - def setitem(self, w_key, w_value): - self.strategy.setitem(self, w_key, w_value) - def setitem_str(self, key, w_value): self.strategy.setitem_str(self, key, w_value) def _add_indirections(): - dict_methods = "getitem \ - getitem_str delitem length \ - clear w_keys values \ - items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_unicode listview_int \ + dict_methods = "getitem getitem_str setitem setdefault \ + popitem delitem clear \ + length w_keys values items \ + iterkeys itervalues iteritems \ + listview_str listview_unicode listview_int \ view_as_kwargs".split() def make_method(method): diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py --- a/pypy/objspace/std/kwargsdict.py +++ b/pypy/objspace/std/kwargsdict.py @@ -72,9 +72,17 @@ values_w.append(w_value) def setdefault(self, w_dict, w_key, w_default): - # XXX could do better, but is it worth it? - self.switch_to_object_strategy(w_dict) - return w_dict.setdefault(w_key, w_default) + space = self.space + if self.is_correct_type(w_key): + key = self.unwrap(w_key) + w_result = self.getitem_str(w_dict, key) + if w_result is not None: + return w_result + self.setitem_str(w_dict, key, w_default) + return w_default + else: + self.switch_to_object_strategy(w_dict) + return w_dict.setdefault(w_key, w_default) def delitem(self, w_dict, w_key): # XXX could do better, but is it worth it? diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py --- a/pypy/objspace/std/test/test_kwargsdict.py +++ b/pypy/objspace/std/test/test_kwargsdict.py @@ -146,3 +146,16 @@ assert dict.fromkeys(f(a=2, b=3)) == {"a": None, "b": None} assert sorted(f(a=2, b=3).itervalues()) == [2, 3] + + def test_setdefault(self): + def f(**args): + return args + d = f(a=1, b=2) + a = d.setdefault("a", 0) + assert a == 1 + a = d.setdefault("b", 0) + assert a == 2 + a = d.setdefault("c", 3) + assert a == 3 + assert "KwargsDictStrategy" in self.get_strategy(d) + diff --git a/rpython/jit/backend/x86/test/test_ztranslation.py b/rpython/jit/backend/x86/test/test_ztranslation.py --- a/rpython/jit/backend/x86/test/test_ztranslation.py +++ b/rpython/jit/backend/x86/test/test_ztranslation.py @@ -22,155 +22,6 @@ assert '-msse2' in cbuilder.eci.compile_extra assert '-mfpmath=sse' in cbuilder.eci.compile_extra - def test_stuff_translates(self): - # this is a basic test that tries to hit a number of features and their - # translation: - # - jitting of loops and bridges - # - virtualizables - # - set_param interface - # - profiler - # - full optimizer - # - floats neg and abs - - class Frame(object): - _virtualizable2_ = ['i'] - - def __init__(self, i): - self.i = i - - @dont_look_inside - def myabs(x): - return abs(x) - - jitdriver = JitDriver(greens = [], - reds = ['total', 'frame', 'j'], - virtualizables = ['frame']) - def f(i, j): - for param, _ in unroll_parameters: - defl = PARAMETERS[param] - set_param(jitdriver, param, defl) - set_param(jitdriver, "threshold", 3) - set_param(jitdriver, "trace_eagerness", 2) - total = 0 - frame = Frame(i) - j = float(j) - while frame.i > 3: - jitdriver.can_enter_jit(frame=frame, total=total, j=j) - jitdriver.jit_merge_point(frame=frame, total=total, j=j) - total += frame.i - if frame.i >= 20: - frame.i -= 2 - frame.i -= 1 - j *= -0.712 - if j + (-j): raise ValueError - k = myabs(j) - if k - abs(j): raise ValueError - if k - abs(-j): raise ValueError - return chr(total % 253) - # - from rpython.rtyper.lltypesystem import lltype, rffi - from rpython.rlib.libffi import types, CDLL, ArgChain - from rpython.rlib.test.test_clibffi import get_libm_name - libm_name = get_libm_name(sys.platform) - jitdriver2 = JitDriver(greens=[], reds = ['i', 'func', 'res', 'x']) - def libffi_stuff(i, j): - lib = CDLL(libm_name) - func = lib.getpointer('fabs', [types.double], types.double) - res = 0.0 - x = float(j) - while i > 0: - jitdriver2.jit_merge_point(i=i, res=res, func=func, x=x) - promote(func) - argchain = ArgChain() - argchain.arg(x) - res = func.call(argchain, rffi.DOUBLE) - i -= 1 - return res - # - def main(i, j): - a_char = f(i, j) - a_float = libffi_stuff(i, j) - return ord(a_char) * 10 + int(a_float) - expected = main(40, -49) - res = self.meta_interp(main, [40, -49]) - assert res == expected - - def test_direct_assembler_call_translates(self): - """Test CALL_ASSEMBLER and the recursion limit""" - from rpython.rlib.rstackovf import StackOverflow - - class Thing(object): - def __init__(self, val): - self.val = val - - class Frame(object): - _virtualizable2_ = ['thing'] - - driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], - virtualizables = ['frame'], - get_printable_location = lambda codeno: str(codeno)) - class SomewhereElse(object): - pass - - somewhere_else = SomewhereElse() - - def change(newthing): - somewhere_else.frame.thing = newthing - - def main(codeno): - frame = Frame() - somewhere_else.frame = frame - frame.thing = Thing(0) - portal(codeno, frame) - return frame.thing.val - - def portal(codeno, frame): - i = 0 - while i < 10: - driver.can_enter_jit(frame=frame, codeno=codeno, i=i) - driver.jit_merge_point(frame=frame, codeno=codeno, i=i) - nextval = frame.thing.val - if codeno == 0: - subframe = Frame() - subframe.thing = Thing(nextval) - nextval = portal(1, subframe) - elif frame.thing.val > 40: - change(Thing(13)) - nextval = 13 - frame.thing = Thing(nextval + 1) - i += 1 - return frame.thing.val - - driver2 = JitDriver(greens = [], reds = ['n']) - - def main2(bound): - try: - while portal2(bound) == -bound+1: - bound *= 2 - except StackOverflow: - pass - return bound - - def portal2(n): - while True: - driver2.jit_merge_point(n=n) - n -= 1 - if n <= 0: - return n - n = portal2(n) - assert portal2(10) == -9 - - def mainall(codeno, bound): - return main(codeno) + main2(bound) - - res = self.meta_interp(mainall, [0, 1], inline=True, - policy=StopAtXPolicy(change)) - print hex(res) - assert res & 255 == main(0) - bound = res & ~255 - assert 1024 <= bound <= 131072 - assert bound & (bound-1) == 0 # a power of two - def test_jit_get_stats(self): driver = JitDriver(greens = [], reds = ['i']) @@ -189,87 +40,3 @@ res = self.meta_interp(main, []) assert res == 3 # one for loop, one for entry point and one for the prologue - -class TestTranslationRemoveTypePtrX86(CCompiledMixin): - CPUClass = getcpuclass() - - def _get_TranslationContext(self): - t = TranslationContext() - t.config.translation.gc = DEFL_GC # 'hybrid' or 'minimark' - t.config.translation.gcrootfinder = 'asmgcc' - t.config.translation.list_comprehension_operations = True - t.config.translation.gcremovetypeptr = True - return t - - def test_external_exception_handling_translates(self): - jitdriver = JitDriver(greens = [], reds = ['n', 'total']) - - class ImDone(Exception): - def __init__(self, resvalue): - self.resvalue = resvalue - - @dont_look_inside - def f(x, total): - if x <= 30: - raise ImDone(total * 10) - if x > 200: - return 2 - raise ValueError - @dont_look_inside - def g(x): - if x > 150: - raise ValueError - return 2 - class Base: - def meth(self): - return 2 - class Sub(Base): - def meth(self): - return 1 - @dont_look_inside - def h(x): - if x < 20000: - return Sub() - else: - return Base() - def myportal(i): - set_param(jitdriver, "threshold", 3) - set_param(jitdriver, "trace_eagerness", 2) - total = 0 - n = i - while True: - jitdriver.can_enter_jit(n=n, total=total) - jitdriver.jit_merge_point(n=n, total=total) - try: - total += f(n, total) - except ValueError: - total += 1 - try: - total += g(n) - except ValueError: - total -= 1 - n -= h(n).meth() # this is to force a GUARD_CLASS - def main(i): - try: - myportal(i) - except ImDone, e: - return e.resvalue - - # XXX custom fishing, depends on the exact env var and format - logfile = udir.join('test_ztranslation.log') - os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,) - try: - res = self.meta_interp(main, [400]) - assert res == main(400) - finally: - del os.environ['PYPYLOG'] - - guard_class = 0 - for line in open(str(logfile)): - if 'guard_class' in line: - guard_class += 1 - # if we get many more guard_classes, it means that we generate - # guards that always fail (the following assert's original purpose - # is to catch the following case: each GUARD_CLASS is misgenerated - # and always fails with "gcremovetypeptr") - assert 0 < guard_class < 10 diff --git a/rpython/jit/backend/x86/test/test_ztranslation_basic.py b/rpython/jit/backend/x86/test/test_ztranslation_basic.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/x86/test/test_ztranslation_basic.py @@ -0,0 +1,96 @@ +import py, os, sys +from rpython.tool.udir import udir +from rpython.rlib.jit import JitDriver, unroll_parameters, set_param +from rpython.rlib.jit import PARAMETERS, dont_look_inside +from rpython.rlib.jit import promote +from rpython.rlib import jit_hooks +from rpython.jit.metainterp.jitprof import Profiler +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.backend.test.support import CCompiledMixin +from rpython.jit.codewriter.policy import StopAtXPolicy +from rpython.translator.translator import TranslationContext +from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 +from rpython.config.translationoption import DEFL_GC +from rpython.rlib import rgc + +class TestTranslationX86(CCompiledMixin): + CPUClass = getcpuclass() + + def _check_cbuilder(self, cbuilder): + # We assume here that we have sse2. If not, the CPUClass + # needs to be changed to CPU386_NO_SSE2, but well. + assert '-msse2' in cbuilder.eci.compile_extra + assert '-mfpmath=sse' in cbuilder.eci.compile_extra + + def test_stuff_translates(self): + # this is a basic test that tries to hit a number of features and their + # translation: + # - jitting of loops and bridges + # - virtualizables + # - set_param interface + # - profiler + # - full optimizer + # - floats neg and abs + + class Frame(object): + _virtualizable2_ = ['i'] + + def __init__(self, i): + self.i = i + + @dont_look_inside + def myabs(x): + return abs(x) + + jitdriver = JitDriver(greens = [], + reds = ['total', 'frame', 'j'], + virtualizables = ['frame']) + def f(i, j): From noreply at buildbot.pypy.org Wed Mar 20 22:53:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Mar 2013 22:53:58 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: Kill interpclass_w everywhere. Message-ID: <20130320215358.CCDE71C019F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: remove-list-smm Changeset: r62582:d944ad6fa63d Date: 2013-03-20 14:53 -0700 http://bitbucket.org/pypy/pypy/changeset/d944ad6fa63d/ Log: Kill interpclass_w everywhere. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -216,16 +216,15 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True - def __spacebind__(self, space): return self + +# ---------- backward compatibility: these classes are the same now ---------- +Wrappable = W_Root +# ---------------------------------------------------------------------------- + + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -337,9 +336,8 @@ continue raise modname = self.str_w(w_modname) - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -348,9 +346,8 @@ self.call_function(w_exitfunc) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -422,9 +419,8 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): @@ -721,21 +717,10 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): @@ -746,13 +731,12 @@ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' def unpackiterable(self, w_iterable, expected_length=-1): @@ -1030,8 +1014,7 @@ def is_oldstyle_instance(self, w_obj): # xxx hack hack hack from pypy.module.__builtin__.interp_classobj import W_InstanceObject - obj = self.interpclass_w(w_obj) - return obj is not None and isinstance(obj, W_InstanceObject) + return isinstance(w_obj, W_InstanceObject) def callable(self, w_obj): if self.lookup(w_obj, "__call__") is not None: @@ -1668,7 +1651,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1685,7 +1667,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -550,18 +550,17 @@ def descr_method_eq(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, Method): + if not isinstance(w_other, Method): return space.w_NotImplemented if self.w_instance is None: - if other.w_instance is not None: + if w_other.w_instance is not None: return space.w_False else: - if other.w_instance is None: + if w_other.w_instance is None: return space.w_False - if not space.eq_w(self.w_instance, other.w_instance): + if not space.eq_w(self.w_instance, w_other.w_instance): return space.w_False - return space.eq(self.w_function, other.w_function) + return space.eq(self.w_function, w_other.w_function) def descr_method_hash(self): space = self.space @@ -578,13 +577,14 @@ new_inst = mod.get('method_new') w = space.wrap w_instance = self.w_instance or space.w_None - function = space.interpclass_w(self.w_function) - if isinstance(function, Function) and isinstance(function.code, BuiltinCode): + w_function = self.w_function + if (isinstance(w_function, Function) and + isinstance(w_function.code, BuiltinCode)): new_inst = mod.get('builtin_method_new') if space.is_w(w_instance, space.w_None): - tup = [self.w_class, space.wrap(function.name)] + tup = [self.w_class, space.wrap(w_function.name)] else: - tup = [w_instance, space.wrap(function.name)] + tup = [w_instance, space.wrap(w_function.name)] elif space.is_w( self.w_class, space.w_None ): tup = [self.w_function, w_instance] else: diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -91,13 +91,13 @@ return None else: w_value = loader(space) - func = space.interpclass_w(w_value) # the idea of the following code is that all functions that are # directly in a mixed-module are "builtin", e.g. they get a # special type without a __get__ # note that this is not just all functions that contain a # builtin code object, as e.g. methods of builtin types have to # be normal Functions to get the correct binding behaviour + func = w_value if (isinstance(func, Function) and type(func) is not BuiltinFunction): try: diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -34,18 +34,17 @@ self.w_value = None def descr__cmp__(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Cell): + if not isinstance(w_other, Cell): return space.w_NotImplemented if self.w_value is None: - if other.w_value is None: + if w_other.w_value is None: return space.newint(0) return space.newint(-1) - elif other.w_value is None: + elif w_other.w_value is None: return space.newint(1) - return space.cmp(self.w_value, other.w_value) + return space.cmp(self.w_value, w_other.w_value) def descr__reduce__(self, space): w_mod = space.getbuiltinmodule('_pickle_support') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -290,29 +290,28 @@ def descr_code__eq__(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, PyCode): + if not isinstance(w_other, PyCode): return space.w_False - areEqual = (self.co_name == other.co_name and - self.co_argcount == other.co_argcount and - self.co_nlocals == other.co_nlocals and - self.co_flags == other.co_flags and - self.co_firstlineno == other.co_firstlineno and - self.co_code == other.co_code and - len(self.co_consts_w) == len(other.co_consts_w) and - len(self.co_names_w) == len(other.co_names_w) and - self.co_varnames == other.co_varnames and - self.co_freevars == other.co_freevars and - self.co_cellvars == other.co_cellvars) + areEqual = (self.co_name == w_other.co_name and + self.co_argcount == w_other.co_argcount and + self.co_nlocals == w_other.co_nlocals and + self.co_flags == w_other.co_flags and + self.co_firstlineno == w_other.co_firstlineno and + self.co_code == w_other.co_code and + len(self.co_consts_w) == len(w_other.co_consts_w) and + len(self.co_names_w) == len(w_other.co_names_w) and + self.co_varnames == w_other.co_varnames and + self.co_freevars == w_other.co_freevars and + self.co_cellvars == w_other.co_cellvars) if not areEqual: return space.w_False for i in range(len(self.co_names_w)): - if not space.eq_w(self.co_names_w[i], other.co_names_w[i]): + if not space.eq_w(self.co_names_w[i], w_other.co_names_w[i]): return space.w_False for i in range(len(self.co_consts_w)): - if not space.eq_w(self.co_consts_w[i], other.co_consts_w[i]): + if not space.eq_w(self.co_consts_w[i], w_other.co_consts_w[i]): return space.w_False return space.w_True diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -607,16 +607,15 @@ if self.space.is_w(w_top, self.space.w_None): # case of a finally: block with no exception return None - unroller = self.space.interpclass_w(w_top) - if isinstance(unroller, SuspendedUnroller): + if isinstance(w_top, SuspendedUnroller): # case of a finally: block with a suspended unroller - return unroller + return w_top else: # case of an except: block. We popped the exception type self.popvalue() # Now we pop the exception value - unroller = self.space.interpclass_w(self.popvalue()) - assert unroller is not None - return unroller + w_unroller = self.popvalue() + assert w_unroller is not None + return w_unroller def BUILD_CLASS(self, oparg, next_instr): w_methodsdict = self.popvalue() @@ -944,11 +943,9 @@ w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) - unroller = self.space.interpclass_w(w_unroller) - is_app_exc = (unroller is not None and - isinstance(unroller, SApplicationException)) - if is_app_exc: - operr = unroller.operr + if isinstance(w_unroller, SApplicationException): + # app-level exception + operr = w_unroller.operr self.last_exception = operr w_traceback = self.space.wrap(operr.get_traceback()) w_suppress = self.call_contextmanager_exit_function( diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -61,8 +61,7 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if w_tb is None or not space.is_true(space.isinstance(w_tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) - return tb + return w_tb diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -116,9 +116,8 @@ return space.builtin if space.is_true(space.isinstance(w_builtin, space.w_dict)): return module.Module(space, None, w_builtin) - builtin = space.interpclass_w(w_builtin) - if isinstance(builtin, module.Module): - return builtin + if isinstance(w_builtin, module.Module): + return w_builtin # no builtin! make a default one. Give them None, at least. builtin = module.Module(space, None) space.setitem(builtin.w_dict, space.wrap('None'), space.w_None) diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -88,11 +88,9 @@ return space.is_true(w_result) # -- case (old-style instance, old-style class) - oldstyleclass = space.interpclass_w(w_klass_or_tuple) - if isinstance(oldstyleclass, W_ClassObject): - oldstyleinst = space.interpclass_w(w_obj) - if isinstance(oldstyleinst, W_InstanceObject): - return oldstyleinst.w_class.is_subclass_of(oldstyleclass) + if isinstance(w_klass_or_tuple, W_ClassObject): + if isinstance(w_obj, W_InstanceObject): + return w_obj.w_class.is_subclass_of(w_klass_or_tuple) return _abstract_isinstance_w_helper(space, w_obj, w_klass_or_tuple) @jit.dont_look_inside @@ -152,11 +150,9 @@ return space.is_true(w_result) # -- case (old-style class, old-style class) - oldstylederived = space.interpclass_w(w_derived) - if isinstance(oldstylederived, W_ClassObject): - oldstyleklass = space.interpclass_w(w_klass_or_tuple) - if isinstance(oldstyleklass, W_ClassObject): - return oldstylederived.is_subclass_of(oldstyleklass) + if isinstance(w_derived, W_ClassObject): + if isinstance(w_klass_or_tuple, W_ClassObject): + return w_derived.is_subclass_of(w_klass_or_tuple) else: check_class(space, w_derived, "issubclass() arg 1 must be a class") # from here on, we are sure that w_derived is a class-like object @@ -171,31 +167,26 @@ # Exception helpers def exception_is_valid_obj_as_class_w(space, w_obj): - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_ClassObject): + if isinstance(w_obj, W_ClassObject): return True return BaseObjSpace.exception_is_valid_obj_as_class_w(space, w_obj) def exception_is_valid_class_w(space, w_cls): - cls = space.interpclass_w(w_cls) - if isinstance(cls, W_ClassObject): + if isinstance(w_cls, W_ClassObject): return True return BaseObjSpace.exception_is_valid_class_w(space, w_cls) def exception_getclass(space, w_obj): - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_InstanceObject): - return obj.w_class + if isinstance(w_obj, W_InstanceObject): + return w_obj.w_class return BaseObjSpace.exception_getclass(space, w_obj) def exception_issubclass_w(space, w_cls1, w_cls2): - cls1 = space.interpclass_w(w_cls1) - cls2 = space.interpclass_w(w_cls2) - if isinstance(cls1, W_ClassObject): - if isinstance(cls2, W_ClassObject): - return cls1.is_subclass_of(cls2) + if isinstance(w_cls1, W_ClassObject): + if isinstance(w_cls2, W_ClassObject): + return w_cls1.is_subclass_of(w_cls2) return False - if isinstance(cls2, W_ClassObject): + if isinstance(w_cls2, W_ClassObject): return False return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -79,8 +79,7 @@ space.wrap(' \t')), "", "eval") - codeobj = space.interpclass_w(w_code) - if not isinstance(codeobj, PyCode): + if not isinstance(w_code, PyCode): raise OperationError(space.w_TypeError, w('eval() arg 1 must be a string or code object')) @@ -102,4 +101,4 @@ # the gettopframe_nohidden()). I bet no test fails, and it's a really # obscure case. - return codeobj.exec_code(space, w_globals, w_locals) + return w_code.exec_code(space, w_globals, w_locals) diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py --- a/pypy/module/__builtin__/interp_memoryview.py +++ b/pypy/module/__builtin__/interp_memoryview.py @@ -22,11 +22,10 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if isinstance(other, W_MemoryView): + if isinstance(w_other, W_MemoryView): # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) try: diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -90,15 +90,14 @@ from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitive space = self.space cdata1 = self._cdata - other = space.interpclass_w(w_other) - if isinstance(other, W_CData): + if isinstance(w_other, W_CData): if requires_ordering: if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(other.ctype, W_CTypePrimitive)): + isinstance(w_other.ctype, W_CTypePrimitive)): raise OperationError(space.w_TypeError, space.wrap("cannot do comparison on a " "primitive cdata")) - cdata2 = other._cdata + cdata2 = w_other._cdata elif (misc.is_zero(space, w_other) and not isinstance(self.ctype, W_CTypePrimitive)): cdata2 = lltype.nullptr(rffi.CCHARP.TO) @@ -246,10 +245,9 @@ def sub(self, w_other): space = self.space - ob = space.interpclass_w(w_other) - if isinstance(ob, W_CData): + if isinstance(w_other, W_CData): from pypy.module._cffi_backend import ctypeptr, ctypearray - ct = ob.ctype + ct = w_other.ctype if isinstance(ct, ctypearray.W_CTypeArray): ct = ct.ctptr # @@ -261,7 +259,7 @@ self.ctype.name, ct.name) # diff = (rffi.cast(lltype.Signed, self._cdata) - - rffi.cast(lltype.Signed, ob._cdata)) // ct.ctitem.size + rffi.cast(lltype.Signed, w_other._cdata)) // ct.ctitem.size return space.wrap(diff) # return self._add_or_sub(w_other, -1) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -80,12 +80,11 @@ def _convert_error(self, expected, w_got): space = self.space - ob = space.interpclass_w(w_got) - if isinstance(ob, cdataobj.W_CData): + if isinstance(w_got, cdataobj.W_CData): return operationerrfmt(space.w_TypeError, "initializer for ctype '%s' must be a %s, " "not cdata '%s'", self.name, expected, - ob.ctype.name) + w_got.ctype.name) else: return operationerrfmt(space.w_TypeError, "initializer for ctype '%s' must be a %s, " diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -50,10 +50,9 @@ def cast(self, w_ob): from pypy.module._cffi_backend import ctypeptr space = self.space - ob = space.interpclass_w(w_ob) - if (isinstance(ob, cdataobj.W_CData) and - isinstance(ob.ctype, ctypeptr.W_CTypePtrOrArray)): - value = rffi.cast(lltype.Signed, ob._cdata) + if (isinstance(w_ob, cdataobj.W_CData) and + isinstance(w_ob.ctype, ctypeptr.W_CTypePtrOrArray)): + value = rffi.cast(lltype.Signed, w_ob._cdata) value = self._cast_result(value) elif space.isinstance_w(w_ob, space.w_str): value = self.cast_str(w_ob) @@ -112,10 +111,9 @@ s = space.str_w(w_ob) if len(s) == 1: return s[0] - ob = space.interpclass_w(w_ob) - if (isinstance(ob, cdataobj.W_CData) and - isinstance(ob.ctype, W_CTypePrimitiveChar)): - return ob._cdata[0] + if (isinstance(w_ob, cdataobj.W_CData) and + isinstance(w_ob.ctype, W_CTypePrimitiveChar)): + return w_ob._cdata[0] raise self._convert_error("string of length 1", w_ob) def convert_from_object(self, cdata, w_ob): @@ -146,10 +144,9 @@ s = space.unicode_w(w_ob) if len(s) == 1: return s[0] - ob = space.interpclass_w(w_ob) - if (isinstance(ob, cdataobj.W_CData) and - isinstance(ob.ctype, W_CTypePrimitiveUniChar)): - return rffi.cast(rffi.CWCHARP, ob._cdata)[0] + if (isinstance(w_ob, cdataobj.W_CData) and + isinstance(w_ob.ctype, W_CTypePrimitiveUniChar)): + return rffi.cast(rffi.CWCHARP, w_ob._cdata)[0] raise self._convert_error("unicode string of length 1", w_ob) def convert_from_object(self, cdata, w_ob): @@ -270,13 +267,12 @@ def cast(self, w_ob): space = self.space - ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - if not isinstance(ob.ctype, W_CTypePrimitive): + if isinstance(w_ob, cdataobj.W_CData): + if not isinstance(w_ob.ctype, W_CTypePrimitive): raise operationerrfmt(space.w_TypeError, "cannot cast ctype '%s' to ctype '%s'", - ob.ctype.name, self.name) - w_ob = ob.convert_to_object() + w_ob.ctype.name, self.name) + w_ob = w_ob.convert_to_object() # if space.isinstance_w(w_ob, space.w_str): value = self.cast_str(w_ob) @@ -319,11 +315,10 @@ def cast(self, w_ob): space = self.space - ob = space.interpclass_w(w_ob) - if (isinstance(ob, cdataobj.W_CData) and - isinstance(ob.ctype, W_CTypePrimitiveLongDouble)): - w_cdata = self.convert_to_object(ob._cdata) - keepalive_until_here(ob) + if (isinstance(w_ob, cdataobj.W_CData) and + isinstance(w_ob.ctype, W_CTypePrimitiveLongDouble)): + w_cdata = self.convert_to_object(w_ob._cdata) + keepalive_until_here(w_ob) return w_cdata else: return W_CTypePrimitiveFloat.cast(self, w_ob) @@ -356,11 +351,10 @@ def convert_from_object(self, cdata, w_ob): space = self.space - ob = space.interpclass_w(w_ob) - if (isinstance(ob, cdataobj.W_CData) and - isinstance(ob.ctype, W_CTypePrimitiveLongDouble)): - self._copy_longdouble(ob._cdata, cdata) - keepalive_until_here(ob) + if (isinstance(w_ob, cdataobj.W_CData) and + isinstance(w_ob.ctype, W_CTypePrimitiveLongDouble)): + self._copy_longdouble(w_ob._cdata, cdata) + keepalive_until_here(w_ob) else: value = space.float_w(space.float(w_ob)) self._to_longdouble_and_write(value, cdata) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -50,10 +50,9 @@ if self.size < 0: return W_CType.cast(self, w_ob) space = self.space - ob = space.interpclass_w(w_ob) - if (isinstance(ob, cdataobj.W_CData) and - isinstance(ob.ctype, W_CTypePtrOrArray)): - value = ob._cdata + if (isinstance(w_ob, cdataobj.W_CData) and + isinstance(w_ob.ctype, W_CTypePtrOrArray)): + value = w_ob._cdata else: value = misc.as_unsigned_long(space, w_ob, strict=False) value = rffi.cast(rffi.CCHARP, value) @@ -152,14 +151,13 @@ def convert_from_object(self, cdata, w_ob): space = self.space - ob = space.interpclass_w(w_ob) - if not isinstance(ob, cdataobj.W_CData): + if not isinstance(w_ob, cdataobj.W_CData): if misc.is_zero(space, w_ob): NULL = lltype.nullptr(rffi.CCHARP.TO) rffi.cast(rffi.CCHARPP, cdata)[0] = NULL return raise self._convert_error("cdata pointer", w_ob) - other = ob.ctype + other = w_ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray if isinstance(other, ctypearray.W_CTypeArray): @@ -170,7 +168,7 @@ if not (self.can_cast_anything or other.can_cast_anything): raise self._convert_error("compatible pointer", w_ob) - rffi.cast(rffi.CCHARPP, cdata)[0] = ob._cdata + rffi.cast(rffi.CCHARPP, cdata)[0] = w_ob._cdata def _alignof(self): from pypy.module._cffi_backend import newtype @@ -252,9 +250,8 @@ def prepare_file(self, w_ob): from pypy.module._file.interp_file import W_File - ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) + if isinstance(w_ob, W_File): + return prepare_file_argument(self.space, w_ob) else: return lltype.nullptr(rffi.CCHARP.TO) @@ -306,8 +303,7 @@ def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space - ob = space.interpclass_w(w_ob) - result = (not isinstance(ob, cdataobj.W_CData) and + result = (not isinstance(w_ob, cdataobj.W_CData) and self._prepare_pointer_call_argument(w_ob, cdata)) if result == 0: self.convert_from_object(cdata, w_ob) diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -80,11 +80,10 @@ def _copy_from_same(self, cdata, w_ob): space = self.space - ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - if ob.ctype is self and self.size >= 0: - misc._raw_memcopy(ob._cdata, cdata, self.size) - keepalive_until_here(ob) + if isinstance(w_ob, cdataobj.W_CData): + if w_ob.ctype is self and self.size >= 0: + misc._raw_memcopy(w_ob._cdata, cdata, self.size) + keepalive_until_here(w_ob) return True return False diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -31,15 +31,14 @@ # ____________________________________________________________ def sizeof(space, w_obj): - ob = space.interpclass_w(w_obj) - if isinstance(ob, cdataobj.W_CData): - size = ob._sizeof() - elif isinstance(ob, ctypeobj.W_CType): - size = ob.size + if isinstance(w_obj, cdataobj.W_CData): + size = w_obj._sizeof() + elif isinstance(w_obj, ctypeobj.W_CType): + size = w_obj.size if size < 0: raise operationerrfmt(space.w_ValueError, "ctype '%s' is of unknown size", - ob.name) + w_obj.name) else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata' or 'ctype' object")) diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -106,9 +106,8 @@ def _is_a_float(space, w_ob): from pypy.module._cffi_backend.cdataobj import W_CData from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat - ob = space.interpclass_w(w_ob) - if isinstance(ob, W_CData): - return isinstance(ob.ctype, W_CTypePrimitiveFloat) + if isinstance(w_ob, W_CData): + return isinstance(w_ob.ctype, W_CTypePrimitiveFloat) return space.isinstance_w(w_ob, space.w_float) def as_long_long(space, w_ob): @@ -243,14 +242,14 @@ from pypy.module._cffi_backend.cdataobj import W_CData from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble - ob = space.interpclass_w(w_ob) - is_cdata = isinstance(ob, W_CData) - if is_cdata and isinstance(ob.ctype, W_CTypePrimitiveFloat): - if isinstance(ob.ctype, W_CTypePrimitiveLongDouble): - result = is_nonnull_longdouble(read_raw_longdouble_data(ob._cdata)) + is_cdata = isinstance(w_ob, W_CData) + if is_cdata and isinstance(w_ob.ctype, W_CTypePrimitiveFloat): + if isinstance(w_ob.ctype, W_CTypePrimitiveLongDouble): + result = is_nonnull_longdouble( + read_raw_longdouble_data(w_ob._cdata)) else: - result = read_raw_float_data(ob._cdata, ob.ctype.size) != 0.0 - keepalive_until_here(ob) + result = read_raw_float_data(w_ob._cdata, w_ob.ctype.size) != 0.0 + keepalive_until_here(w_ob) return result # if not is_cdata and space.lookup(w_ob, '__float__') is not None: diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -305,13 +305,12 @@ from pypy.module._cffi_backend import ctypefunc fargs = [] for w_farg in space.fixedview(w_fargs): - farg = space.interpclass_w(w_farg) - if not isinstance(farg, ctypeobj.W_CType): + if not isinstance(w_farg, ctypeobj.W_CType): raise OperationError(space.w_TypeError, space.wrap("first arg must be a tuple of ctype objects")) - if isinstance(farg, ctypearray.W_CTypeArray): - farg = farg.ctptr - fargs.append(farg) + if isinstance(w_farg, ctypearray.W_CTypeArray): + w_farg = w_farg.ctptr + fargs.append(w_farg) # if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid)) or isinstance(fresult, ctypearray.W_CTypeArray)): diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -322,7 +322,7 @@ def compare(self, w_other, op): space = self.space - if not isinstance(space.interpclass_w(w_other), W_Deque): + if not isinstance(w_other, W_Deque): return space.w_NotImplemented return space.compare_by_iteration(space.wrap(self), w_other, op) compare._annspecialcase_ = 'specialize:arg(2)' diff --git a/pypy/module/_csv/interp_csv.py b/pypy/module/_csv/interp_csv.py --- a/pypy/module/_csv/interp_csv.py +++ b/pypy/module/_csv/interp_csv.py @@ -60,8 +60,7 @@ w_module = space.getbuiltinmodule('_csv') w_dialect = space.call_method(w_module, 'get_dialect', w_dialect) - dialect = space.interpclass_w(w_dialect) - if (isinstance(dialect, W_Dialect) and + if (isinstance(w_dialect, W_Dialect) and w_delimiter is None and w_doublequote is None and w_escapechar is None and @@ -70,7 +69,7 @@ w_quoting is None and w_skipinitialspace is None and w_strict is None): - return dialect + return w_dialect if w_delimiter is None: w_delimiter = _fetch(space, w_dialect, 'delimiter') diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -321,9 +321,8 @@ w = space.wrap if letter in TYPEMAP_PTR_LETTERS: # check for NULL ptr - datainstance = space.interpclass_w(w_arg) - if isinstance(datainstance, W_DataInstance): - ptr = datainstance.ll_buffer + if isinstance(w_arg, W_DataInstance): + ptr = w_arg.ll_buffer else: ptr = unwrap_truncate_int(rffi.VOIDP, space, w_arg) push_func(add_arg, argdesc, ptr) diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py --- a/pypy/module/cppyy/converter.py +++ b/pypy/module/cppyy/converter.py @@ -424,11 +424,10 @@ def _unwrap_object(self, space, w_obj): from pypy.module.cppyy.interp_cppyy import W_CPPInstance - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_CPPInstance): - if capi.c_is_subtype(obj.cppclass, self.cppclass): - rawobject = obj.get_rawobject() - offset = capi.c_base_offset(obj.cppclass, self.cppclass, rawobject, 1) + if isinstance(w_obj, W_CPPInstance): + if capi.c_is_subtype(w_obj.cppclass, self.cppclass): + rawobject = w_obj.get_rawobject() + offset = capi.c_base_offset(w_obj.cppclass, self.cppclass, rawobject, 1) obj_address = capi.direct_ptradd(rawobject, offset) return rffi.cast(capi.C_OBJECT, obj_address) raise OperationError(space.w_TypeError, @@ -498,10 +497,9 @@ def finalize_call(self, space, w_obj, call_local): from pypy.module.cppyy.interp_cppyy import W_CPPInstance - obj = space.interpclass_w(w_obj) - assert isinstance(obj, W_CPPInstance) + assert isinstance(w_obj, W_CPPInstance) r = rffi.cast(rffi.VOIDPP, call_local) - obj._rawobject = rffi.cast(capi.C_OBJECT, r[0]) + w_obj._rawobject = rffi.cast(capi.C_OBJECT, r[0]) class StdStringConverter(InstanceConverter): diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py --- a/pypy/module/cppyy/test/test_zjit.py +++ b/pypy/module/cppyy/test/test_zjit.py @@ -130,9 +130,6 @@ return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' - def interpclass_w(self, w_obj): - return w_obj - def buffer_w(self, w_obj): return FakeBuffer(w_obj) diff --git a/pypy/module/cpyext/frameobject.py b/pypy/module/cpyext/frameobject.py --- a/pypy/module/cpyext/frameobject.py +++ b/pypy/module/cpyext/frameobject.py @@ -85,5 +85,4 @@ @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyTraceBack_Check(space, w_obj): - obj = space.interpclass_w(w_obj) - return obj is not None and isinstance(obj, PyTraceback) + return isinstance(w_obj, PyTraceback) diff --git a/pypy/module/gc/referents.py b/pypy/module/gc/referents.py --- a/pypy/module/gc/referents.py +++ b/pypy/module/gc/referents.py @@ -34,9 +34,8 @@ return w_obj def unwrap(space, w_obj): - gcrefobj = space.interpclass_w(w_obj) - if isinstance(gcrefobj, W_GcRef): - gcref = gcrefobj.gcref + if isinstance(w_obj, W_GcRef): + gcref = w_obj.gcref else: gcref = rgc.cast_instance_to_gcref(w_obj) return gcref 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 @@ -992,11 +992,10 @@ w_marshal = space.getbuiltinmodule('marshal') w_code = space.call_method(w_marshal, 'loads', space.wrap(strbuf)) - pycode = space.interpclass_w(w_code) - if pycode is None or not isinstance(pycode, Code): + if not isinstance(w_code, Code): raise operationerrfmt(space.w_ImportError, "Non-code object in %s", cpathname) - return pycode + return w_code @jit.dont_look_inside def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -727,7 +727,7 @@ stream.seek(8, 0) w_code = importing.read_compiled_module( space, cpathname, stream.readall()) - pycode = space.interpclass_w(w_code) + pycode = w_code finally: stream.close() assert type(pycode) is pypy.interpreter.pycode.PyCode @@ -772,7 +772,7 @@ stream.readall()) finally: stream.close() - pycode = space.interpclass_w(w_ret) + pycode = w_ret assert type(pycode) is pypy.interpreter.pycode.PyCode w_dic = space.newdict() pycode.exec_code(space, w_dic, w_dic) @@ -911,7 +911,7 @@ stream.readall()) finally: stream.close() - pycode = space.interpclass_w(w_ret) + pycode = w_ret assert type(pycode) is pypy.interpreter.pycode.PyCode cpathname = str(udir.join('cpathname.pyc')) @@ -939,7 +939,7 @@ stream.seek(8, 0) w_code = importing.read_compiled_module(space, cpathname, stream.readall()) - pycode = space.interpclass_w(w_code) + pycode = w_code finally: stream.close() diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -823,10 +823,9 @@ if n < 0: raise OperationError(space.w_ValueError, space.wrap("n must be >= 0")) - myiter = space.interpclass_w(w_iterable) - if isinstance(myiter, W_TeeIterable): # optimization only - chained_list = myiter.chained_list - w_iterator = myiter.w_iterator + if isinstance(w_iterable, W_TeeIterable): # optimization only + chained_list = w_iterable.chained_list + w_iterator = w_iterable.w_iterator iterators_w = [w_iterable] * n for i in range(1, n): iterators_w[i] = space.wrap(W_TeeIterable(space, w_iterator, diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py --- a/pypy/module/marshal/interp_marshal.py +++ b/pypy/module/marshal/interp_marshal.py @@ -11,9 +11,8 @@ def dump(space, w_data, w_f, w_version): """Write the 'data' object into the open file 'f'.""" # special case real files for performance - file = space.interpclass_w(w_f) - if isinstance(file, W_File): - writer = DirectStreamWriter(space, file) + if isinstance(w_f, W_File): + writer = DirectStreamWriter(space, w_f) else: writer = FileWriter(space, w_f) try: @@ -36,9 +35,8 @@ def load(space, w_f): """Read one value from the file 'f' and return it.""" # special case real files for performance - file = space.interpclass_w(w_f) - if isinstance(file, W_File): - reader = DirectStreamReader(space, file) + if isinstance(w_f, W_File): + reader = DirectStreamReader(space, w_f) else: reader = FileReader(space, w_f) try: diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -129,17 +129,15 @@ return space.lookup(w_obj, '__set__') is not None def get_and_call_args(space, w_descr, w_obj, args): - descr = space.interpclass_w(w_descr) # a special case for performance and to avoid infinite recursion - if isinstance(descr, Function): - return descr.call_obj_args(w_obj, args) + if isinstance(w_descr, Function): + return w_descr.call_obj_args(w_obj, args) else: w_impl = space.get(w_descr, w_obj) return space.call_args(w_impl, args) def get_and_call_function(space, w_descr, w_obj, *args_w): - descr = space.interpclass_w(w_descr) - typ = type(descr) + typ = type(w_descr) # a special case for performance and to avoid infinite recursion if typ is Function or typ is FunctionWithFixedCode: # isinstance(typ, Function) would not be correct here: @@ -150,7 +148,7 @@ # the fastcall paths are purely for performance, but the resulting # increase of speed is huge - return descr.funccall(w_obj, *args_w) + return w_descr.funccall(w_obj, *args_w) else: args = Arguments(space, list(args_w)) w_impl = space.get(w_descr, w_obj) 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 @@ -867,9 +867,8 @@ # we have a data descriptor, which means the dictionary value # (if any) has no relevance. from pypy.interpreter.typedef import Member - descr = space.interpclass_w(w_descr) - if isinstance(descr, Member): # it is a slot -- easy case - selector = ("slot", SLOTS_STARTING_FROM + descr.index) + if isinstance(w_descr, Member): # it is a slot -- easy case + selector = ("slot", SLOTS_STARTING_FROM + w_descr.index) else: # There is a non-data descriptor in the class. If there is # also a dict attribute, use the latter, caching its position. diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -256,11 +256,11 @@ def unwrap(self, w_obj): """NOT_RPYTHON""" - if isinstance(w_obj, Wrappable): - return w_obj if isinstance(w_obj, model.W_Object): return w_obj.unwrap(self) - raise model.UnwrapError, "cannot unwrap: %r" % w_obj + if isinstance(w_obj, W_Root): + return w_obj + raise model.UnwrapError("cannot unwrap: %r" % w_obj) def newint(self, intval): return wrapint(self, intval) diff --git a/pypy/tool/traceconfig.py b/pypy/tool/traceconfig.py --- a/pypy/tool/traceconfig.py +++ b/pypy/tool/traceconfig.py @@ -10,7 +10,7 @@ operations[name] = name # Remove list - for name in ["wrap", "unwrap", "interpclass_w"]: + for name in ["wrap", "unwrap"]: if name in operations: del operations[name] From noreply at buildbot.pypy.org Wed Mar 20 23:19:01 2013 From: noreply at buildbot.pypy.org (Jason Chu) Date: Wed, 20 Mar 2013 23:19:01 +0100 (CET) Subject: [pypy-commit] pypy py3k-subprocess-new-session: Set HAVE_SETSID if we have setsid so we can create new sessions in subprocesses Message-ID: <20130320221901.5F12C1C03A7@cobra.cs.uni-duesseldorf.de> Author: Jason Chu Branch: py3k-subprocess-new-session Changeset: r62583:4ce57b37d051 Date: 2013-03-20 15:12 -0700 http://bitbucket.org/pypy/pypy/changeset/4ce57b37d051/ Log: Set HAVE_SETSID if we have setsid so we can create new sessions in subprocesses diff --git a/pypy/module/_posixsubprocess/interp_subprocess.py b/pypy/module/_posixsubprocess/interp_subprocess.py --- a/pypy/module/_posixsubprocess/interp_subprocess.py +++ b/pypy/module/_posixsubprocess/interp_subprocess.py @@ -14,6 +14,7 @@ _compilation_info_ = ExternalCompilationInfo( includes=['unistd.h', 'sys/syscall.h']) HAVE_SYS_SYSCALL_H = platform.Has("syscall") + HAVE_SETSID = platform.Has("setsid") config = platform.configure(CConfig) @@ -24,10 +25,15 @@ 'pypy_subprocess_init', ]) +compile_extra = [] if config['HAVE_SYS_SYSCALL_H']: - eci = eci.merge( - ExternalCompilationInfo( - compile_extra=["-DHAVE_SYS_SYSCALL_H"])) + compile_extra.append("-DHAVE_SYS_SYSCALL_H") +if config['HAVE_SETSID']: + compile_extra.append("-DHAVE_SETSID") + +eci = eci.merge( + ExternalCompilationInfo( + compile_extra=compile_extra)) c_child_exec = rffi.llexternal( 'pypy_subprocess_child_exec', diff --git a/pypy/module/_posixsubprocess/test/test_subprocess.py b/pypy/module/_posixsubprocess/test/test_subprocess.py --- a/pypy/module/_posixsubprocess/test/test_subprocess.py +++ b/pypy/module/_posixsubprocess/test/test_subprocess.py @@ -38,3 +38,22 @@ assert not (remaining_fds & open_fds), "Some fds were left open" assert 1 in remaining_fds, "Subprocess failed" + + def test_start_new_session(self): + # For code coverage of calling setsid(). We don't care if we get an + # EPERM error from it depending on the test execution environment, that + # still indicates that it was called. + import subprocess + import os + try: + output = subprocess.check_output( + ['/usr/bin/env', 'python', "-c", + "import os; print(os.getpgid(os.getpid()))"], + start_new_session=True) + except OSError as e: + if e.errno != errno.EPERM: + raise + else: + parent_pgid = os.getpgid(os.getpid()) + child_pgid = int(output) + assert parent_pgid != child_pgid From noreply at buildbot.pypy.org Wed Mar 20 23:19:02 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Mar 2013 23:19:02 +0100 (CET) Subject: [pypy-commit] pypy py3k: Merged in xentac/pypy/py3k-subprocess-new-session (pull request #143) Message-ID: <20130320221902.A22B01C04AB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62584:27b08f6ff879 Date: 2013-03-20 15:18 -0700 http://bitbucket.org/pypy/pypy/changeset/27b08f6ff879/ Log: Merged in xentac/pypy/py3k-subprocess-new-session (pull request #143) Set HAVE_SETSID if we have setsid so we can create new sessions in subprocesses diff --git a/pypy/module/_posixsubprocess/interp_subprocess.py b/pypy/module/_posixsubprocess/interp_subprocess.py --- a/pypy/module/_posixsubprocess/interp_subprocess.py +++ b/pypy/module/_posixsubprocess/interp_subprocess.py @@ -14,6 +14,7 @@ _compilation_info_ = ExternalCompilationInfo( includes=['unistd.h', 'sys/syscall.h']) HAVE_SYS_SYSCALL_H = platform.Has("syscall") + HAVE_SETSID = platform.Has("setsid") config = platform.configure(CConfig) @@ -24,10 +25,15 @@ 'pypy_subprocess_init', ]) +compile_extra = [] if config['HAVE_SYS_SYSCALL_H']: - eci = eci.merge( - ExternalCompilationInfo( - compile_extra=["-DHAVE_SYS_SYSCALL_H"])) + compile_extra.append("-DHAVE_SYS_SYSCALL_H") +if config['HAVE_SETSID']: + compile_extra.append("-DHAVE_SETSID") + +eci = eci.merge( + ExternalCompilationInfo( + compile_extra=compile_extra)) c_child_exec = rffi.llexternal( 'pypy_subprocess_child_exec', diff --git a/pypy/module/_posixsubprocess/test/test_subprocess.py b/pypy/module/_posixsubprocess/test/test_subprocess.py --- a/pypy/module/_posixsubprocess/test/test_subprocess.py +++ b/pypy/module/_posixsubprocess/test/test_subprocess.py @@ -38,3 +38,22 @@ assert not (remaining_fds & open_fds), "Some fds were left open" assert 1 in remaining_fds, "Subprocess failed" + + def test_start_new_session(self): + # For code coverage of calling setsid(). We don't care if we get an + # EPERM error from it depending on the test execution environment, that + # still indicates that it was called. + import subprocess + import os + try: + output = subprocess.check_output( + ['/usr/bin/env', 'python', "-c", + "import os; print(os.getpgid(os.getpid()))"], + start_new_session=True) + except OSError as e: + if e.errno != errno.EPERM: + raise + else: + parent_pgid = os.getpgid(os.getpid()) + child_pgid = int(output) + assert parent_pgid != child_pgid From noreply at buildbot.pypy.org Wed Mar 20 23:51:53 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 23:51:53 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: improved "const" removal Message-ID: <20130320225153.6B74B1C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62585:94948aa3cb9c Date: 2013-03-20 14:39 -0700 http://bitbucket.org/pypy/pypy/changeset/94948aa3cb9c/ Log: improved "const" removal diff --git a/pypy/module/cppyy/helper.py b/pypy/module/cppyy/helper.py --- a/pypy/module/cppyy/helper.py +++ b/pypy/module/cppyy/helper.py @@ -2,26 +2,26 @@ #- type name manipulations -------------------------------------------------- -def _remove_const(name): +def remove_const(name): tmplt_start = name.find("<") - if 0 <= tmplt_start: - # only replace const within the class name, not in the template parameters - return "".join(rstring.split(name[:tmplt_start], "const"))+name[tmplt_start:] + tmplt_stop = name.rfind(">") + if 0 <= tmplt_start and 0 <= tmplt_stop: + # only replace const qualifying the class name, not in the template parameters + return "".join([x.strip(" ") for x in rstring.split(name[:tmplt_start], "const")])+\ + name[tmplt_start:tmplt_stop]+\ + "".join([x.strip(" ") for x in rstring.split(name[tmplt_stop:], "const")]) else: - return "".join(rstring.split(name, "const")) - -def remove_const(name): - return _remove_const(name).strip(' ') + return "".join([x.strip(" ") for x in rstring.split(name, "const")]) def compound(name): - name = _remove_const(name) + name = remove_const(name) if name.endswith("]"): # array type? return "[]" i = _find_qualifier_index(name) return "".join(name[i:].split(" ")) def array_size(name): - name = _remove_const(name) + name = remove_const(name) if name.endswith("]"): # array type? idx = name.rfind("[") if 0 < idx: @@ -42,7 +42,7 @@ def clean_type(name): # can't strip const early b/c name could be a template ... i = _find_qualifier_index(name) - name = name[:i].strip(' ') + name = name[:i].strip(" ") idx = -1 if name.endswith("]"): # array type? @@ -52,10 +52,10 @@ elif name.endswith(">"): # template type? idx = name.find("<") if 0 < idx: # always true, but just so that the translater knows - n1 = _remove_const(name[:idx]) + n1 = remove_const(name[:idx]) name = "".join([n1, name[idx:]]) else: - name = _remove_const(name) + name = remove_const(name) name = name[:_find_qualifier_index(name)] return name.strip(' ') diff --git a/pypy/module/cppyy/test/test_helper.py b/pypy/module/cppyy/test/test_helper.py --- a/pypy/module/cppyy/test/test_helper.py +++ b/pypy/module/cppyy/test/test_helper.py @@ -3,6 +3,14 @@ def test_remove_const(): assert helper.remove_const("const int") == "int" + assert helper.remove_const("const some_class*") == "some_class*" + assert helper.remove_const("const some_class const*") == "some_class*" + assert helper.remove_const("some_class const*const") == "some_class*" + + assert helper.remove_const("const some_class*") == "some_class*" + assert helper.remove_const("const some_class const*") == "some_class*" + assert helper.remove_const("some_class const*const") == "some_class*" + def test_compound(): assert helper.compound("int*") == "*" assert helper.compound("int* const *&") == "**&" From noreply at buildbot.pypy.org Wed Mar 20 23:51:54 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 23:51:54 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: several ROOT-based tests; added to test_cint.py for completeness Message-ID: <20130320225154.AFAF21C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62586:e13d241eae72 Date: 2013-03-20 14:39 -0700 http://bitbucket.org/pypy/pypy/changeset/e13d241eae72/ Log: several ROOT-based tests; added to test_cint.py for completeness diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py --- a/pypy/module/cppyy/test/test_cint.py +++ b/pypy/module/cppyy/test/test_cint.py @@ -95,7 +95,7 @@ assert c.get_data() == 13 -class AppTestCINTPythonizations: +class AppTestCINTPYTHONIZATIONS: spaceconfig = dict(usemodules=['cppyy']) def test01_strings(self): @@ -138,7 +138,7 @@ assert round(v[int(math.sqrt(j)+0.5)]-j, 5) == 0. -class AppTestCINTTTree: +class AppTestCINTTTREE: spaceconfig = dict(usemodules=['cppyy', 'array', '_rawffi', '_cffi_backend']) def setup_class(cls): @@ -384,9 +384,12 @@ assert mytree.my_int2 == i+1 -class AppTestRegression: +class AppTestCINTREGRESSION: spaceconfig = dict(usemodules=['cppyy']) + # these are tests that at some point in the past resulted in failures on + # PyROOT; kept here to confirm no regression from PyROOT + def test01_regression(self): """TPaveText::AddText() used to result in KeyError""" @@ -399,3 +402,71 @@ hello = TPaveText( .1, .8, .9, .97 ) hello.AddText( 'Hello, World!' ) + + +class AppTestSURPLUS: + spaceconfig = dict(usemodules=['cppyy']) + + # these are tests that were historically exercised on ROOT classes and + # have twins on custom classes; kept here just in case differences crop + # up between the ROOT classes and the custom ones + + def test01_class_enum(self): + """Test class enum access and values""" + + import cppyy + TObject = cppyy.gbl.TObject + gROOT = cppyy.gbl.gROOT + + assert TObject.kBitMask == gROOT.ProcessLine("return TObject::kBitMask;") + assert TObject.kIsOnHeap == gROOT.ProcessLine("return TObject::kIsOnHeap;") + assert TObject.kNotDeleted == gROOT.ProcessLine("return TObject::kNotDeleted;") + assert TObject.kZombie == gROOT.ProcessLine("return TObject::kZombie;") + + t = TObject() + + assert TObject.kBitMask == t.kBitMask + assert TObject.kIsOnHeap == t.kIsOnHeap + assert TObject.kNotDeleted == t.kNotDeleted + assert TObject.kZombie == t.kZombie + + def test02_global_enum(self): + """Test global enums access and values""" + + import cppyy + from cppyy import gbl + + assert gbl.kRed == gbl.gROOT.ProcessLine("return kRed;") + assert gbl.kGreen == gbl.gROOT.ProcessLine("return kGreen;") + assert gbl.kBlue == gbl.gROOT.ProcessLine("return kBlue;") + + def test03_copy_contructor(self): + """Test copy constructor""" + + import cppyy + TLorentzVector = cppyy.gbl.TLorentzVector + + t1 = TLorentzVector(1., 2., 3., -4.) + t2 = TLorentzVector(0., 0., 0., 0.) + t3 = TLorentzVector(t1) + + assert t1 == t3 + assert t1 != t2 + + for i in range(4): + assert t1[i] == t3[i] + + def test04_object_validity(self): + """Test object validity checking""" + + import cppyy + + t1 = cppyy.gbl.TObject() + + assert t1 + assert not not t1 + + t2 = cppyy.gbl.gROOT.FindObject("Nah, I don't exist") + + assert not t2 + From noreply at buildbot.pypy.org Wed Mar 20 23:51:55 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 23:51:55 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: tests for global enums Message-ID: <20130320225155.DFE531C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62587:582b2ae42222 Date: 2013-03-20 14:48 -0700 http://bitbucket.org/pypy/pypy/changeset/582b2ae42222/ Log: tests for global enums diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h --- a/pypy/module/cppyy/test/datatypes.h +++ b/pypy/module/cppyy/test/datatypes.h @@ -9,6 +9,9 @@ //=========================================================================== +enum fruit { kApple=78, kBanana=29, kCitrus=34 }; + +//=========================================================================== class cppyy_test_data { public: cppyy_test_data(); diff --git a/pypy/module/cppyy/test/datatypes.xml b/pypy/module/cppyy/test/datatypes.xml --- a/pypy/module/cppyy/test/datatypes.xml +++ b/pypy/module/cppyy/test/datatypes.xml @@ -2,6 +2,8 @@ + + diff --git a/pypy/module/cppyy/test/datatypes_LinkDef.h b/pypy/module/cppyy/test/datatypes_LinkDef.h --- a/pypy/module/cppyy/test/datatypes_LinkDef.h +++ b/pypy/module/cppyy/test/datatypes_LinkDef.h @@ -7,6 +7,8 @@ #pragma link C++ struct cppyy_test_pod; #pragma link C++ class cppyy_test_data; +#pragma link C++ enum fruit; + #pragma link C++ function get_pod_address(cppyy_test_data&); #pragma link C++ function get_int_address(cppyy_test_data&); #pragma link C++ function get_double_address(cppyy_test_data&); diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py --- a/pypy/module/cppyy/test/test_datatypes.py +++ b/pypy/module/cppyy/test/test_datatypes.py @@ -454,6 +454,11 @@ assert c.s_enum == cppyy_test_data.kSomething assert cppyy_test_data.s_enum == cppyy_test_data.kSomething + # global enums + assert gbl.kApple == 78 + assert gbl.kBanana == 29 + assert gbl.kCitrus == 34 + def test12_object_returns(self): """Test access to and return of PODs""" From noreply at buildbot.pypy.org Wed Mar 20 23:51:57 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 23:51:57 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: copy constructor test Message-ID: <20130320225157.1E2621C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62588:f59f2e75c584 Date: 2013-03-20 14:59 -0700 http://bitbucket.org/pypy/pypy/changeset/f59f2e75c584/ Log: copy constructor test diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h --- a/pypy/module/cppyy/test/datatypes.h +++ b/pypy/module/cppyy/test/datatypes.h @@ -11,6 +11,36 @@ //=========================================================================== enum fruit { kApple=78, kBanana=29, kCitrus=34 }; + +//=========================================================================== +class four_vector { +public: + four_vector(double x, double y, double z, double t) : + m_x(x), m_y(y), m_z(z), m_t(t), m_cc_called(false) {} + four_vector(const four_vector& s) : + m_x(s.m_x), m_y(s.m_y), m_z(s.m_z), m_t(s.m_t), m_cc_called(true) {} + + double operator[](int i) { + if (i == 0) return m_x; + if (i == 1) return m_y; + if (i == 2) return m_z; + if (i == 3) return m_t; + return -1; + } + + bool operator==(const four_vector& o) { + return (m_x == o.m_x && m_y == o.m_y && + m_z == o.m_z && m_t == o.m_t); + } + +public: + bool m_cc_called; + +private: + double m_x, m_y, m_z, m_t; +}; + + //=========================================================================== class cppyy_test_data { public: diff --git a/pypy/module/cppyy/test/datatypes.xml b/pypy/module/cppyy/test/datatypes.xml --- a/pypy/module/cppyy/test/datatypes.xml +++ b/pypy/module/cppyy/test/datatypes.xml @@ -1,6 +1,7 @@ + diff --git a/pypy/module/cppyy/test/datatypes_LinkDef.h b/pypy/module/cppyy/test/datatypes_LinkDef.h --- a/pypy/module/cppyy/test/datatypes_LinkDef.h +++ b/pypy/module/cppyy/test/datatypes_LinkDef.h @@ -6,6 +6,7 @@ #pragma link C++ struct cppyy_test_pod; #pragma link C++ class cppyy_test_data; +#pragma link C++ class four_vector; #pragma link C++ enum fruit; diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py --- a/pypy/module/cppyy/test/test_datatypes.py +++ b/pypy/module/cppyy/test/test_datatypes.py @@ -459,7 +459,23 @@ assert gbl.kBanana == 29 assert gbl.kCitrus == 34 - def test12_object_returns(self): + def test12_copy_contructor(self): + """Test copy constructor""" + + import cppyy + four_vector = cppyy.gbl.four_vector + + t1 = four_vector(1., 2., 3., -4.) + t2 = four_vector(0., 0., 0., 0.) + t3 = four_vector(t1) + + assert t1 == t3 + assert t1 != t2 + + for i in range(4): + assert t1[i] == t3[i] + + def test13_object_returns(self): """Test access to and return of PODs""" import cppyy @@ -486,7 +502,7 @@ assert c.get_pod_ptrref().m_int == 666 assert c.get_pod_ptrref().m_double == 3.14 - def test13_object_arguments(self): + def test14_object_arguments(self): """Test setting and returning of a POD through arguments""" import cppyy @@ -554,7 +570,7 @@ assert p.m_int == 888 assert p.m_double == 3.14 - def test14_respect_privacy(self): + def test15_respect_privacy(self): """Test that privacy settings are respected""" import cppyy @@ -567,7 +583,7 @@ c.destruct() - def test15_buffer_reshaping(self): + def test16_buffer_reshaping(self): """Test usage of buffer sizing""" import cppyy From noreply at buildbot.pypy.org Wed Mar 20 23:51:58 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 23:51:58 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: object validity behavior tests Message-ID: <20130320225158.591F01C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62589:381e15c68488 Date: 2013-03-20 15:23 -0700 http://bitbucket.org/pypy/pypy/changeset/381e15c68488/ Log: object validity behavior tests diff --git a/pypy/module/cppyy/test/datatypes.cxx b/pypy/module/cppyy/test/datatypes.cxx --- a/pypy/module/cppyy/test/datatypes.cxx +++ b/pypy/module/cppyy/test/datatypes.cxx @@ -224,3 +224,7 @@ cppyy_test_pod* get_global_pod() { return g_pod; } + +cppyy_test_pod* get_null_pod() { + return (cppyy_test_pod*)0; +} diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h --- a/pypy/module/cppyy/test/datatypes.h +++ b/pypy/module/cppyy/test/datatypes.h @@ -225,3 +225,4 @@ bool is_global_pod(cppyy_test_pod* t); void set_global_pod(cppyy_test_pod* t); cppyy_test_pod* get_global_pod(); +cppyy_test_pod* get_null_pod(); diff --git a/pypy/module/cppyy/test/datatypes_LinkDef.h b/pypy/module/cppyy/test/datatypes_LinkDef.h --- a/pypy/module/cppyy/test/datatypes_LinkDef.h +++ b/pypy/module/cppyy/test/datatypes_LinkDef.h @@ -19,6 +19,7 @@ #pragma link C++ function is_global_pod(cppyy_test_pod*); #pragma link C++ function set_global_pod(cppyy_test_pod*); #pragma link C++ function get_global_pod(); +#pragma link C++ function get_null_pod(); #pragma link C++ global N; #pragma link C++ global g_int; diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py --- a/pypy/module/cppyy/test/test_datatypes.py +++ b/pypy/module/cppyy/test/test_datatypes.py @@ -583,7 +583,21 @@ c.destruct() - def test16_buffer_reshaping(self): + def test16_object_validity(self): + """Test object validity checking""" + + from cppyy import gbl + + d = gbl.cppyy_test_pod() + + assert d + assert not not d + + d2 = gbl.get_null_pod() + + assert not d2 + + def test17_buffer_reshaping(self): """Test usage of buffer sizing""" import cppyy From noreply at buildbot.pypy.org Wed Mar 20 23:51:59 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 20 Mar 2013 23:51:59 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: add a few more ROOT-based tests for completeness Message-ID: <20130320225159.A1CAD1C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62590:bae554d4296a Date: 2013-03-20 15:50 -0700 http://bitbucket.org/pypy/pypy/changeset/bae554d4296a/ Log: add a few more ROOT-based tests for completeness diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py --- a/pypy/module/cppyy/test/test_cint.py +++ b/pypy/module/cppyy/test/test_cint.py @@ -470,3 +470,40 @@ assert not t2 + def test05_element_access(self): + """Test access to elements in matrix and array objects.""" + + from cppyy import gbl + + N = 3 + v = gbl.TVectorF(N) + m = gbl.TMatrixD(N, N) + + for i in range(N): + assert v[i] == 0.0 + + for j in range(N): + assert m[i][j] == 0.0 + + def test06_static_function_call( self ): + """Test call to static function.""" + + import cppyy + TROOT, gROOT = cppyy.gbl.TROOT, cppyy.gbl.gROOT + + c1 = TROOT.Class() + assert not not c1 + + c2 = gROOT.Class() + + assert c1 == c2 + + old = gROOT.GetDirLevel() + TROOT.SetDirLevel(2) + assert 2 == gROOT.GetDirLevel() + gROOT.SetDirLevel(old) + + old = TROOT.GetDirLevel() + gROOT.SetDirLevel(3) + assert 3 == TROOT.GetDirLevel() + TROOT.SetDirLevel(old) From noreply at buildbot.pypy.org Wed Mar 20 23:56:53 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 23:56:53 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: general progress removing Wrappable, stuff is a bit broken Message-ID: <20130320225653.5436F1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: remove-list-smm Changeset: r62591:4f75442b1bcf Date: 2013-03-20 15:39 -0700 http://bitbucket.org/pypy/pypy/changeset/4f75442b1bcf/ Log: general progress removing Wrappable, stuff is a bit broken diff too long, truncating to 2000 out of 2161 lines diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -538,7 +538,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -555,7 +555,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -621,7 +621,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -15,7 +15,7 @@ from rpython.rlib.rarithmetic import r_uint -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) @@ -220,11 +220,6 @@ return self -# ---------- backward compatibility: these classes are the same now ---------- -Wrappable = W_Root -# ---------------------------------------------------------------------------- - - class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -726,7 +721,7 @@ def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -144,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -208,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -3,10 +3,10 @@ Code and Frame. """ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root -class Code(Wrappable): +class Code(W_Root): """A code is a compiled version of some source code. Abstract base class.""" _immutable_ = True @@ -52,19 +52,20 @@ def funcrun_obj(self, func, w_obj, args): return self.funcrun(func, args.prepend(w_obj)) -class Frame(Wrappable): + +class Frame(W_Root): """A frame is an environment supporting the execution of a code object. Abstract base class.""" def __init__(self, space, w_globals=None): - self.space = space - self.w_globals = w_globals # wrapped dict of globals - self.w_locals = None # wrapped dict of locals + self.space = space + self.w_globals = w_globals # wrapped dict of globals + self.w_locals = None # wrapped dict of locals def run(self): "Abstract method to override. Runs the frame" - raise TypeError, "abstract" - + raise TypeError("abstract") + def getdictscope(self): "Get the locals as a dictionary." self.fast2locals() @@ -86,16 +87,16 @@ def getfastscope(self): "Abstract. Get the fast locals as a list." - raise TypeError, "abstract" + raise TypeError("abstract") def setfastscope(self, scope_w): """Abstract. Initialize the fast locals from a list of values, where the order is according to self.getcode().signature().""" - raise TypeError, "abstract" + raise TypeError("abstract") def getfastscopelength(self): "Abstract. Get the expected number of locals." - raise TypeError, "abstract" + raise TypeError("abstract") def fast2locals(self): # Copy values from the fastlocals to self.w_locals diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -8,21 +8,22 @@ from rpython.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized + funccallunrolling = unrolling_iterable(range(4)) + @jit.elidable_promote() def _get_immutable_code(func): assert not func.can_change_code return func.code -class Function(Wrappable): +class Function(W_Root): """A function is a code object captured with some environment: an object space, a dictionary of globals, default arguments, and an arbitrary 'closure' passed to the code object.""" @@ -41,7 +42,7 @@ self.w_doc = None # lazily read from code.getdocstring() self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary - self.closure = closure # normally, list of Cell instances or None + self.closure = closure # normally, list of Cell instances or None self.defs_w = defs_w self.w_func_dict = None # filled out below if needed self.w_module = None @@ -240,7 +241,6 @@ def descr_function_repr(self): return self.getrepr(self.space, 'function %s' % (self.name,)) - # delicate _all = {'': None} @@ -267,8 +267,8 @@ def descr_function__reduce__(self, space): from pypy.interpreter.gateway import BuiltinCode from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) code = self.code if isinstance(code, BuiltinCode): new_inst = mod.get('builtin_function') @@ -276,7 +276,7 @@ space.newtuple([space.wrap(code.identifier)])]) new_inst = mod.get('func_new') - w = space.wrap + w = space.wrap if self.closure is None: w_closure = space.w_None else: @@ -309,7 +309,6 @@ return nt([new_inst, nt(tup_base), nt(tup_state)]) def descr_function__setstate__(self, space, w_args): - from pypy.interpreter.pycode import PyCode args_w = space.unpackiterable(w_args) try: (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs, @@ -354,7 +353,7 @@ self.defs_w = [] return if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): - raise OperationError( space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None") ) + raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) def fdel_func_defaults(self, space): @@ -381,7 +380,6 @@ "to a string object")) raise - def fdel_func_doc(self, space): self.w_doc = space.w_None @@ -420,7 +418,7 @@ def fget_func_closure(self, space): if self.closure is not None: - w_res = space.newtuple( [ space.wrap(i) for i in self.closure ] ) + w_res = space.newtuple([space.wrap(i) for i in self.closure]) else: w_res = space.w_None return w_res @@ -439,7 +437,7 @@ return space.wrap(Method(space, w_function, None, w_cls)) -class Method(Wrappable): +class Method(W_Root): """A method is a function bound to a specific instance or class.""" _immutable_fields_ = ['w_function', 'w_instance', 'w_class'] @@ -585,13 +583,14 @@ tup = [self.w_class, space.wrap(w_function.name)] else: tup = [w_instance, space.wrap(w_function.name)] - elif space.is_w( self.w_class, space.w_None ): + elif space.is_w(self.w_class, space.w_None): tup = [self.w_function, w_instance] else: tup = [self.w_function, w_instance, self.w_class] return space.newtuple([new_inst, space.newtuple(tup)]) -class StaticMethod(Wrappable): + +class StaticMethod(W_Root): """The staticmethod objects.""" _immutable_fields_ = ['w_function'] @@ -607,7 +606,8 @@ instance.__init__(w_function) return space.wrap(instance) -class ClassMethod(Wrappable): + +class ClassMethod(W_Root): """The classmethod objects.""" _immutable_fields_ = ['w_function'] diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -16,8 +16,8 @@ from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from pypy.interpreter.signature import Signature -from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, - SpaceCache, DescrMismatch) +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, SpaceCache, + DescrMismatch) from pypy.interpreter.error import OperationError from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from rpython.rlib import rstackovf @@ -53,7 +53,7 @@ class UnwrapSpecRecipe(object): "NOT_RPYTHON" - bases_order = [Wrappable, W_Root, ObjSpace, Arguments, object] + bases_order = [W_Root, ObjSpace, Arguments, object] def dispatch(self, el, *args): if isinstance(el, str): @@ -111,7 +111,7 @@ self.orig_arg = iter(original_sig.argnames).next def visit_self(self, cls, app_sig): - self.visit__Wrappable(cls, app_sig) + self.visit__W_Root(cls, app_sig) def checked_space_method(self, typname, app_sig): argname = self.orig_arg() @@ -147,14 +147,6 @@ def visit_truncatedint_w(self, el, app_sig): self.checked_space_method(el, app_sig) - def visit__Wrappable(self, el, app_sig): - name = el.__name__ - argname = self.orig_arg() - assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (name, argname, self.func)) - app_sig.append(argname) - def visit__ObjSpace(self, el, app_sig): self.orig_arg() @@ -216,10 +208,6 @@ self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) - def visit__Wrappable(self, typ): - self.run_args.append("space.interp_w(%s, %s)" % (self.use(typ), - self.scopenext())) - def visit__ObjSpace(self, el): self.run_args.append('space') @@ -353,10 +341,6 @@ self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) - def visit__Wrappable(self, typ): - self.unwrap.append("space.interp_w(%s, %s)" % (self.use(typ), - self.nextarg())) - def visit__ObjSpace(self, el): if self.finger != 0: raise FastFuncNotSupported @@ -541,7 +525,6 @@ # It is a list of types or singleton objects: # baseobjspace.ObjSpace is used to specify the space argument # baseobjspace.W_Root is for wrapped arguments to keep wrapped - # baseobjspace.Wrappable subclasses imply interp_w and a typecheck # argument.Arguments is for a final rest arguments Arguments object # 'args_w' for fixedview applied to rest arguments # 'w_args' for rest arguments passed as wrapped tuple @@ -560,7 +543,7 @@ assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: - assert issubclass(self_type, Wrappable) + assert issubclass(self_type, W_Root) unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type @@ -805,7 +788,7 @@ return w_result -class interp2app(Wrappable): +class interp2app(W_Root): """Build a gateway that calls 'f' at interp-level.""" # Takes optionally an unwrap_spec, see BuiltinCode @@ -838,7 +821,7 @@ result = cls.instancecache[key] assert result.__class__ is cls return result - self = Wrappable.__new__(cls) + self = W_Root.__new__(cls) cls.instancecache[key] = self self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, self_type=self_type, diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -1,10 +1,10 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.pyopcode import LoopBlock from rpython.rlib import jit -class GeneratorIterator(Wrappable): +class GeneratorIterator(W_Root): "An iterator created by a generator." _immutable_fields_ = ['pycode'] @@ -94,7 +94,6 @@ w_val = self.space.w_None return self.throw(w_type, w_val, w_tb) - def throw(self, w_type, w_val, w_tb): from pypy.interpreter.pytraceback import check_traceback space = self.space @@ -164,6 +163,7 @@ jitdriver = jit.JitDriver(greens=['pycode'], reds=['self', 'frame', 'results'], name='unpack_into') + def unpack_into(self, results): """This is a hack for performance: runs the generator and collects all produced items in a list.""" diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -2,11 +2,12 @@ Module objects. """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import we_are_translated -class Module(Wrappable): + +class Module(W_Root): """A module.""" _immutable_fields_ = ["w_dict?"] diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -3,12 +3,12 @@ from pypy.interpreter import function, pycode, pyframe from pypy.interpreter.astcompiler import consts -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.mixedmodule import MixedModule -class Cell(Wrappable): +class Cell(W_Root): "A simple container for a wrapped value." def __init__(self, w_value=None): diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -6,7 +6,7 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import gateway, function, eval, pyframe, pytraceback from pypy.interpreter.pycode import PyCode, BytecodeCorruption from rpython.tool.sourcetools import func_with_new_name @@ -1141,11 +1141,15 @@ class ExitFrame(Exception): pass + class Return(ExitFrame): """Raised when exiting a frame via a 'return' statement.""" + + class Yield(ExitFrame): """Raised when exiting a frame via a 'yield' statement.""" + class RaiseWithExplicitTraceback(Exception): """Raised at interp-level by a 0- or 3-arguments 'raise' statement.""" def __init__(self, operr): @@ -1154,7 +1158,7 @@ ### Frame Blocks ### -class SuspendedUnroller(Wrappable): +class SuspendedUnroller(W_Root): """Abstract base class for interpreter-level objects that instruct the interpreter to change the control flow and the block stack. diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -4,7 +4,7 @@ from rpython.tool.error import offset2lineno -class PyTraceback(baseobjspace.Wrappable): +class PyTraceback(baseobjspace.W_Root): """Traceback object Public app-level fields: @@ -38,7 +38,7 @@ w(self.frame), w(self.lasti), w(self.next), - ] + ] nt = space.newtuple return nt([new_inst, nt(tup_base), nt(tup_state)]) diff --git a/pypy/interpreter/special.py b/pypy/interpreter/special.py --- a/pypy/interpreter/special.py +++ b/pypy/interpreter/special.py @@ -1,15 +1,17 @@ +from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.baseobjspace import Wrappable -class Ellipsis(Wrappable): +class Ellipsis(W_Root): def __init__(self, space): - self.space = space + self.space = space + def descr__repr__(self): return self.space.wrap('Ellipsis') -class NotImplemented(Wrappable): + +class NotImplemented(W_Root): def __init__(self, space): - self.space = space + self.space = space + def descr__repr__(self): return self.space.wrap('NotImplemented') - diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,7 +1,7 @@ import py from pypy.interpreter.argument import Arguments -from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch +from pypy.interpreter.baseobjspace import W_Root, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, WrappedDefault) @@ -381,7 +381,7 @@ """ else: cls_name = cls.__name__ - assert issubclass(cls, Wrappable) + assert issubclass(cls, W_Root) source = """ def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s): obj = space.descr_self_interp_w(%(cls_name)s, w_obj) @@ -439,7 +439,7 @@ res = miniglobals['objclass_getter'], cls return res -class GetSetProperty(Wrappable): +class GetSetProperty(W_Root): _immutable_fields_ = ["fget", "fset", "fdel"] @specialize.arg(7) @@ -542,7 +542,7 @@ GetSetProperty.typedef.acceptable_as_base_class = False -class Member(Wrappable): +class Member(W_Root): """For slots.""" _immutable_ = True @@ -677,7 +677,7 @@ weakref_descr.name = '__weakref__' def make_weakref_descr(cls): - """Make instances of the Wrappable subclass 'cls' weakrefable. + """Make instances of the W_Root subclass 'cls' weakrefable. This returns the '__weakref__' desctriptor to use for the TypeDef. Note that if the class also defines a custom '__del__', the __del__ should call self.clear_all_weakrefs() before it clears @@ -686,10 +686,13 @@ # force the interface into the given cls def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None + cls._lifeline_ = None cls.getweakref = getweakref cls.setweakref = setweakref diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault @@ -6,7 +6,8 @@ generic_new_descr) from pypy.objspace.descroperation import object_getattribute -class W_Super(Wrappable): + +class W_Super(W_Root): def __init__(self, space, w_starttype, w_objtype, w_self): self.w_starttype = w_starttype self.w_objtype = w_objtype @@ -91,7 +92,8 @@ super(C, self).meth(arg)""" ) -class W_Property(Wrappable): + +class W_Property(W_Root): _immutable_fields_ = ["w_fget", "w_fset", "w_fdel"] def __init__(self, space): @@ -192,4 +194,3 @@ # descriptor for the instances. W_Property.typedef.rawdict['__doc__'] = interp_attrproperty_w('w_doc', W_Property) - diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -3,7 +3,7 @@ """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef @@ -226,8 +226,8 @@ """ return min_max(space, __args__, "min") -class W_Enumerate(Wrappable): +class W_Enumerate(W_Root): def __init__(self, w_iter, w_start): self.w_iter = w_iter self.w_index = w_start @@ -283,8 +283,8 @@ return space.call_function(w_reversed) return space.wrap(W_ReversedIterator(space, w_sequence)) -class W_ReversedIterator(Wrappable): +class W_ReversedIterator(W_Root): def __init__(self, space, w_sequence): self.remaining = space.len_w(w_sequence) - 1 if space.lookup(w_sequence, "__getitem__") is None: @@ -339,8 +339,7 @@ return space.wrap(iterator) - -class W_XRange(Wrappable): +class W_XRange(W_Root): def __init__(self, space, start, len, step, promote_step=False): self.space = space self.start = start @@ -429,7 +428,8 @@ __reduce__ = interp2app(W_XRange.descr_reduce), ) -class W_XRangeIterator(Wrappable): + +class W_XRangeIterator(W_Root): def __init__(self, space, current, remaining, step): self.space = space self.current = current @@ -441,7 +441,7 @@ def descr_next(self): return self.next() - + def next(self): if self.remaining > 0: item = self.current diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -2,7 +2,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, descr_set_dict from rpython.rlib.objectmodel import compute_identity_hash from rpython.rlib.debug import make_sure_not_resized @@ -48,7 +48,8 @@ return W_ClassObject(space, w_name, bases_w, w_dict) -class W_ClassObject(Wrappable): + +class W_ClassObject(W_Root): def __init__(self, space, w_name, bases, w_dict): self.name = space.str_w(w_name) make_sure_not_resized(bases) @@ -315,7 +316,8 @@ w_result.setdict(space, w_dict) return w_result -class W_InstanceObject(Wrappable): + +class W_InstanceObject(W_Root): def __init__(self, space, w_class): # note that user_setup is overridden by the typedef.py machinery self.user_setup(space, space.gettypeobject(self.typedef)) diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py --- a/pypy/module/__builtin__/interp_memoryview.py +++ b/pypy/module/__builtin__/interp_memoryview.py @@ -1,7 +1,7 @@ """ Implementation of the 'buffer' and 'memoryview' types. """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import buffer from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -11,7 +11,7 @@ W_Buffer = buffer.Buffer # actually implemented in pypy.interpreter.buffer -class W_MemoryView(Wrappable): +class W_MemoryView(W_Root): """Implement the built-in 'memoryview' type as a thin wrapper around an interp-level buffer. """ @@ -110,16 +110,22 @@ def w_get_format(self, space): return space.wrap("B") + def w_get_itemsize(self, space): return space.wrap(1) + def w_get_ndim(self, space): return space.wrap(1) + def w_is_readonly(self, space): return space.wrap(not isinstance(self.buf, buffer.RWBuffer)) + def w_get_shape(self, space): return space.newtuple([space.wrap(self.getlength())]) + def w_get_strides(self, space): return space.newtuple([space.wrap(1)]) + def w_get_suboffsets(self, space): # I've never seen anyone filling this field return space.w_None diff --git a/pypy/module/__pypy__/interp_builders.py b/pypy/module/__pypy__/interp_builders.py --- a/pypy/module/__pypy__/interp_builders.py +++ b/pypy/module/__pypy__/interp_builders.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef @@ -7,7 +7,7 @@ def create_builder(name, strtype, builder_cls): - class W_Builder(Wrappable): + class W_Builder(W_Root): def __init__(self, space, size): if size < 0: self.builder = builder_cls() diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -1,9 +1,10 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root -class W_IdentityDict(Wrappable): + +class W_IdentityDict(W_Root): def __init__(self, space): self.dict = {} diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,6 +1,6 @@ import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr @@ -13,7 +13,7 @@ from pypy.module._cffi_backend import misc -class W_CData(Wrappable): +class W_CData(W_Root): _attrs_ = ['space', '_cdata', 'ctype', '_lifeline_'] _immutable_fields_ = ['_cdata', 'ctype'] _cdata = lltype.nullptr(rffi.CCHARP.TO) diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,7 +2,7 @@ Arrays. """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef @@ -119,7 +119,7 @@ return W_CTypePtrOrArray._fget(self, attrchar) -class W_CDataIter(Wrappable): +class W_CDataIter(W_Root): _immutable_fields_ = ['ctitem', 'cdata', '_stop'] # but not '_next' def __init__(self, space, ctitem, cdata): diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty @@ -9,8 +9,8 @@ from pypy.module._cffi_backend import cdataobj -class W_CType(Wrappable): - _attrs_ = ['space', 'size', 'name', 'name_position', '_lifeline_'] +class W_CType(W_Root): + _attrs_ = ['space', 'size', 'name', 'name_position', '_lifeline_'] _immutable_fields_ = ['size?', 'name', 'name_position'] # note that 'size' is not strictly immutable, because it can change # from -1 to the real value in the W_CTypeStruct subclass. diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,7 +3,7 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, interp_attrproperty from rpython.rlib import jit @@ -155,7 +155,7 @@ self.name, n) -class W_CField(Wrappable): +class W_CField(W_Root): _immutable_ = True BS_REGULAR = -1 diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -1,6 +1,6 @@ import sys from pypy.interpreter import gateway -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.typedef import GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -51,7 +51,7 @@ # ------------------------------------------------------------ -class W_Deque(Wrappable): +class W_Deque(W_Root): def __init__(self, space): self.space = space self.maxlen = sys.maxint @@ -504,7 +504,7 @@ # ------------------------------------------------------------ -class W_DequeIter(Wrappable): +class W_DequeIter(W_Root): def __init__(self, deque): self.space = deque.space self.deque = deque @@ -547,7 +547,7 @@ # ------------------------------------------------------------ -class W_DequeRevIter(Wrappable): +class W_DequeRevIter(W_Root): def __init__(self, deque): self.space = deque.space self.deque = deque diff --git a/pypy/module/_ffi/interp_ffitype.py b/pypy/module/_ffi/interp_ffitype.py --- a/pypy/module/_ffi/interp_ffitype.py +++ b/pypy/module/_ffi/interp_ffitype.py @@ -1,13 +1,13 @@ from rpython.rlib import libffi, clibffi from rpython.rlib.rarithmetic import intmask from rpython.rlib import jit -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError -class W_FFIType(Wrappable): +class W_FFIType(W_Root): _immutable_fields_ = ['name', 'w_structdescr', 'w_pointer_to'] def __init__(self, name, ffitype, w_structdescr=None, w_pointer_to=None): @@ -157,6 +157,7 @@ pass app_types.__dict__ = build_ffi_types() + def descr_new_pointer(space, w_cls, w_pointer_to): try: return descr_new_pointer.cache[w_pointer_to] @@ -168,12 +169,13 @@ else: w_pointer_to = space.interp_w(W_FFIType, w_pointer_to) name = '(pointer to %s)' % w_pointer_to.name - w_result = W_FFIType(name, libffi.types.pointer, w_pointer_to = w_pointer_to) + w_result = W_FFIType(name, libffi.types.pointer, w_pointer_to=w_pointer_to) descr_new_pointer.cache[w_pointer_to] = w_result return w_result descr_new_pointer.cache = {} -class W_types(Wrappable): + +class W_types(W_Root): pass W_types.typedef = TypeDef( 'types', diff --git a/pypy/module/_ffi/interp_struct.py b/pypy/module/_ffi/interp_struct.py --- a/pypy/module/_ffi/interp_struct.py +++ b/pypy/module/_ffi/interp_struct.py @@ -4,7 +4,7 @@ from rpython.rlib import jit from rpython.rlib.rgc import must_be_light_finalizer from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_singlefloat, intmask -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import operationerrfmt @@ -13,8 +13,7 @@ from pypy.module._ffi.type_converter import FromAppLevelConverter, ToAppLevelConverter -class W_Field(Wrappable): - +class W_Field(W_Root): def __init__(self, name, w_ffitype): self.name = name self.w_ffitype = w_ffitype @@ -52,9 +51,9 @@ def __del__(self): if self.ffistruct: lltype.free(self.ffistruct, flavor='raw', track_allocation=True) - -class W__StructDescr(Wrappable): + +class W__StructDescr(W_Root): def __init__(self, name): self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL, @@ -155,7 +154,7 @@ NULL = lltype.nullptr(rffi.VOIDP.TO) -class W__StructInstance(Wrappable): +class W__StructInstance(W_Root): _immutable_fields_ = ['structdescr', 'rawmem'] @@ -207,7 +206,7 @@ self.rawmem = rawmem self.offset = offset - def get_longlong(self, w_ffitype): + def get_longlong(self, w_ffitype): return libffi.struct_getfield_longlong(libffi.types.slonglong, self.rawmem, self.offset) diff --git a/pypy/module/_file/interp_stream.py b/pypy/module/_file/interp_stream.py --- a/pypy/module/_file/interp_stream.py +++ b/pypy/module/_file/interp_stream.py @@ -1,15 +1,16 @@ import py + from rpython.rlib import streamio from rpython.rlib.streamio import StreamErrors from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable +from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app from pypy.interpreter.streamutil import wrap_streamerror, wrap_oserror_as_ioerror -class W_AbstractStream(Wrappable): +class W_AbstractStream(W_Root): """Base class for interp-level objects that expose streams to app-level""" slock = None slockowner = None @@ -87,6 +88,7 @@ except StreamErrors, e: raise wrap_streamerror(self.space, e) + # ____________________________________________________________ class W_Stream(W_AbstractStream): diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import ( TypeDef, GetSetProperty, generic_new_descr, descr_get_dict, descr_set_dict, make_weakref_descr) @@ -37,7 +37,8 @@ space.w_IOError, space.wrap("file or stream is not seekable")) -class W_IOBase(Wrappable): + +class W_IOBase(W_Root): def __init__(self, space): # XXX: IOBase thinks it has to maintain its own internal state in # `__IOBase_closed` and call flush() by itself, but it is redundant diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -3,7 +3,7 @@ TypeDef, GetSetProperty, interp_attrproperty_w, interp_attrproperty, generic_new_descr) from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from rpython.rlib.rarithmetic import intmask, r_ulonglong, r_uint from rpython.rlib.rbigint import rbigint @@ -22,7 +22,7 @@ _WINDOWS = sys.platform == 'win32' -class W_IncrementalNewlineDecoder(Wrappable): +class W_IncrementalNewlineDecoder(W_Root): seennl = 0 pendingcr = False w_decoder = None diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py --- a/pypy/module/_multiprocessing/interp_connection.py +++ b/pypy/module/_multiprocessing/interp_connection.py @@ -1,5 +1,5 @@ from __future__ import with_statement -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import ( @@ -25,7 +25,8 @@ def w_handle(space, handle): return space.wrap(rffi.cast(rffi.INTPTR_T, handle)) -class W_BaseConnection(Wrappable): + +class W_BaseConnection(W_Root): BUFFER_SIZE = 1024 def __init__(self, flags): diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -1,5 +1,5 @@ from __future__ import with_statement -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import wrap_oserror, OperationError @@ -416,7 +416,7 @@ return semlock_getvalue(self, space) == 0 -class W_SemLock(Wrappable): +class W_SemLock(W_Root): def __init__(self, handle, kind, maxvalue): self.handle = handle self.kind = kind diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -1,11 +1,12 @@ +import time + from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from rpython.rlib.rarithmetic import r_uint, intmask from rpython.rlib import rbigint, rrandom, rstring -import time def descr_new__(space, w_subtype, __args__): w_anything = __args__.firstarg() @@ -14,7 +15,8 @@ W_Random.__init__(x, space, w_anything) return space.wrap(x) -class W_Random(Wrappable): + +class W_Random(W_Root): def __init__(self, space, w_anything): self._rnd = rrandom.Random() self.seed(space, w_anything) diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -138,7 +138,7 @@ space.wrap("not supported by libffi")) -class W_CDLL(Wrappable): +class W_CDLL(W_Root): def __init__(self, space, name, cdll): self.cdll = cdll self.name = name @@ -246,7 +246,7 @@ w_exception = space.getattr(w_mod, space.wrap("SegfaultException")) return OperationError(w_exception, space.wrap(reason)) -class W_DataShape(Wrappable): +class W_DataShape(W_Root): _array_shapes = None size = 0 alignment = 0 @@ -271,7 +271,7 @@ space.wrap(self.alignment)]) -class W_DataInstance(Wrappable): +class W_DataInstance(W_Root): def __init__(self, space, size, address=r_uint(0)): if address: self.ll_buffer = rffi.cast(rffi.VOIDP, address) @@ -378,7 +378,8 @@ space.wrap("cannot directly read value")) wrap_value._annspecialcase_ = 'specialize:arg(1)' -class W_FuncPtr(Wrappable): + +class W_FuncPtr(W_Root): def __init__(self, space, ptr, argshapes, resshape): self.ptr = ptr self.argshapes = argshapes diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -1,5 +1,5 @@ import sys -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.typedef import make_weakref_descr @@ -89,7 +89,7 @@ # # SRE_Pattern class -class W_SRE_Pattern(Wrappable): +class W_SRE_Pattern(W_Root): _immutable_fields_ = ["code", "flags", "num_groups", "w_groupindex"] def cannot_copy_w(self): @@ -320,7 +320,7 @@ # # SRE_Match class -class W_SRE_Match(Wrappable): +class W_SRE_Match(W_Root): flatten_cache = None def __init__(self, srepat, ctx): @@ -493,14 +493,14 @@ regs = GetSetProperty(W_SRE_Match.fget_regs), ) + # ____________________________________________________________ # # SRE_Scanner class # This is mostly an internal class in CPython. # Our version is also directly iterable, to make finditer() easier. -class W_SRE_Scanner(Wrappable): - +class W_SRE_Scanner(W_Root): def __init__(self, pattern, ctx): self.space = pattern.space self.srepat = pattern diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py --- a/pypy/module/_weakref/interp__weakref.py +++ b/pypy/module/_weakref/interp__weakref.py @@ -1,5 +1,5 @@ import py -from pypy.interpreter.baseobjspace import Wrappable, W_Root +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, ObjSpace from pypy.interpreter.typedef import TypeDef @@ -150,7 +150,7 @@ assert dead_ref() is None -class W_WeakrefBase(Wrappable): +class W_WeakrefBase(W_Root): def __init__(w_self, space, w_obj, w_callable): assert w_callable is not space.w_None # should be really None w_self.space = space @@ -183,6 +183,7 @@ state = "; to '%s'" % (typename,) return self.getrepr(space, self.typedef.name, state) + class W_Weakref(W_WeakrefBase): def __init__(w_self, space, w_obj, w_callable): W_WeakrefBase.__init__(w_self, space, w_obj, w_callable) @@ -217,8 +218,7 @@ ref2 = w_ref2 w_obj1 = ref1.dereference() w_obj2 = ref2.dereference() - if (w_obj1 is None or - w_obj2 is None): + if w_obj1 is None or w_obj2 is None: return space.is_(ref1, ref2) return space.eq(w_obj1, w_obj2) diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py --- a/pypy/module/cpyext/methodobject.py +++ b/pypy/module/cpyext/methodobject.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -59,7 +59,8 @@ from pypy.module.cpyext.object import PyObject_dealloc PyObject_dealloc(space, py_obj) -class W_PyCFunctionObject(Wrappable): + +class W_PyCFunctionObject(W_Root): def __init__(self, space, ml, w_self, w_module=None): self.ml = ml self.name = rffi.charp2str(self.ml.c_ml_name) @@ -144,7 +145,7 @@ return self.getrepr(self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space))) -class W_PyCWrapperObject(Wrappable): +class W_PyCWrapperObject(W_Root): def __init__(self, space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func): self.space = space diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -72,21 +72,24 @@ +-- BytesWarning """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import (TypeDef, GetSetProperty, descr_get_dict, descr_set_dict, descr_del_dict) from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError from rpython.rlib import rwin32 + def readwrite_attrproperty_w(name, cls): def fget(space, obj): return getattr(obj, name) + def fset(space, obj, w_val): setattr(obj, name, w_val) return GetSetProperty(fget, fset, cls=cls) -class W_BaseException(Wrappable): + +class W_BaseException(W_Root): """Superclass representing the base of the exception hierarchy. The __getitem__ method is provided for backwards-compatibility @@ -153,8 +156,8 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance( w_dict, space.w_dict )): - raise OperationError( space.w_TypeError, space.wrap("setting exceptions's dictionary to a non-dict") ) + if not space.is_true(space.isinstance(w_dict, space.w_dict)): + raise OperationError(space.w_TypeError, space.wrap("setting exceptions's dictionary to a non-dict")) self.w_dict = w_dict def descr_reduce(self, space): 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 @@ -8,7 +8,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, generic_new_descr from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.eval import Code from pypy.interpreter.pycode import PyCode from rpython.rlib import streamio, jit @@ -440,7 +440,7 @@ return w_loader -class W_NullImporter(Wrappable): +class W_NullImporter(W_Root): def __init__(self, space): pass diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -1,10 +1,10 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -class W_Count(Wrappable): +class W_Count(W_Root): def __init__(self, space, w_firstval, w_step): self.space = space self.w_c = w_firstval @@ -79,8 +79,7 @@ """) -class W_Repeat(Wrappable): - +class W_Repeat(W_Root): def __init__(self, space, w_obj, w_times): self.space = space self.w_obj = w_obj @@ -145,8 +144,8 @@ yield object """) -class W_TakeWhile(Wrappable): +class W_TakeWhile(W_Root): def __init__(self, space, w_predicate, w_iterable): self.space = space self.w_predicate = w_predicate @@ -193,8 +192,8 @@ break """) -class W_DropWhile(Wrappable): +class W_DropWhile(W_Root): def __init__(self, space, w_predicate, w_iterable): self.space = space self.w_predicate = w_predicate @@ -246,8 +245,8 @@ yield x """) -class _IFilterBase(Wrappable): +class _IFilterBase(W_Root): def __init__(self, space, w_predicate, w_iterable): self.space = space if space.is_w(w_predicate, space.w_None): @@ -328,7 +327,8 @@ yield x """) -class W_ISlice(Wrappable): + +class W_ISlice(W_Root): def __init__(self, space, w_iterable, w_startstop, args_w): self.iterable = space.iter(w_iterable) self.space = space @@ -430,7 +430,7 @@ """) -class W_Chain(Wrappable): +class W_Chain(W_Root): def __init__(self, space, w_iterables): self.space = space self.w_iterables = w_iterables @@ -495,7 +495,8 @@ yield element """) -class W_IMap(Wrappable): + +class W_IMap(W_Root): _error_name = "imap" _immutable_fields_ = ["w_fun", "iterators_w"] @@ -685,8 +686,7 @@ """) -class W_Cycle(Wrappable): - +class W_Cycle(W_Root): def __init__(self, space, w_iterable): self.space = space self.saved_w = [] @@ -752,8 +752,8 @@ yield element """) -class W_StarMap(Wrappable): +class W_StarMap(W_Root): def __init__(self, space, w_fun, w_iterable): self.space = space self.w_fun = w_fun @@ -841,7 +841,8 @@ class TeeChainedListNode(object): w_obj = None -class W_TeeIterable(Wrappable): + +class W_TeeIterable(W_Root): def __init__(self, space, w_iterator, chained_list): self.space = space self.w_iterator = w_iterator @@ -882,8 +883,7 @@ W_TeeIterable.typedef.acceptable_as_base_class = False -class W_GroupBy(Wrappable): - +class W_GroupBy(W_Root): def __init__(self, space, w_iterable, w_fun): self.space = space self.w_iterable = self.space.iter(w_iterable) @@ -1001,7 +1001,8 @@ uniquekeys.append(k) """) -class W_GroupByIterator(Wrappable): + +class W_GroupByIterator(W_Root): def __init__(self, space, index, groupby): self.space = space self.index = index @@ -1031,7 +1032,7 @@ W_GroupByIterator.typedef.acceptable_as_base_class = False -class W_Compress(Wrappable): +class W_Compress(W_Root): def __init__(self, space, w_data, w_selectors): self.space = space self.w_data = space.iter(w_data) @@ -1073,7 +1074,7 @@ """) -class W_Product(Wrappable): +class W_Product(W_Root): def __init__(self, space, args_w, w_repeat): self.gears = [ space.fixedview(arg_w) for arg_w in args_w @@ -1181,7 +1182,7 @@ """) -class W_Combinations(Wrappable): +class W_Combinations(W_Root): def __init__(self, space, pool_w, indices, r): self.pool_w = pool_w self.indices = indices @@ -1299,7 +1300,7 @@ ) -class W_Permutations(Wrappable): +class W_Permutations(W_Root): def __init__(self, space, pool_w, r): self.pool_w = pool_w self.r = r diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py --- a/pypy/module/select/interp_kqueue.py +++ b/pypy/module/select/interp_kqueue.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt, exception_from_errno from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef, generic_new_descr, GetSetProperty @@ -103,7 +103,7 @@ ) -class W_Kqueue(Wrappable): +class W_Kqueue(W_Root): def __init__(self, space, kqfd): self.kqfd = kqfd @@ -232,7 +232,7 @@ W_Kqueue.typedef.acceptable_as_base_class = False -class W_Kevent(Wrappable): +class W_Kevent(W_Root): def __init__(self, space): self.event = lltype.nullptr(kevent) diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -1,8 +1,9 @@ """ Implementation of the interpreter-level functions in the module unicodedata. """ -from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.baseobjspace import Wrappable + +from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, interp_attrproperty from rpython.rlib.rarithmetic import r_longlong @@ -72,7 +73,7 @@ 'need a single Unicode character as parameter')) -class UCD(Wrappable): +class UCD(W_Root): def __init__(self, unicodedb): self._lookup = unicodedb.lookup self._name = unicodedb.name @@ -119,7 +120,6 @@ raise OperationError(space.w_ValueError, space.wrap('no such name')) return space.wrap(name) - def decimal(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: @@ -205,10 +205,10 @@ ch = space.int_w(space.ord(space.getitem(w_unistr, space.wrap(i)))) # Do Hangul decomposition if SBase <= ch < SBase + SCount: - SIndex = ch - SBase; - L = LBase + SIndex / NCount; - V = VBase + (SIndex % NCount) / TCount; - T = TBase + SIndex % TCount; + SIndex = ch - SBase + L = LBase + SIndex / NCount + V = VBase + (SIndex % NCount) / TCount + T = TBase + SIndex % TCount if T == TBase: if j + 2 > resultlen: result.extend([0] * (j + 2 - resultlen + 10)) @@ -300,7 +300,6 @@ current = next continue - result[next_insert] = next next_insert += 1 if next_combining > prev_combining: diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -1,6 +1,6 @@ from rpython.annotator.model import SomeInstance, s_None from pypy.interpreter import argument, gateway -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, SpaceCache +from pypy.interpreter.baseobjspace import W_Root, ObjSpace, SpaceCache from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.sliceobject import W_SliceObject @@ -14,7 +14,7 @@ from rpython.translator.translator import TranslationContext -class W_MyObject(Wrappable): +class W_MyObject(W_Root): typedef = None def getdict(self, space): @@ -47,10 +47,10 @@ def int_w(self, space): return NonConstant(-42) - + def uint_w(self, space): return r_uint(NonConstant(42)) - + def bigint_w(self, space): from rpython.rlib.rbigint import rbigint return rbigint.fromint(NonConstant(42)) @@ -354,9 +354,11 @@ pass FakeObjSpace.default_compiler = FakeCompiler() -class FakeModule(Wrappable): + +class FakeModule(W_Root): def __init__(self): self.w_dict = w_some_obj() + def get(self, name): name + "xx" # check that it's a string return w_some_obj() diff --git a/pypy/objspace/fake/test/test_checkmodule.py b/pypy/objspace/fake/test/test_checkmodule.py --- a/pypy/objspace/fake/test/test_checkmodule.py +++ b/pypy/objspace/fake/test/test_checkmodule.py @@ -1,10 +1,11 @@ +from rpython.rlib.objectmodel import specialize +from rpython.rtyper.test.test_llinterp import interpret from pypy.objspace.fake.objspace import FakeObjSpace, is_root -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, W_Root, ObjSpace -from rpython.rlib.objectmodel import specialize -from rpython.rtyper.test.test_llinterp import interpret +from pypy.interpreter.gateway import interp2app, ObjSpace + def make_checker(): check = [] @@ -65,7 +66,7 @@ def test_gettypefor_untranslated(): see, check = make_checker() - class W_Foo(Wrappable): + class W_Foo(W_Root): def do_it(self, space, w_x): is_root(w_x) see() @@ -96,7 +97,7 @@ def test_see_objects(): see, check = make_checker() - class W_Foo(Wrappable): + class W_Foo(W_Root): def __init__(self, x): self.x = x def do_it(self): 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 @@ -1666,9 +1666,6 @@ list(sequence) -> new list initialized from sequence's items""", __new__ = interp2app(descr_new), __hash__ = None, - # XXX this cannot work, within the methods the annotation of 'self' is W_Root - # the reason why it works in modules is that there all classes inherit from Wrappable - # see gateway.UnwrapSpec_EmitRun.visit__Wrappable vs visit__W_Root sort = interp2app(W_ListObject.descr_sort), index = interp2app(W_ListObject.descr_index), append = interp2app(W_ListObject.append), diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -1,15 +1,15 @@ import __builtin__ import types from pypy.interpreter import special -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable +from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, - transparent, callmethod, proxyobject) + transparent, callmethod) from pypy.objspace.descroperation import DescrOperation, raiseattrerror -from rpython.rlib.objectmodel import instantiate, r_dict, specialize, is_annotation_constant +from rpython.rlib.objectmodel import instantiate, specialize, is_annotation_constant from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.rarithmetic import base_int, widen, maxint, is_valid_int +from rpython.rlib.rarithmetic import base_int, widen, is_valid_int from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit @@ -162,7 +162,7 @@ return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) - if isinstance(x, Wrappable): + if isinstance(x, W_Root): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py --- a/pypy/objspace/std/proxyobject.py +++ b/pypy/objspace/std/proxyobject.py @@ -2,39 +2,36 @@ """ transparent list implementation """ -from pypy.objspace.std.model import registerimplementation, W_Object -from pypy.objspace.std.proxy_helpers import register_type +from pypy.objspace.std.model import W_Object from pypy.interpreter.error import OperationError -from pypy.interpreter import baseobjspace, argument +from pypy.interpreter import baseobjspace #class W_Transparent(W_Object): # def __init__(self, w_controller): # self.controller = w_controller -#class W_TransparentWrappable(Wrappable): def transparent_class(name, BaseCls): - class W_Transparent(BaseCls): ignore_for_isinstance_cache = True def __init__(self, space, w_type, w_controller): self.w_type = w_type self.w_controller = w_controller - + def descr_call_mismatch(self, space, name, reqcls, args): args_w = args.arguments_w[:] args_w[0] = space.wrap(name) args = args.replace_arguments(args_w) return space.call_args(self.w_controller, args) - + def getclass(self, space): return self.w_type - + def setclass(self, space, w_subtype): raise OperationError(space.w_TypeError, space.wrap("You cannot override __class__ for transparent proxies")) - + def getdictvalue(self, space, attr): try: return space.call_function(self.w_controller, space.wrap('__getattribute__'), @@ -43,7 +40,7 @@ if not e.match(space, space.w_AttributeError): raise return None - + def setdictvalue(self, space, attr, w_value): try: space.call_function(self.w_controller, space.wrap('__setattr__'), @@ -53,7 +50,7 @@ if not e.match(space, space.w_AttributeError): raise return False - + def deldictvalue(self, space, attr): try: space.call_function(self.w_controller, space.wrap('__delattr__'), @@ -63,18 +60,18 @@ if not e.match(space, space.w_AttributeError): raise return False - + def getdict(self, space): return self.getdictvalue(space, '__dict__') - + def setdict(self, space, w_dict): if not self.setdictvalue(space, '__dict__', w_dict): baseobjspace.W_Root.setdict(self, space, w_dict) - + W_Transparent.__name__ = name return W_Transparent -W_Transparent = transparent_class('W_Transparent', baseobjspace.Wrappable) +W_Transparent = transparent_class('W_Transparent', baseobjspace.W_Root) W_TransparentObject = transparent_class('W_TransparentObject', W_Object) from pypy.objspace.std.objecttype import object_typedef diff --git a/pypy/objspace/std/test/test_proxy_internals.py b/pypy/objspace/std/test/test_proxy_internals.py --- a/pypy/objspace/std/test/test_proxy_internals.py +++ b/pypy/objspace/std/test/test_proxy_internals.py @@ -14,7 +14,7 @@ class Controller(object): def __init__(self, obj): self.obj = obj - + def perform(self, name, *args, **kwargs): return getattr(self.obj, name)(*args, **kwargs) def get_proxy(f): @@ -28,9 +28,9 @@ if cls.runappdirect: py.test.skip("interp only test") from pypy.interpreter.typedef import TypeDef, interp2app - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root - class W_Stuff(Wrappable): + class W_Stuff(W_Root): pass def descr_new(space, w_subtype): @@ -52,7 +52,7 @@ except: import sys e = sys.exc_info() - + tb = self.get_proxy(e[2]) assert tb.tb_frame is e[2].tb_frame @@ -75,7 +75,7 @@ except: import sys e = sys.exc_info() - + tb = self.get_proxy(e[2]) raises(ZeroDivisionError, "raise e[0], e[1], tb") raises(ZeroDivisionError, "raise e[0], self.get_proxy(e[1]), tb") @@ -93,11 +93,11 @@ import types import sys import traceback - + def get_proxy(f): from __pypy__ import tproxy as proxy return proxy(type(f), Controller(f).perform) - + class FakeTb(object): def __init__(self, tb): self.tb_lasti = tb.tb_lasti @@ -107,37 +107,37 @@ else: self.tb_next = None self.tb_frame = get_proxy(tb.tb_frame) - + class Controller(object): def __init__(self, tb): if isinstance(tb, types.TracebackType): self.obj = FakeTb(tb) else: self.obj = tb - + def perform(self, name, *args, **kwargs): return getattr(self.obj, name)(*args, **kwargs) - + def f(): 1/0 - + def g(): f() - + try: g() except: e = sys.exc_info() - + last_tb = e[2] tb = get_proxy(e[2]) try: raise e[0], e[1], tb except: e = sys.exc_info() - + assert traceback.format_tb(last_tb) == traceback.format_tb(e[2]) - + def test_proxy_get(self): from __pypy__ import tproxy, get_tproxy_controller l = [1,2,3] diff --git a/pypy/objspace/std/test/test_proxy_usercreated.py b/pypy/objspace/std/test/test_proxy_usercreated.py --- a/pypy/objspace/std/test/test_proxy_usercreated.py +++ b/pypy/objspace/std/test/test_proxy_usercreated.py @@ -1,13 +1,14 @@ From noreply at buildbot.pypy.org Wed Mar 20 23:56:54 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 20 Mar 2013 23:56:54 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: finish killing Wrappable Message-ID: <20130320225654.B43E01C0EB1@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: remove-list-smm Changeset: r62592:26af0e3ce5d3 Date: 2013-03-20 15:56 -0700 http://bitbucket.org/pypy/pypy/changeset/26af0e3ce5d3/ Log: finish killing Wrappable diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. 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 @@ -25,7 +25,7 @@ def d(self, w_boo): pass code = gateway.BuiltinCode(d, unwrap_spec= ['self', - gateway.W_Root], self_type=gateway.Wrappable) + gateway.W_Root], self_type=gateway.W_Root) assert code.signature() == Signature(['self', 'boo'], None, None) def e(space, w_x, w_y, __args__): pass @@ -167,7 +167,7 @@ space.wrap(True)) def test_caching_methods(self): - class Base(gateway.Wrappable): + class Base(gateway.W_Root): def f(self): return 1 diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py --- a/pypy/interpreter/test/test_typedef.py +++ b/pypy/interpreter/test/test_typedef.py @@ -1,7 +1,7 @@ import gc from pypy.interpreter import typedef from rpython.tool.udir import udir -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, interp2app # this test isn't so much to test that the objspace interface *works* @@ -139,7 +139,7 @@ cls, len(set), list(set)) def test_getsetproperty(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): pass def fget(self, space, w_self): assert self is prop @@ -151,7 +151,7 @@ assert self.space.getattr(w_obj, self.space.wrap('x')) is self.space.w_None def test_getsetproperty_arguments(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): def fget1(space, w_self): assert isinstance(space, ObjSpace) assert isinstance(w_self, W_SomeType) @@ -169,7 +169,7 @@ assert space.getattr(w_obj, space.wrap('x2')) == space.w_None def test_unhashable(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): pass W_SomeType.typedef = typedef.TypeDef( 'some_type', @@ -183,12 +183,12 @@ def test_destructor(self): space = self.space - class W_Level1(Wrappable): + class W_Level1(W_Root): def __init__(self, space1): assert space1 is space def __del__(self): space.call_method(w_seen, 'append', space.wrap(1)) - class W_Level2(Wrappable): + class W_Level2(W_Root): def __init__(self, space1): assert space1 is space def __del__(self): @@ -261,7 +261,7 @@ assert space.unwrap(w_seen) == [6, 2] def test_multiple_inheritance(self): - class W_A(Wrappable): + class W_A(W_Root): a = 1 b = 2 class W_C(W_A): @@ -270,7 +270,7 @@ a = typedef.interp_attrproperty("a", cls=W_A), b = typedef.interp_attrproperty("b", cls=W_A), ) - class W_B(Wrappable): + class W_B(W_Root): pass def standalone_method(space, w_obj): if isinstance(w_obj, W_A): @@ -305,7 +305,7 @@ assert_method(w_o2, "c", False) def test_total_ordering(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): def __init__(self, space, x): self.space = space self.x = x diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app @@ -38,8 +38,8 @@ raw_cdata[i] = string[i] -class MiniBuffer(Wrappable): - # a different subclass of Wrappable for the MiniBuffer, because we +class MiniBuffer(W_Root): + # a different subclass of W_Root for the MiniBuffer, because we # want a slightly different (simplified) API at the level of Python. def __init__(self, buffer, keepalive=None): diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,6 +1,6 @@ from __future__ import with_statement -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef @@ -12,7 +12,7 @@ from pypy.module._cffi_backend.ctypeobj import W_CType -class W_Library(Wrappable): +class W_Library(W_Root): _immutable_ = True handle = rffi.cast(DLLHANDLE, 0) diff --git a/pypy/module/_collections/app_defaultdict.py b/pypy/module/_collections/app_defaultdict.py --- a/pypy/module/_collections/app_defaultdict.py +++ b/pypy/module/_collections/app_defaultdict.py @@ -3,7 +3,7 @@ # For now this is here, living at app-level. # # The issue is that for now we don't support writing interp-level -# subclasses of Wrappable that inherit at app-level from a type like +# subclasses of W_Root that inherit at app-level from a type like # 'dict'. But what we can do is write individual methods at # interp-level. @@ -11,7 +11,7 @@ class defaultdict(dict): - + def __init__(self, *args, **kwds): if len(args) > 0: default_factory = args[0] @@ -22,7 +22,7 @@ default_factory = None self.default_factory = default_factory super(defaultdict, self).__init__(*args, **kwds) - + def __missing__(self, key): pass # this method is written at interp-level __missing__.func_code = _collections.__missing__.func_code @@ -39,7 +39,7 @@ def copy(self): return type(self)(self.default_factory, self) - + def __copy__(self): return self.copy() diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -2,14 +2,14 @@ from rpython.rlib import jit from pypy.interpreter.error import OperationError from pypy.interpreter.executioncontext import ExecutionContext -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyframe import PyFrame -class W_Continulet(Wrappable): +class W_Continulet(W_Root): sthread = None def __init__(self, space): diff --git a/pypy/module/_csv/interp_csv.py b/pypy/module/_csv/interp_csv.py --- a/pypy/module/_csv/interp_csv.py +++ b/pypy/module/_csv/interp_csv.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.typedef import GetSetProperty @@ -8,7 +8,7 @@ QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) -class W_Dialect(Wrappable): +class W_Dialect(W_Root): _immutable_fields_ = [ "dialect", "delimiter", @@ -19,7 +19,7 @@ "quoting", "skipinitialspace", "strict", - ] + ] def _fetch(space, w_dialect, name): return space.findattr(w_dialect, space.wrap(name)) diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -1,5 +1,5 @@ from rpython.rlib.rstring import StringBuilder -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.typedef import TypeDef, interp2app @@ -13,7 +13,7 @@ EAT_CRNL) = range(8) -class W_Reader(Wrappable): +class W_Reader(W_Root): def __init__(self, space, dialect, w_iter): self.space = space diff --git a/pypy/module/_csv/interp_writer.py b/pypy/module/_csv/interp_writer.py --- a/pypy/module/_csv/interp_writer.py +++ b/pypy/module/_csv/interp_writer.py @@ -1,5 +1,5 @@ from rpython.rlib.rstring import StringBuilder -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.typedef import interp_attrproperty_w @@ -8,16 +8,17 @@ QUOTE_NONNUMERIC, QUOTE_NONE) -class W_Writer(Wrappable): - +class W_Writer(W_Root): def __init__(self, space, dialect, w_fileobj): self.space = space self.dialect = dialect self.w_filewrite = space.getattr(w_fileobj, space.wrap('write')) # precompute this special = dialect.delimiter + dialect.lineterminator - if dialect.escapechar != '\0': special += dialect.escapechar - if dialect.quotechar != '\0': special += dialect.quotechar + if dialect.escapechar != '\0': + special += dialect.escapechar + if dialect.quotechar != '\0': + special += dialect.quotechar self.special_characters = special def error(self, msg): diff --git a/pypy/module/_demo/demo.py b/pypy/module/_demo/demo.py --- a/pypy/module/_demo/demo.py +++ b/pypy/module/_demo/demo.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty from rpython.rtyper.lltypesystem import rffi, lltype @@ -47,8 +47,8 @@ newlst.append(element) lst = newlst head += 1 - -class W_MyType(Wrappable): + +class W_MyType(W_Root): def __init__(self, space, x=1): self.space = space self.x = x diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py --- a/pypy/module/_ffi/interp_funcptr.py +++ b/pypy/module/_ffi/interp_funcptr.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, wrap_oserror, \ operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -24,7 +24,7 @@ if space.isinstance_w(w_name, space.w_str): name = space.str_w(w_name) try: - func = CDLL.cdll.getpointer(name, argtypes, restype, + func = CDLL.cdll.getpointer(name, argtypes, restype, flags = CDLL.flags) except KeyError: raise operationerrfmt( @@ -38,7 +38,7 @@ ordinal = space.int_w(w_name) try: func = CDLL.cdll.getpointer_by_ordinal( - ordinal, argtypes, restype, + ordinal, argtypes, restype, flags = CDLL.flags) except KeyError: raise operationerrfmt( @@ -51,14 +51,14 @@ else: raise OperationError(space.w_TypeError, space.wrap( 'function name must be a string or integer')) -else: +else: @unwrap_spec(name=str) def _getfunc(space, CDLL, w_name, w_argtypes, w_restype): name = space.str_w(w_name) argtypes_w, argtypes, w_restype, restype = unpack_argtypes( space, w_argtypes, w_restype) try: - func = CDLL.cdll.getpointer(name, argtypes, restype, + func = CDLL.cdll.getpointer(name, argtypes, restype, flags = CDLL.flags) except KeyError: raise operationerrfmt( @@ -79,7 +79,7 @@ # ======================================================================== -class W_FuncPtr(Wrappable): +class W_FuncPtr(W_Root): _immutable_fields_ = ['func', 'argtypes_w[*]', 'w_restype'] @@ -229,7 +229,7 @@ return rffi.cast(rffi.LONG, call(self.argchain, rffi.SIGNEDCHAR)) else: self.error(w_ffitype) - + def get_unsigned(self, w_ffitype): return self.func.call(self.argchain, rffi.ULONG) @@ -276,7 +276,7 @@ def get_void(self, w_ffitype): return self.func.call(self.argchain, lltype.Void) - + def unpack_argtypes(space, w_argtypes, w_restype): argtypes_w = [space.interp_w(W_FFIType, w_argtype) @@ -288,7 +288,7 @@ return argtypes_w, argtypes, w_restype, restype @unwrap_spec(addr=r_uint, name=str, flags=int) -def descr_fromaddr(space, w_cls, addr, name, w_argtypes, +def descr_fromaddr(space, w_cls, addr, name, w_argtypes, w_restype, flags=libffi.FUNCFLAG_CDECL): argtypes_w, argtypes, w_restype, restype = unpack_argtypes(space, w_argtypes, @@ -313,7 +313,7 @@ # ======================================================================== -class W_CDLL(Wrappable): +class W_CDLL(W_Root): def __init__(self, space, name, mode): self.flags = libffi.FUNCFLAG_CDECL self.space = space diff --git a/pypy/module/_hashlib/interp_hashlib.py b/pypy/module/_hashlib/interp_hashlib.py --- a/pypy/module/_hashlib/interp_hashlib.py +++ b/pypy/module/_hashlib/interp_hashlib.py @@ -3,16 +3,17 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.error import OperationError from rpython.tool.sourcetools import func_renamer -from pypy.interpreter.baseobjspace import Wrappable -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from pypy.interpreter.baseobjspace import W_Root +from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib import rgc, ropenssl -from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rstring import StringBuilder from pypy.module.thread.os_lock import Lock + algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') -class W_Hash(Wrappable): + +class W_Hash(W_Root): NULL_CTX = lltype.nullptr(ropenssl.EVP_MD_CTX.TO) ctx = NULL_CTX @@ -116,7 +117,7 @@ digestsize=GetSetProperty(W_Hash.get_digest_size), block_size=GetSetProperty(W_Hash.get_block_size), name=GetSetProperty(W_Hash.get_name), - ) +) W_Hash.acceptable_as_base_class = False @unwrap_spec(name=str, string='bufferstr') diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py --- a/pypy/module/_lsprof/interp_lsprof.py +++ b/pypy/module/_lsprof/interp_lsprof.py @@ -1,6 +1,6 @@ import py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.function import Method, Function from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -35,7 +35,7 @@ else: timer_size_int = r_longlong -class W_StatsEntry(Wrappable): +class W_StatsEntry(W_Root): def __init__(self, space, frame, callcount, reccallcount, tt, it, w_sublist): self.frame = frame @@ -72,7 +72,7 @@ __repr__ = interp2app(W_StatsEntry.repr), ) -class W_StatsSubEntry(Wrappable): +class W_StatsSubEntry(W_Root): def __init__(self, space, frame, callcount, reccallcount, tt, it): self.frame = frame self.callcount = callcount @@ -252,8 +252,8 @@ # ignore or raise an exception??? pass -class W_Profiler(Wrappable): +class W_Profiler(W_Root): def __init__(self, space, w_callable, time_unit, subcalls, builtins): self.subcalls = subcalls self.builtins = builtins diff --git a/pypy/module/_md5/interp_md5.py b/pypy/module/_md5/interp_md5.py --- a/pypy/module/_md5/interp_md5.py +++ b/pypy/module/_md5/interp_md5.py @@ -1,10 +1,10 @@ from rpython.rlib import rmd5 -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec -class W_MD5(Wrappable, rmd5.RMD5): +class W_MD5(W_Root, rmd5.RMD5): """ A subclass of RMD5 that can be exposed to app-level. """ diff --git a/pypy/module/_multibytecodec/interp_incremental.py b/pypy/module/_multibytecodec/interp_incremental.py --- a/pypy/module/_multibytecodec/interp_incremental.py +++ b/pypy/module/_multibytecodec/interp_incremental.py @@ -3,14 +3,13 @@ from pypy.module._multibytecodec.interp_multibytecodec import ( MultibyteCodec, wrap_unicodedecodeerror, wrap_runtimeerror, wrap_unicodeencodeerror) -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module._codecs.interp_codecs import CodecState -class MultibyteIncrementalBase(Wrappable): - +class MultibyteIncrementalBase(W_Root): def __init__(self, space, errors): if errors is None: errors = 'strict' @@ -82,7 +81,7 @@ reset = interp2app(MultibyteIncrementalDecoder.reset_w), errors = GetSetProperty(MultibyteIncrementalDecoder.fget_errors, MultibyteIncrementalDecoder.fset_errors), - ) +) class MultibyteIncrementalEncoder(MultibyteIncrementalBase): @@ -131,7 +130,7 @@ reset = interp2app(MultibyteIncrementalEncoder.reset_w), errors = GetSetProperty(MultibyteIncrementalEncoder.fget_errors, MultibyteIncrementalEncoder.fset_errors), - ) +) def get_ignore_error(final): diff --git a/pypy/module/_multibytecodec/interp_multibytecodec.py b/pypy/module/_multibytecodec/interp_multibytecodec.py --- a/pypy/module/_multibytecodec/interp_multibytecodec.py +++ b/pypy/module/_multibytecodec/interp_multibytecodec.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef from pypy.interpreter.error import OperationError @@ -6,8 +6,7 @@ from pypy.module._codecs.interp_codecs import CodecState -class MultibyteCodec(Wrappable): - +class MultibyteCodec(W_Root): def __init__(self, name, codec): self.name = name self.codec = codec diff --git a/pypy/module/_sha/interp_sha.py b/pypy/module/_sha/interp_sha.py --- a/pypy/module/_sha/interp_sha.py +++ b/pypy/module/_sha/interp_sha.py @@ -1,10 +1,10 @@ from rpython.rlib import rsha -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec -class W_SHA(Wrappable, rsha.RSHA): +class W_SHA(W_Root, rsha.RSHA): """ A subclass of RSHA that can be exposed to app-level. """ diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ interp_attrproperty from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault @@ -131,7 +131,7 @@ return addr -class W_RSocket(Wrappable, RSocket): +class W_RSocket(W_Root, RSocket): def __del__(self): self.clear_all_weakrefs() RSocket.__del__(self) diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -1,7 +1,7 @@ from __future__ import with_statement from rpython.rtyper.lltypesystem import rffi, lltype from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -119,7 +119,8 @@ raise ssl_error(space, msg) return space.wrap(bytes) -class SSLObject(Wrappable): + +class SSLObject(W_Root): def __init__(self, space): self.space = space self.w_socket = None diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -1,5 +1,5 @@ from __future__ import with_statement -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.error import OperationError, wrap_windowserror @@ -13,7 +13,7 @@ space.newtuple([space.wrap(errcode), space.wrap(message)])) -class W_HKEY(Wrappable): +class W_HKEY(W_Root): def __init__(self, hkey): self.hkey = hkey diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py --- a/pypy/module/bz2/interp_bz2.py +++ b/pypy/module/bz2/interp_bz2.py @@ -3,7 +3,7 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rtyper.lltypesystem import lltype from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.gateway import interp2app, unwrap_spec from rpython.rlib.streamio import Stream @@ -512,7 +512,7 @@ W_BZ2Compressor.__init__(x, space, compresslevel) return space.wrap(x) -class W_BZ2Compressor(Wrappable): +class W_BZ2Compressor(W_Root): """BZ2Compressor([compresslevel=9]) -> compressor object Create a new compressor object. This object may be used to compress @@ -616,7 +616,8 @@ W_BZ2Decompressor.__init__(x, space) return space.wrap(x) -class W_BZ2Decompressor(Wrappable): + +class W_BZ2Decompressor(W_Root): """BZ2Decompressor() -> decompressor object Create a new decompressor object. This object may be used to decompress diff --git a/pypy/module/cStringIO/interp_stringio.py b/pypy/module/cStringIO/interp_stringio.py --- a/pypy/module/cStringIO/interp_stringio.py +++ b/pypy/module/cStringIO/interp_stringio.py @@ -1,11 +1,11 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec from rpython.rlib.rStringIO import RStringIO -class W_InputOutputType(Wrappable): +class W_InputOutputType(W_Root): softspace = 0 # part of the file object API def descr___iter__(self): diff --git a/pypy/module/clr/interp_clr.py b/pypy/module/clr/interp_clr.py --- a/pypy/module/clr/interp_clr.py +++ b/pypy/module/clr/interp_clr.py @@ -1,6 +1,6 @@ import os.path from pypy.module.clr import assemblyname -from pypy.interpreter.baseobjspace import W_Root, Wrappable +from pypy.interpreter.baseobjspace import W_Root, W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec, ApplevelClass from pypy.interpreter.typedef import TypeDef @@ -327,7 +327,7 @@ space.wrap(isClassGeneric)) -class W_CliObject(Wrappable): +class W_CliObject(W_Root): def __init__(self, space, b_obj): self.space = space self.b_obj = b_obj diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py --- a/pypy/module/cppyy/capi/cint_capi.py +++ b/pypy/module/cppyy/capi/cint_capi.py @@ -3,7 +3,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rtyper.lltypesystem import rffi @@ -169,14 +169,14 @@ w_klassname = space.call_method(w_branch, "GetClassName") klass = interp_cppyy.scope_byname(space, space.str_w(w_klassname)) w_obj = klass.construct() - #space.call_method(w_branch, "SetStatus", space.wrap(1)) + #space.call_method(w_branch, "SetStatus", space.wrap(1)) activate_branch(space, w_branch) space.call_method(w_branch, "SetObject", w_obj) space.call_method(w_branch, "GetEntry", space.wrap(0)) space.setattr(w_self, args_w[0], w_obj) return w_obj -class W_TTreeIter(Wrappable): +class W_TTreeIter(W_Root): def __init__(self, space, w_tree): from pypy.module.cppyy import interp_cppyy @@ -199,7 +199,7 @@ raise OperationError(self.space.w_StopIteration, self.space.w_None) # TODO: check bytes read? self.getentry.call(self.tree, [self.space.wrap(self.current)]) - self.current += 1 + self.current += 1 return self.w_tree W_TTreeIter.typedef = TypeDef( diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -3,7 +3,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty -from pypy.interpreter.baseobjspace import Wrappable, W_Root +from pypy.interpreter.baseobjspace import W_Root from rpython.rtyper.lltypesystem import rffi, lltype, llmemory @@ -99,7 +99,7 @@ state.cppclass_registry[cppclass.handle] = w_pycppclass -class W_CPPLibrary(Wrappable): +class W_CPPLibrary(W_Root): _immutable_ = True def __init__(self, space, cdll): @@ -412,7 +412,7 @@ CPPMethod.call(self, cppthis, args_w) -class W_CPPOverload(Wrappable): +class W_CPPOverload(W_Root): """Dispatcher that is actually available at the app-level: it is a collection of (possibly) overloaded methods or functions. It calls these in order and deals with error handling and reporting.""" @@ -495,7 +495,7 @@ ) -class W_CPPDataMember(Wrappable): +class W_CPPDataMember(W_Root): _attrs_ = ['space', 'scope', 'converter', 'offset', '_is_static'] _immutable_fields = ['scope', 'converter', 'offset', '_is_static'] @@ -543,7 +543,7 @@ W_CPPDataMember.typedef.acceptable_as_base_class = False -class W_CPPScope(Wrappable): +class W_CPPScope(W_Root): _attrs_ = ['space', 'name', 'handle', 'methods', 'datamembers'] _immutable_fields_ = ['kind', 'name'] @@ -715,7 +715,7 @@ dname = capi.c_datamember_name(self, i) if dname: alldir.append(self.space.wrap(dname)) return self.space.newlist(alldir) - + W_CPPNamespace.typedef = TypeDef( 'CPPNamespace', @@ -836,7 +836,7 @@ W_ComplexCPPClass.typedef.acceptable_as_base_class = False -class W_CPPTemplateType(Wrappable): +class W_CPPTemplateType(W_Root): _attrs_ = ['space', 'name', 'handle'] _immutable_fields = ['name', 'handle'] @@ -859,7 +859,7 @@ W_CPPTemplateType.typedef.acceptable_as_base_class = False -class W_CPPInstance(Wrappable): +class W_CPPInstance(W_Root): _attrs_ = ['space', 'cppclass', '_rawobject', 'isref', 'python_owns'] _immutable_fields_ = ["cppclass", "isref"] diff --git a/pypy/module/gc/referents.py b/pypy/module/gc/referents.py --- a/pypy/module/gc/referents.py +++ b/pypy/module/gc/referents.py @@ -1,12 +1,12 @@ from rpython.rlib import rgc -from pypy.interpreter.baseobjspace import W_Root, Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.error import wrap_oserror, OperationError from rpython.rlib.objectmodel import we_are_translated -class W_GcRef(Wrappable): +class W_GcRef(W_Root): def __init__(self, gcref): self.gcref = gcref 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 @@ -1,28 +1,31 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from rpython.tool.pairtype import extendabletype from pypy.module.micronumpy.support import calc_strides from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation + def issequence_w(space, w_obj): return (space.isinstance_w(w_obj, space.w_tuple) or space.isinstance_w(w_obj, space.w_list) or isinstance(w_obj, W_NDimArray)) + class ArrayArgumentException(Exception): pass -class W_NDimArray(Wrappable): + +class W_NDimArray(W_Root): __metaclass__ = extendabletype def __init__(self, implementation): assert isinstance(implementation, BaseArrayImplementation) self.implementation = implementation - + @staticmethod def from_shape(shape, dtype, order='C'): from pypy.module.micronumpy.arrayimpl import concrete, scalar - + if not shape: impl = scalar.Scalar(dtype) else: @@ -40,7 +43,6 @@ backstrides, storage) return W_NDimArray(impl) - @staticmethod def new_slice(offset, strides, backstrides, shape, parent, orig_arr, dtype=None): from pypy.module.micronumpy.arrayimpl import concrete @@ -57,10 +59,11 @@ w_val = dtype.coerce(space, w_val) return W_NDimArray(scalar.Scalar(dtype, w_val)) + def convert_to_array(space, w_obj): from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy import interp_ufuncs - + if isinstance(w_obj, W_NDimArray): return w_obj elif issequence_w(space, w_obj): 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 @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -64,7 +64,8 @@ def convert_imag_to(self, dtype): return dtype.box(self.imag) -class W_GenericBox(Wrappable): + +class W_GenericBox(W_Root): _attrs_ = () def descr__new__(space, w_subtype, __args__): 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 @@ -1,6 +1,6 @@ import sys -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, @@ -44,7 +44,8 @@ out = base.W_NDimArray.from_shape(shape, dtype) return out -class W_Dtype(Wrappable): + +class W_Dtype(W_Root): _immutable_fields_ = ["itemtype", "num", "kind"] def __init__(self, itemtype, num, kind, name, char, w_box_type, 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 @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty @@ -16,7 +16,7 @@ def done_if_false(dtype, val): return not dtype.itemtype.bool(val) -class W_Ufunc(Wrappable): +class W_Ufunc(W_Root): _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex", "complex_to_float"] _immutable_fields_ = ["promote_to_float", "promote_bools", "name", diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, wrap_oserror -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from rpython.rlib import rmmap, rarithmetic @@ -11,7 +11,7 @@ OFF_T = int -class W_MMap(Wrappable): +class W_MMap(W_Root): def __init__(self, space, mmap_obj): self.space = space self.mmap = mmap_obj diff --git a/pypy/module/oracle/interp_connect.py b/pypy/module/oracle/interp_connect.py --- a/pypy/module/oracle/interp_connect.py +++ b/pypy/module/oracle/interp_connect.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.typedef import (TypeDef, interp_attrproperty_w, GetSetProperty) @@ -13,7 +13,8 @@ from pypy.module.oracle.interp_pool import W_SessionPool from pypy.module.oracle.interp_variable import VT_String -class W_Connection(Wrappable): + +class W_Connection(W_Root): def __init__(self): self.commitMode = roci.OCI_DEFAULT self.environment = None diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -13,7 +13,7 @@ # XXX are those "assert isinstance(xxx, interp_variable.W_Variable)" necessary? # the bindList should annotate to SomeList(SomeInstance(W_Variable)) -class W_Cursor(Wrappable): +class W_Cursor(W_Root): def __init__(self, space, connection): self.connection = connection self.environment = connection.environment diff --git a/pypy/module/oracle/interp_error.py b/pypy/module/oracle/interp_error.py --- a/pypy/module/oracle/interp_error.py +++ b/pypy/module/oracle/interp_error.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from rpython.rtyper.lltypesystem import rffi, lltype from pypy.interpreter.typedef import TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -45,10 +45,10 @@ datetime.datetime, datetime.date, datetime.timedelta) """)) -def get(space): - return space.fromcache(State) +def get(space): + return space.fromcache(State) -class W_Error(Wrappable): +class W_Error(W_Root): def __init__(self, space, environment, context, retrieveError): self.context = context if retrieveError: diff --git a/pypy/module/oracle/interp_lob.py b/pypy/module/oracle/interp_lob.py --- a/pypy/module/oracle/interp_lob.py +++ b/pypy/module/oracle/interp_lob.py @@ -1,11 +1,12 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError from pypy.module.oracle.interp_error import get -class W_ExternalLob(Wrappable): + +class W_ExternalLob(W_Root): def __init__(self, var, pos): self.lobVar = var self.pos = pos diff --git a/pypy/module/oracle/interp_object.py b/pypy/module/oracle/interp_object.py --- a/pypy/module/oracle/interp_object.py +++ b/pypy/module/oracle/interp_object.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -8,7 +8,7 @@ from pypy.module.oracle import roci, config, transform from pypy.module.oracle.interp_error import get -class W_ObjectType(Wrappable): +class W_ObjectType(W_Root): def __init__(self, connection, param): self.tdo = lltype.nullptr(roci.dvoidp.TO) self.environment = connection.environment @@ -287,7 +287,7 @@ attributes = GetSetProperty(W_ObjectType.get_attributes), ) -class W_ObjectAttribute(Wrappable): +class W_ObjectAttribute(W_Root): def __init__(self, connection, param): self.initialize(connection, param) @@ -340,7 +340,7 @@ name = interp_attrproperty('name', W_ObjectAttribute), ) -class W_ExternalObject(Wrappable): +class W_ExternalObject(W_Root): def __init__(self, var, objectType, instance, indicator, isIndependent=True): self.var = var # keepalive diff --git a/pypy/module/oracle/interp_pool.py b/pypy/module/oracle/interp_pool.py --- a/pypy/module/oracle/interp_pool.py +++ b/pypy/module/oracle/interp_pool.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -11,7 +11,8 @@ from pypy.module.oracle import interp_error, interp_environ from pypy.module.oracle.interp_error import get -class W_SessionPool(Wrappable): + +class W_SessionPool(W_Root): def __init__(self): self.environment = None diff --git a/pypy/module/oracle/interp_variable.py b/pypy/module/oracle/interp_variable.py --- a/pypy/module/oracle/interp_variable.py +++ b/pypy/module/oracle/interp_variable.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.typedef import interp_attrproperty from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -116,7 +116,7 @@ return var -class W_Variable(Wrappable): +class W_Variable(W_Root): charsetForm = roci.SQLCS_IMPLICIT isVariableLength = False canBeInArray = True diff --git a/pypy/module/parser/pyparser.py b/pypy/module/parser/pyparser.py --- a/pypy/module/parser/pyparser.py +++ b/pypy/module/parser/pyparser.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -8,8 +8,7 @@ from rpython.rlib.objectmodel import specialize -class STType(Wrappable): - +class STType(W_Root): def __init__(self, tree, mode): self.tree = tree self.mode = mode diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError @@ -212,7 +212,7 @@ global_storage = Storage() -class CallbackData(Wrappable): +class CallbackData(W_Root): def __init__(self, space, parser): self.space = space self.parser = weakref.ref(parser) @@ -414,8 +414,8 @@ def __init__(self, space): self.w_error = space.new_exception_class("pyexpat.ExpatError") -class W_XMLParserType(Wrappable): +class W_XMLParserType(W_Root): def __init__(self, space, parser, w_intern): self.itself = parser 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 @@ -1,7 +1,7 @@ from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError @@ -114,7 +114,8 @@ logops.repr_of_resop(op))) return l_w -class WrappedBox(Wrappable): + +class WrappedBox(W_Root): """ A class representing a single box """ def __init__(self, llbox): @@ -155,7 +156,8 @@ jit_hooks.resop_new(num, args, jit_hooks.emptyval()), repr, jd_name, call_depth, call_id, w_greenkey) -class WrappedOp(Wrappable): + +class WrappedOp(W_Root): """ A class representing a single ResOperation, wrapped nicely """ def __init__(self, op, offset, repr_of_resop): @@ -191,7 +193,7 @@ """ A class representing Debug Merge Point - the entry point to a jitted loop. """ - + def __init__(self, space, op, repr_of_resop, jd_name, call_depth, call_id, w_greenkey): @@ -249,15 +251,16 @@ ) DebugMergePoint.acceptable_as_base_class = False -class W_JitLoopInfo(Wrappable): + +class W_JitLoopInfo(W_Root): """ Loop debug information """ - + w_green_key = None bridge_no = 0 asmaddr = 0 asmlen = 0 - + def __init__(self, space, debug_info, is_bridge=False): logops = debug_info.logger._make_log_operations() if debug_info.asminfo is not None: @@ -266,7 +269,7 @@ ofs = {} self.w_ops = space.newlist( wrap_oplist(space, logops, debug_info.operations, ofs)) - + self.jd_name = debug_info.get_jitdriver().name self.type = debug_info.type if is_bridge: @@ -337,7 +340,8 @@ ) W_JitLoopInfo.acceptable_as_base_class = False -class W_JitInfoSnapshot(Wrappable): + +class W_JitInfoSnapshot(W_Root): def __init__(self, space, w_times, w_counters, w_counter_times): self.w_loop_run_times = w_times self.w_counters = w_counters diff --git a/pypy/module/select/interp_epoll.py b/pypy/module/select/interp_epoll.py --- a/pypy/module/select/interp_epoll.py +++ b/pypy/module/select/interp_epoll.py @@ -2,7 +2,7 @@ import errno -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError, operationerrfmt, exception_from_errno from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -69,7 +69,7 @@ ) -class W_Epoll(Wrappable): +class W_Epoll(W_Root): def __init__(self, space, epfd): self.epfd = epfd diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py --- a/pypy/module/select/interp_select.py +++ b/pypy/module/select/interp_select.py @@ -1,5 +1,5 @@ from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, wrap_oserror from rpython.rlib import rpoll @@ -16,7 +16,7 @@ unregistering file descriptors, and then polling them for I/O events.""" return Poll() -class Poll(Wrappable): +class Poll(W_Root): def __init__(self): self.fddict = {} diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py --- a/pypy/module/thread/os_local.py +++ b/pypy/module/thread/os_local.py @@ -1,11 +1,12 @@ import weakref from rpython.rlib import jit -from pypy.interpreter.baseobjspace import Wrappable, W_Root +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.typedef import (TypeDef, interp2app, GetSetProperty, descr_get_dict) from rpython.rlib.rshrinklist import AbstractShrinkList + class WRefShrinkList(AbstractShrinkList): def must_keep(self, wref): return wref() is not None @@ -14,7 +15,7 @@ ExecutionContext._thread_local_objs = None -class Local(Wrappable): +class Local(W_Root): """Thread-local data""" @jit.dont_look_inside diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -4,7 +4,7 @@ from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef @@ -23,8 +23,8 @@ ## sys.stderr.write(msg) -class Lock(Wrappable): - "A wrappable box around an interp-level lock object." +class Lock(W_Root): + "A box around an interp-level lock object." def __init__(self, space): self.space = space diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -1,5 +1,5 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -30,7 +30,7 @@ def get_error(space): return space.fromcache(Cache).w_error -class W_ZipCache(Wrappable): +class W_ZipCache(W_Root): def __init__(self): self.cache = {} @@ -114,7 +114,7 @@ zip_cache = W_ZipCache() -class W_ZipImporter(Wrappable): +class W_ZipImporter(W_Root): def __init__(self, space, name, filename, zip_file, prefix): self.space = space self.name = name @@ -125,7 +125,7 @@ def getprefix(self, space): if ZIPSEP == os.path.sep: return space.wrap(self.prefix) - return space.wrap(self.prefix.replace(ZIPSEP, os.path.sep)) + return space.wrap(self.prefix.replace(ZIPSEP, os.path.sep)) def _find_relative_path(self, filename): if filename.startswith(self.filename): @@ -406,4 +406,3 @@ archive = GetSetProperty(W_ZipImporter.getarchive), prefix = GetSetProperty(W_ZipImporter.getprefix), ) - diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py --- a/pypy/module/zlib/interp_zlib.py +++ b/pypy/module/zlib/interp_zlib.py @@ -1,6 +1,6 @@ import sys from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.error import OperationError from rpython.rlib.rarithmetic import intmask, r_uint @@ -109,7 +109,7 @@ return space.wrap(result) -class ZLibObject(Wrappable): +class ZLibObject(W_Root): """ Common base class for Compress and Decompress. """ diff --git a/pypy/objspace/fake/test/test_objspace.py b/pypy/objspace/fake/test/test_objspace.py --- a/pypy/objspace/fake/test/test_objspace.py +++ b/pypy/objspace/fake/test/test_objspace.py @@ -2,9 +2,9 @@ from pypy.objspace.fake.objspace import FakeObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.baseobjspace import Wrappable from rpython.rlib.unroll import unrolling_iterable + def test_create(): FakeObjSpace() @@ -55,7 +55,8 @@ def test_gettypefor(self): space = self.space - class W_Foo(Wrappable): + + class W_Foo(W_Root): typedef = TypeDef("foo") space.translates(lambda: space.gettypefor(W_Foo)) From noreply at buildbot.pypy.org Thu Mar 21 00:24:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 00:24:28 +0100 (CET) Subject: [pypy-commit] buildbot default: remove tannit-win32 and tannit lock for win32 Message-ID: <20130320232428.5872A1C1564@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r743:ddd91cb6c03e Date: 2013-03-20 19:24 -0400 http://bitbucket.org/pypy/buildbot/changeset/ddd91cb6c03e/ Log: remove tannit-win32 and tannit lock for win32 diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -441,11 +441,10 @@ 'category' : 'mac64', }, {"name": WIN32, - "slavenames": ["tannit-win32", "aurora"], + "slavenames": ["aurora"], "builddir": WIN32, "factory": pypyOwnTestFactoryWin, "category": 'win32', - "locks": [TannitCPU.access('counting')], }, {"name": WIN64, "slavenames": ["snakepit64"], @@ -454,18 +453,16 @@ "category": 'win32' }, {"name": APPLVLWIN32, - "slavenames": ["tannit-win32", "aurora"], + "slavenames": ["aurora"], "builddir": APPLVLWIN32, "factory": pypyTranslatedAppLevelTestFactoryWin, "category": "win32", - "locks": [TannitCPU.access('counting')], }, {"name" : JITWIN32, - "slavenames": ["tannit-win32", "aurora"], + "slavenames": ["aurora"], 'builddir' : JITWIN32, 'factory' : pypyJITTranslatedTestFactoryWin, 'category' : 'win32', - "locks": [TannitCPU.access('counting')], }, {"name" : JITWIN64, "slavenames": ["snakepit64"], From noreply at buildbot.pypy.org Thu Mar 21 00:42:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 00:42:19 +0100 (CET) Subject: [pypy-commit] buildbot default: allow own32 to run alongside translation: we're more limited by memory than CPU Message-ID: <20130320234219.A46D81C1513@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r744:4b28d80ac0bc Date: 2013-03-20 19:41 -0400 http://bitbucket.org/pypy/buildbot/changeset/4b28d80ac0bc/ Log: allow own32 to run alongside translation: we're more limited by memory than CPU diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -17,8 +17,8 @@ # translations in parallel, but then the actual benchmarks are run in # sequence. -# there are 8 logical CPUs, but only 4 physical ones, and only enough memory for 2 translations -TannitCPU = locks.MasterLock('tannit_cpu', maxCount=2) +# there are 8 logical CPUs, but only 4 physical ones, and only enough memory for ~3 translations +TannitCPU = locks.MasterLock('tannit_cpu', maxCount=3) SpeedPythonCPU = locks.MasterLock('speed_python_cpu', maxCount=24) #WinLockCPU = locks.MasterLock('win_cpu', maxCount=1) diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -337,16 +337,14 @@ "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'linux32', - # this build needs 4 CPUs - "locks": [TannitCPU.access('exclusive')], + "locks": [TannitCPU.access('counting')], }, {"name": LINUX64, "slavenames": ["allegro64"], "builddir": LINUX64, "factory": pypyOwnTestFactory, "category": 'linux64', - # this build needs 4 CPUs - #"locks": [TannitCPU.access('exclusive')], + #"locks": [TannitCPU.access('counting')], }, {"name": APPLVLLINUX32, #"slavenames": ["allegro32"], From noreply at buildbot.pypy.org Thu Mar 21 00:58:00 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 21 Mar 2013 00:58:00 +0100 (CET) Subject: [pypy-commit] pypy default: removed a C file that was unused Message-ID: <20130320235800.75A2F1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62593:849bdb0dca78 Date: 2013-03-20 16:57 -0700 http://bitbucket.org/pypy/pypy/changeset/849bdb0dca78/ Log: removed a C file that was unused diff --git a/rpython/translator/tool/__thread_test.c b/rpython/translator/tool/__thread_test.c deleted file mode 100644 --- a/rpython/translator/tool/__thread_test.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -#define N 100000000 - -#if defined(__GNUC__) && defined(_POSIX_THREADS) -#include - -void * th_f(void *x) { - volatile int * n = (volatile int *)x; - static __thread int i = 0; - int delta; - delta = *n; - for (; i < N; i++) { - *n += delta; - } - return NULL; -} - -int nbs[] = {2, 3}; - -int main() { - pthread_t t0, t1; - pthread_create(&t0, NULL, th_f, &nbs[0]); - pthread_create(&t1, NULL, th_f, &nbs[1]); - pthread_join(t0, NULL); - pthread_join(t1, NULL); - printf("1= %d\n", nbs[0]); - printf("2= %d\n", nbs[1]); - return !(nbs[0] == (N+1)*2 && nbs[1] == (N+1)*3); -} - -#else -#error "Meaningful only with GCC (+ POSIX Threads)" -#endif From noreply at buildbot.pypy.org Thu Mar 21 01:10:23 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Thu, 21 Mar 2013 01:10:23 +0100 (CET) Subject: [pypy-commit] pypy numpy-pickle: Implement pickle for dtypes Message-ID: <20130321001023.8B2581C03A7@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: numpy-pickle Changeset: r62594:3a23062660aa Date: 2013-03-20 18:50 +0100 http://bitbucket.org/pypy/pypy/changeset/3a23062660aa/ Log: Implement pickle for dtypes 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 @@ -177,6 +177,36 @@ def get_size(self): return self.itemtype.get_element_size() + def descr_reduce(self, space): + w_class = space.type(self) + + kind = self.kind + elemsize = self.itemtype.get_element_size() + builder_args = space.newtuple([space.wrap("%s%d" % (kind, elemsize)), space.wrap(0), space.wrap(1)]) + + version = space.wrap(3) + order = space.wrap(byteorder_prefix if self.native else nonnative_byteorder_prefix) + names = self.descr_get_names(space) + values = self.descr_get_fields(space) + #TODO: Change this when alignment is implemented : + if self.fields: + #TODO: Implement this when subarrays are implemented + subdescr = space.w_None + size = 0 + for key in self.fields: + size += self.fields[key].get_size() + w_size = space.wrap(size) + alignment = space.wrap(1) + else: + subdescr = space.w_None + w_size = space.wrap(-1) + alignment = space.wrap(-1) + flags = space.wrap(0) + + data = space.newtuple([version, order, subdescr, names, values, w_size, alignment, flags]) + + return space.newtuple([w_class, builder_args, data]) + class W_ComplexDtype(W_Dtype): def __init__(self, itemtype, num, kind, name, char, w_box_type, alternate_constructors=[], aliases=[], @@ -249,7 +279,7 @@ def dtype_from_spec(space, name): raise OperationError(space.w_NotImplementedError, space.wrap( - "dtype from spec")) + "dtype from spec")) def descr__new__(space, w_subtype, w_dtype): cache = get_dtype_cache(space) @@ -291,6 +321,8 @@ __ne__ = interp2app(W_Dtype.descr_ne), __getitem__ = interp2app(W_Dtype.descr_getitem), + __reduce__ = interp2app(W_Dtype.descr_reduce), + num = interp_attrproperty("num", cls=W_Dtype), kind = interp_attrproperty("kind", cls=W_Dtype), char = interp_attrproperty("char", cls=W_Dtype), 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 @@ -14,7 +14,7 @@ from rpython.rtyper.lltypesystem import rffi ptr_size = rffi.sizeof(rffi.CCHARP) cls.w_ptr_size = cls.space.wrap(ptr_size) - + class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): from numpypy import dtype @@ -148,7 +148,7 @@ def test_bool_binop_types(self): from numpypy import array, dtype types = [ - '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', + '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' ] a = array([True], '?') @@ -269,6 +269,10 @@ ]: assert hash(tp(value)) == hash(value) + def test_pickle(self): + from numpypy import array, dtype + assert array([1,2,3]).dtype.__reduce__() == (dtype, ('i8', 0, 1), (3, '<', None, None, None, -1, -1, 0)) + class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): @@ -339,7 +343,7 @@ import numpypy as numpy assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, - numpy.integer, numpy.number, + numpy.integer, numpy.number, numpy.generic, object] a = numpy.array([1, 2, 3], numpy.int8) @@ -362,8 +366,8 @@ def test_uint8(self): import numpypy as numpy - assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, - numpy.integer, numpy.number, + assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, + numpy.integer, numpy.number, numpy.generic, object] a = numpy.array([1, 2, 3], numpy.uint8) @@ -434,8 +438,8 @@ import numpypy as numpy assert numpy.int_ is numpy.dtype(int).type - assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, - numpy.integer, numpy.number, + assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, + numpy.integer, numpy.number, numpy.generic, int, object] def test_int64(self): @@ -443,12 +447,12 @@ import numpypy as numpy if sys.maxint == 2 ** 63 -1: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, - numpy.integer, numpy.number, + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, numpy.generic, int, object] else: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, - numpy.integer, numpy.number, + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, numpy.generic, object] assert numpy.dtype(numpy.int64).type is numpy.int64 @@ -464,8 +468,8 @@ import sys import numpypy as numpy - assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, - numpy.integer, numpy.number, + assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, + numpy.integer, numpy.number, numpy.generic, object] assert numpy.dtype(numpy.uint64).type is numpy.uint64 @@ -480,8 +484,8 @@ def test_float16(self): import numpypy as numpy - assert numpy.float16.mro() == [numpy.float16, numpy.floating, - numpy.inexact, numpy.number, + assert numpy.float16.mro() == [numpy.float16, numpy.floating, + numpy.inexact, numpy.number, numpy.generic, object] assert numpy.float16(12) == numpy.float64(12) @@ -492,8 +496,8 @@ def test_float32(self): import numpypy as numpy - assert numpy.float32.mro() == [numpy.float32, numpy.floating, - numpy.inexact, numpy.number, + assert numpy.float32.mro() == [numpy.float32, numpy.floating, + numpy.inexact, numpy.number, numpy.generic, object] assert numpy.float32(12) == numpy.float64(12) @@ -503,8 +507,8 @@ def test_float64(self): import numpypy as numpy - assert numpy.float64.mro() == [numpy.float64, numpy.floating, - numpy.inexact, numpy.number, + assert numpy.float64.mro() == [numpy.float64, numpy.floating, + numpy.inexact, numpy.number, numpy.generic, float, object] a = numpy.array([1, 2, 3], numpy.float64) @@ -829,7 +833,7 @@ # it can be float96 or float128 if numpy.longfloat != numpy.float64: assert numpy.longfloat.mro()[1:] == [numpy.floating, - numpy.inexact, numpy.number, + numpy.inexact, numpy.number, numpy.generic, object] a = numpy.array([1, 2, 3], numpy.longdouble) assert type(a[1]) is numpy.longdouble @@ -871,3 +875,4 @@ a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble assert a[0] == 1 assert (a + a)[1] == 4 + From noreply at buildbot.pypy.org Thu Mar 21 01:10:24 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Thu, 21 Mar 2013 01:10:24 +0100 (CET) Subject: [pypy-commit] pypy numpy-pickle: Implement pickling for dtypes Message-ID: <20130321001024.DD7BC1C03A7@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: numpy-pickle Changeset: r62595:ef6ba39d4901 Date: 2013-03-21 01:09 +0100 http://bitbucket.org/pypy/pypy/changeset/ef6ba39d4901/ Log: Implement pickling for dtypes 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 @@ -130,11 +130,40 @@ space.wrap(offset)])) return w_d + def set_fields(self, space, w_fields): + if w_fields == space.w_None: + self.fields = {} + else: + iter = space.iter(w_fields) + while True: + try: + key = space.next(iter) + value = space.getitem(w_fields, key) + self.fields[space.str_w(space.next(iter))] = space.int_w(space.getitem(value, 1)), space.getitem(value, 0) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + def descr_get_names(self, space): if self.fieldnames is None: return space.w_None return space.newtuple([space.wrap(name) for name in self.fieldnames]) + def set_names(self, space, w_names): + if w_names == space.w_None: + self.fieldnames = None + else: + self.fieldnames = [] + iter = space.iter(w_names) + while True: + try: + self.fieldnames.append(space.str_w(space.next(iter))) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + @unwrap_spec(item=str) def descr_getitem(self, space, item): if self.fields is None: @@ -188,10 +217,10 @@ order = space.wrap(byteorder_prefix if self.native else nonnative_byteorder_prefix) names = self.descr_get_names(space) values = self.descr_get_fields(space) - #TODO: Change this when alignment is implemented : if self.fields: #TODO: Implement this when subarrays are implemented subdescr = space.w_None + #TODO: Change this when alignment is implemented : size = 0 for key in self.fields: size += self.fields[key].get_size() @@ -207,6 +236,16 @@ return space.newtuple([w_class, builder_args, data]) + def descr_setstate(self, space, w_data): + if space.int_w(space.getitem(w_data, space.wrap(0))) != 3: + raise OperationError(space.w_NotImplementedError, space.wrap("Pickling protocol version not supported")) + + self.native = space.getitem(w_data, space.wrap(1)) == byteorder_prefix + + fieldnames = space.getitem(w_data, space.wrap(2)) + self.set_names(space, fieldnames) + self.set_fields(space, space.getitem(w_data, space.wrap(3))) + class W_ComplexDtype(W_Dtype): def __init__(self, itemtype, num, kind, name, char, w_box_type, alternate_constructors=[], aliases=[], @@ -281,7 +320,8 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "dtype from spec")) -def descr__new__(space, w_subtype, w_dtype): +def descr__new__(space, w_subtype, w_dtype, w_align=None, w_copy=None): + # w_align and w_copy are necessary for pickling cache = get_dtype_cache(space) if space.is_none(w_dtype): @@ -322,6 +362,7 @@ __getitem__ = interp2app(W_Dtype.descr_getitem), __reduce__ = interp2app(W_Dtype.descr_reduce), + __setstate__ = interp2app(W_Dtype.descr_setstate), num = interp_attrproperty("num", cls=W_Dtype), kind = interp_attrproperty("kind", cls=W_Dtype), 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 @@ -16,6 +16,7 @@ cls.w_ptr_size = cls.space.wrap(ptr_size) class AppTestDtypes(BaseAppTestDtypes): + spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"]) def test_dtype(self): from numpypy import dtype @@ -271,8 +272,11 @@ def test_pickle(self): from numpypy import array, dtype - assert array([1,2,3]).dtype.__reduce__() == (dtype, ('i8', 0, 1), (3, '<', None, None, None, -1, -1, 0)) - + from cPickle import loads, dumps + a = array([1,2,3]) + assert a.dtype.__reduce__() == (dtype, ('i8', 0, 1), (3, '<', None, None, None, -1, -1, 0)) + import pdb; pdb.set_trace() + assert loads(dumps(a.dtype)) == a.dtype class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): From noreply at buildbot.pypy.org Thu Mar 21 01:34:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 01:34:14 +0100 (CET) Subject: [pypy-commit] pypy default: clean up the pickle StringBuilder modifications Message-ID: <20130321003414.0CBA21C03A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62596:3252c980a8b1 Date: 2013-03-20 20:32 -0400 http://bitbucket.org/pypy/pypy/changeset/3252c980a8b1/ Log: clean up the pickle StringBuilder modifications diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,8 +34,6 @@ import struct import re -from __pypy__.builders import StringBuilder - __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1411,18 +1409,19 @@ except ImportError: from StringIO import StringIO - -class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - - def getvalue(self): - return self.builder.build() - +try: + from __pypy__.builders import StringBuilder +except ImportError: + StringBuilderFile = StringIO +else: + class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + self.write = self.builder.append + self.getvalue = self.builder.build def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -96,18 +96,18 @@ # closer to the ones produced by cPickle in CPython from pickle import StringIO + try: from pickle import StringBuilderFile except ImportError: - assert '__pypy__' not in sys.builtin_module_names - from pickle import StringIO as StringBuilderFile + StringBuilderFile = StringIO PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringIO() + self.__f = StringBuilderFile() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) From noreply at buildbot.pypy.org Thu Mar 21 01:56:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 01:56:44 +0100 (CET) Subject: [pypy-commit] pypy default: some sanity checks so these don't silently fail if __pypy__ items are moved around Message-ID: <20130321005644.83D8E1C019F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62597:6c2989efb370 Date: 2013-03-20 20:56 -0400 http://bitbucket.org/pypy/pypy/changeset/6c2989efb370/ Log: some sanity checks so these don't silently fail if __pypy__ items are moved around diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -15,6 +15,7 @@ try: from __pypy__ import newdict except ImportError: + assert '__pypy__' not in sys.builtin_module_names newdict = lambda _ : {} try: diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1412,6 +1412,7 @@ try: from __pypy__.builders import StringBuilder except ImportError: + assert '__pypy__' not in sys.builtin_module_names StringBuilderFile = StringIO else: class StringBuilderFile(object): diff --git a/lib-python/2/sre_parse.py b/lib-python/2/sre_parse.py --- a/lib-python/2/sre_parse.py +++ b/lib-python/2/sre_parse.py @@ -19,8 +19,8 @@ try: from __pypy__ import newdict except ImportError: - def newdict(tp): - return {} + assert '__pypy__' not in sys.builtin_module_names + newdict = lambda _ : {} SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" From noreply at buildbot.pypy.org Thu Mar 21 01:58:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 01:58:45 +0100 (CET) Subject: [pypy-commit] pypy default: typo Message-ID: <20130321005845.709B01C019F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62598:7c63dc3c19ab Date: 2013-03-20 20:58 -0400 http://bitbucket.org/pypy/pypy/changeset/7c63dc3c19ab/ Log: typo diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -15,7 +15,7 @@ try: from __pypy__ import newdict except ImportError: - assert '__pypy__' not in sys.builtin_module_names + assert '__pypy__' not in _sys.builtin_module_names newdict = lambda _ : {} try: From noreply at buildbot.pypy.org Thu Mar 21 02:32:21 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 21 Mar 2013 02:32:21 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: initial/experimental support for accessing macro's (CINT-only) Message-ID: <20130321013221.DC6AA1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62599:6f7196e584fc Date: 2013-03-20 16:18 -0700 http://bitbucket.org/pypy/pypy/changeset/6f7196e584fc/ Log: initial/experimental support for accessing macro's (CINT-only) diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py --- a/pypy/module/cppyy/converter.py +++ b/pypy/module/cppyy/converter.py @@ -581,6 +581,14 @@ Py_DecRef(space, rffi.cast(PyObject, rffi.cast(rffi.VOIDPP, arg)[0])) +class MacroConverter(TypeConverter): + def from_memory(self, space, w_obj, w_pycppclass, offset): + # TODO: get the actual type info from somewhere ... + address = self._get_raw_address(space, w_obj, offset) + longptr = rffi.cast(rffi.LONGP, address) + return space.wrap(longptr[0]) + + _converters = {} # builtin and custom types _a_converters = {} # array and ptr versions of above def get_converter(space, name, default): @@ -660,6 +668,8 @@ _converters["PyObject*"] = PyObjectConverter +_converters["#define"] = MacroConverter + # add basic (builtin) converters def _build_basic_converters(): "NOT_RPYTHON" diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py --- a/pypy/module/cppyy/test/test_cint.py +++ b/pypy/module/cppyy/test/test_cint.py @@ -507,3 +507,19 @@ gROOT.SetDirLevel(3) assert 3 == TROOT.GetDirLevel() TROOT.SetDirLevel(old) + + def test07_macro(self): + """Test access to cpp macro's""" + + from cppyy import gbl + + assert gbl.NULL == 0 + + gbl.gROOT.ProcessLine('#define aap "aap"') + gbl.gROOT.ProcessLine('#define noot 1') + gbl.gROOT.ProcessLine('#define mies 2.0') + + # TODO: macro's assumed to always be of long type ... + #assert gbl.aap == "aap" + assert gbl.noot == 1 + #assert gbl.mies == 2.0 From noreply at buildbot.pypy.org Thu Mar 21 02:32:23 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 21 Mar 2013 02:32:23 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: allow bind_object to take a string (the class name) instead of the class itself Message-ID: <20130321013223.40F871C13F4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62600:f81426f91525 Date: 2013-03-20 17:17 -0700 http://bitbucket.org/pypy/pypy/changeset/f81426f91525/ Log: allow bind_object to take a string (the class name) instead of the class itself diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -1109,5 +1109,7 @@ """Takes an address and a bound C++ class proxy, returns a bound instance.""" rawobject = rffi.cast(capi.C_OBJECT, address) w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy")) + if not w_cppclass: + w_cppclass = scope_byname(space, space.str_w(w_pycppclass)) cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False) return wrap_cppobject(space, rawobject, cppclass, do_cast=False, python_owns=owns) diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -402,6 +402,9 @@ o = some_concrete_class() + # TODO: figure out the PyPy equivalent of CObject (may have to do this + # through the C-API from C++) + #cobj = cppyy.as_cobject(o) addr = cppyy.addressof(o) @@ -413,7 +416,8 @@ assert o == cppyy.bind_object(addr, some_concrete_class) assert o == cppyy.bind_object(addr, type(o)) assert o == cppyy.bind_object(addr, o.__class__) - #assert o == cppyy.bind_object(addr, "some_concrete_class") + assert o == cppyy.bind_object(addr, "some_concrete_class") + raises(TypeError, cppyy.bind_object, addr, 1) def test10_object_identity(self): """Test object identity""" From noreply at buildbot.pypy.org Thu Mar 21 02:32:24 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 21 Mar 2013 02:32:24 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: better error reporting for bind_object and associated test Message-ID: <20130321013224.833301C0EB1@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62601:1689e35140bf Date: 2013-03-20 17:35 -0700 http://bitbucket.org/pypy/pypy/changeset/1689e35140bf/ Log: better error reporting for bind_object and associated test diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -1111,5 +1111,8 @@ w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy")) if not w_cppclass: w_cppclass = scope_byname(space, space.str_w(w_pycppclass)) + if not w_cppclass: + raise OperationError(space.w_TypeError, + space.wrap("no such class: %s" % space.str_w(w_pycppclass))) cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False) return wrap_cppobject(space, rawobject, cppclass, do_cast=False, python_owns=owns) diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -417,6 +417,7 @@ assert o == cppyy.bind_object(addr, type(o)) assert o == cppyy.bind_object(addr, o.__class__) assert o == cppyy.bind_object(addr, "some_concrete_class") + raises(TypeError, cppyy.bind_object, addr, "does_not_exist") raises(TypeError, cppyy.bind_object, addr, 1) def test10_object_identity(self): From noreply at buildbot.pypy.org Thu Mar 21 02:32:25 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 21 Mar 2013 02:32:25 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: adding some more ROOT-based tests (CINT only) for completeness Message-ID: <20130321013225.AF4BB1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62602:4661b4e901ee Date: 2013-03-20 17:38 -0700 http://bitbucket.org/pypy/pypy/changeset/4661b4e901ee/ Log: adding some more ROOT-based tests (CINT only) for completeness diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py --- a/pypy/module/cppyy/test/test_cint.py +++ b/pypy/module/cppyy/test/test_cint.py @@ -523,3 +523,19 @@ #assert gbl.aap == "aap" assert gbl.noot == 1 #assert gbl.mies == 2.0 + + def test08_opaque_pointer_passing(self): + """Test passing around of opaque pointers""" + + import cppyy + + # TODO: figure out CObject (see also test_advanced.py) + + s = cppyy.gbl.TString("Hello World!") + #cobj = cppyy.as_cobject(s) + addr = cppyy.addressof(s) + + #assert s == cppyy.bind_object(cobj, s.__class__) + #assert s == cppyy.bind_object(cobj, "TString") + assert s == cppyy.bind_object(addr, s.__class__) + assert s == cppyy.bind_object(addr, "TString") From noreply at buildbot.pypy.org Thu Mar 21 02:32:26 2013 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 21 Mar 2013 02:32:26 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: allow comparisons to None (and have them respond sanely) Message-ID: <20130321013226.DFD071C0EB1@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62603:9d5aae59d25e Date: 2013-03-20 18:24 -0700 http://bitbucket.org/pypy/pypy/changeset/9d5aae59d25e/ Log: allow comparisons to None (and have them respond sanely) diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -937,6 +937,10 @@ return None def instance__eq__(self, w_other): + # special case: if other is None, compare pointer-style + if self.space.is_w(w_other, self.space.w_None): + return self.space.wrap(not self._rawobject) + # get here if no class-specific overloaded operator is available, try to # find a global overload in gbl, in __gnu_cxx (for iterators), or in the # scopes of the argument classes (TODO: implement that last option) diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py --- a/pypy/module/cppyy/pythonify.py +++ b/pypy/module/cppyy/pythonify.py @@ -301,6 +301,24 @@ # general note: use 'in pyclass.__dict__' rather than 'hasattr' to prevent # adding pythonizations multiple times in derived classes + # map __eq__/__ne__ through a comparison to None + if '__eq__' in pyclass.__dict__: + def __eq__(self, other): + if other is None: return not self + if type(self) is not type(other): return False + if not self and not other: return True + return self._cxx_eq(other) + pyclass._cxx_eq = pyclass.__dict__['__eq__'] + pyclass.__eq__ = __eq__ + + if '__ne__' in pyclass.__dict__: + def __ne__(self, other): + if other is None: return not not self + if type(self) is not type(other): return True + return self._cxx_ne(other) + pyclass._cxx_ne = pyclass.__dict__['__ne__'] + pyclass.__ne__ = __ne__ + # map size -> __len__ (generally true for STL) if 'size' in pyclass.__dict__ and not '__len__' in pyclass.__dict__ \ and callable(pyclass.size): diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py --- a/pypy/module/cppyy/test/test_cint.py +++ b/pypy/module/cppyy/test/test_cint.py @@ -539,3 +539,40 @@ #assert s == cppyy.bind_object(cobj, "TString") assert s == cppyy.bind_object(addr, s.__class__) assert s == cppyy.bind_object(addr, "TString") + + def test09_object_and_pointer_comparisons(self): + """Verify object and pointer comparisons""" + + import cppyy + gbl = cppyy.gbl + + c1 = cppyy.bind_object(0, gbl.TCanvas) + assert c1 == None + assert None == c1 + + c2 = cppyy.bind_object(0, gbl.TCanvas) + assert c1 == c2 + assert c2 == c1 + + # TLorentzVector overrides operator== + l1 = cppyy.bind_object(0, gbl.TLorentzVector) + assert l1 == None + assert None == l1 + + assert c1 != l1 + assert l1 != c1 + + l2 = cppyy.bind_object(0, gbl.TLorentzVector) + assert l1 == l2 + assert l2 == l1 + + l3 = gbl.TLorentzVector(1, 2, 3, 4) + l4 = gbl.TLorentzVector(1, 2, 3, 4) + l5 = gbl.TLorentzVector(4, 3, 2, 1) + assert l3 == l4 + assert l4 == l3 + + assert l3 != None # like this to ensure __ne__ is called + assert None != l3 # id. + assert l3 != l5 + assert l5 != l3 diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py --- a/pypy/module/cppyy/test/test_datatypes.py +++ b/pypy/module/cppyy/test/test_datatypes.py @@ -583,7 +583,44 @@ c.destruct() - def test16_object_validity(self): + def test16_object_and_pointer_comparisons(self): + """Verify object and pointer comparisons""" + + import cppyy + gbl = cppyy.gbl + + c1 = cppyy.bind_object(0, gbl.cppyy_test_data) + assert c1 == None + assert None == c1 + + c2 = cppyy.bind_object(0, gbl.cppyy_test_data) + assert c1 == c2 + assert c2 == c1 + + # four_vector overrides operator== + l1 = cppyy.bind_object(0, gbl.four_vector) + assert l1 == None + assert None == l1 + + assert c1 != l1 + assert l1 != c1 + + l2 = cppyy.bind_object(0, gbl.four_vector) + assert l1 == l2 + assert l2 == l1 + + l3 = gbl.four_vector(1, 2, 3, 4) + l4 = gbl.four_vector(1, 2, 3, 4) + l5 = gbl.four_vector(4, 3, 2, 1) + assert l3 == l4 + assert l4 == l3 + + assert l3 != None # like this to ensure __ne__ is called + assert None != l3 # id. + assert l3 != l5 + assert l5 != l3 + + def test17_object_validity(self): """Test object validity checking""" from cppyy import gbl @@ -597,7 +634,7 @@ assert not d2 - def test17_buffer_reshaping(self): + def test18_buffer_reshaping(self): """Test usage of buffer sizing""" import cppyy From noreply at buildbot.pypy.org Thu Mar 21 03:07:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 03:07:25 +0100 (CET) Subject: [pypy-commit] pypy default: another sanity check for a __pypy__ import Message-ID: <20130321020725.76C1B1C019F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62604:22ae273e67c1 Date: 2013-03-20 22:06 -0400 http://bitbucket.org/pypy/pypy/changeset/22ae273e67c1/ Log: another sanity check for a __pypy__ import diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -100,6 +100,7 @@ try: from pickle import StringBuilderFile except ImportError: + assert '__pypy__' not in sys.builtin_module_names StringBuilderFile = StringIO PythonPickler = Pickler From noreply at buildbot.pypy.org Thu Mar 21 05:19:22 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:22 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: a branch to sort the nightlies page by directory modification time, with trunk on top Message-ID: <20130321041922.B5BFF1C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r745:578d497c6b64 Date: 2013-03-20 19:16 -0700 http://bitbucket.org/pypy/buildbot/changeset/578d497c6b64/ Log: a branch to sort the nightlies page by directory modification time, with trunk on top diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -60,6 +60,21 @@ 'pypy-c-stackless-10000-linux.tar.bz2', ] +def test_dir_render(tmpdir): + import os, time + tmpdir.mkdir('trunk') + for ascii in range(ord('a'), ord('m')): + tmpdir.mkdir(chr(ascii) * 4) + time.sleep(0.1) + from twisted.web.test.test_web import DummyRequest + pypylist = PyPyList(tmpdir.dirname) + listener = pypylist.directoryListing() + request = DummyRequest([os.path.dirname(__file__)]) + page = listener.render(request) + for ascii in range(ord('a'), ord('m') - 1): + assert page.find(chr(ascii) * 4) > page.find((chr(ascii) + 1) * 4) + assert page.find('trunk') < page.find('mmm') + def load_BuildmasterConfig(): import os from pypybuildbot import summary, builds From noreply at buildbot.pypy.org Thu Mar 21 05:19:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:23 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: add a passing test for sorting directories Message-ID: <20130321041923.E7E661C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r746:95d5e9d16d87 Date: 2013-03-20 18:35 -0700 http://bitbucket.org/pypy/buildbot/changeset/95d5e9d16d87/ Log: add a passing test for sorting directories diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -1,5 +1,5 @@ import py -from pypybuildbot.pypylist import PyPyTarball +from pypybuildbot.pypylist import PyPyTarball, PyPyList def test_pypytarball_svn(): t = PyPyTarball('pypy-c-jit-75654-linux.tar.bz2') @@ -12,6 +12,7 @@ assert t.platform == 'linux' assert t.vcs == 'svn' + def test_pypytarball_hg(): t = PyPyTarball('pypy-c-jit-75654-foo-linux.tar.bz2') assert t.filename == 'pypy-c-jit-75654-foo-linux.tar.bz2' @@ -23,6 +24,7 @@ assert t.platform == 'linux' assert t.vcs == 'hg' + def test_invalid_filename(): t = PyPyTarball('foo') assert t.vcs == None @@ -60,6 +62,12 @@ 'pypy-c-stackless-10000-linux.tar.bz2', ] +def test_pypy_list(): + import os + pypylist = PyPyList(os.path.dirname(__file__)) + files = pypylist.listNames() + assert os.path.basename(__file__) in files + def test_dir_render(tmpdir): import os, time tmpdir.mkdir('trunk') @@ -85,7 +93,7 @@ return builds else: assert False - + this = py.path.local(__file__) master_py = this.dirpath().dirpath().join('master.py') glob = {'httpPortNumber': 80, @@ -106,13 +114,13 @@ assert app == expected_app assert own in builders or own in known_exceptions assert app in builders or app in known_exceptions - + t = PyPyTarball('pypy-c-jit-76867-linux.tar.bz2') check_builder_names(t, 'own-linux-x86-32', 'pypy-c-jit-linux-x86-32') t = PyPyTarball('pypy-c-nojit-76867-linux.tar.bz2') check_builder_names(t, 'own-linux-x86-32', 'pypy-c-app-level-linux-x86-32') - + t = PyPyTarball('pypy-c-jit-76867-osx.tar.bz2') check_builder_names(t, 'own-macosx-x86-32', 'pypy-c-jit-macosx-x86-32') From noreply at buildbot.pypy.org Thu Mar 21 05:19:25 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:25 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: extend test to check for correct sorting Message-ID: <20130321041925.174141C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r747:e7faa72fce49 Date: 2013-03-20 19:54 -0700 http://bitbucket.org/pypy/buildbot/changeset/e7faa72fce49/ Log: extend test to check for correct sorting diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -70,17 +70,20 @@ def test_dir_render(tmpdir): import os, time + # Create a bunch of directories, including one named trunk, + # Make sure the time order is reversed collation order tmpdir.mkdir('trunk') for ascii in range(ord('a'), ord('m')): tmpdir.mkdir(chr(ascii) * 4) time.sleep(0.1) from twisted.web.test.test_web import DummyRequest - pypylist = PyPyList(tmpdir.dirname) + pypylist = PyPyList(tmpdir.strpath) listener = pypylist.directoryListing() - request = DummyRequest([os.path.dirname(__file__)]) + request = DummyRequest([os.path.dirname(tmpdir.strpath)]) page = listener.render(request) + tmpdir.join('index.html').write(page) for ascii in range(ord('a'), ord('m') - 1): - assert page.find(chr(ascii) * 4) > page.find((chr(ascii) + 1) * 4) + assert page.find(chr(ascii) * 4) > page.find((chr(ascii + 1)) * 4) assert page.find('trunk') < page.find('mmm') def load_BuildmasterConfig(): From noreply at buildbot.pypy.org Thu Mar 21 05:19:26 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:26 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: refactor test to use PyPyList, start to fix code Message-ID: <20130321041926.217321C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r748:8aecca90aba5 Date: 2013-03-20 20:22 -0700 http://bitbucket.org/pypy/buildbot/changeset/8aecca90aba5/ Log: refactor test to use PyPyList, start to fix code diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -106,22 +106,28 @@ class PyPyList(File): - def listNames(self): - names = File.listNames(self) + def sortBuildNames(self, names): + items = map(PyPyTarball, names) + items.sort(key=PyPyTarball.key, reverse=True) + return [item.filename for item in items] + + def sortDirectoryNames(self, names): items = map(PyPyTarball, names) items.sort(key=PyPyTarball.key, reverse=True) return [item.filename for item in items] def directoryListing(self): - def is_pypy_dir(names): - for name in names: + def is_pypy_dir(names_unsorted): + for name in names_unsorted: if name.startswith('pypy-c'): return True return False - names = self.listNames() - if is_pypy_dir(names): + names_unsorted = File.listNames(self) + if is_pypy_dir(names_unsorted): + names = self.sortBuildNames(names_unsorted) Listener = PyPyDirectoryLister else: + names = self.sortDirectoryNames(names_unsorted) Listener = DirectoryLister return Listener(self.path, names, diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -37,8 +37,8 @@ t2 = PyPyTarball('pypy-c-jit-75654-linux.tar.bz2') assert t.key() < t2.key() -def test_sort(): - files = map(PyPyTarball, [ +def test_sort(tmpdir): + files = [ 'pypy-c-jit-10000-linux.tar.bz2', 'pypy-c-jit-20000-linux.tar.bz2', 'pypy-c-nojit-10000-linux.tar.bz2', @@ -47,11 +47,11 @@ 'pypy-c-stackless-10000-linux.tar.bz2', 'pypy-c-jit-1000-e5b73981fc8d-linux.tar.bz2', # this is mercurial based 'pypy-c-jit-10000-linux-armel.tar.bz2', - ]) - - files.sort(key=PyPyTarball.key, reverse=True) - files = [f.filename for f in files] - assert files == [ + ] + [tmpdir.join(f).write(f) for f in files] + pypylist = PyPyList(tmpdir.strpath) + listener = pypylist.directoryListing() + assert listener.dirs == [ 'pypy-c-jit-1000-e5b73981fc8d-linux.tar.bz2', # mercurial first 'pypy-c-jit-20000-linux.tar.bz2', 'pypy-c-jit-10000-linux.tar.bz2', @@ -62,7 +62,7 @@ 'pypy-c-stackless-10000-linux.tar.bz2', ] -def test_pypy_list(): +def test_pypy_list(tmpdir): import os pypylist = PyPyList(os.path.dirname(__file__)) files = pypylist.listNames() @@ -70,13 +70,13 @@ def test_dir_render(tmpdir): import os, time + from twisted.web.test.test_web import DummyRequest # Create a bunch of directories, including one named trunk, # Make sure the time order is reversed collation order tmpdir.mkdir('trunk') for ascii in range(ord('a'), ord('m')): tmpdir.mkdir(chr(ascii) * 4) time.sleep(0.1) - from twisted.web.test.test_web import DummyRequest pypylist = PyPyList(tmpdir.strpath) listener = pypylist.directoryListing() request = DummyRequest([os.path.dirname(tmpdir.strpath)]) From noreply at buildbot.pypy.org Thu Mar 21 05:19:27 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:27 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: skeleton class for 'sort by last mod time' Message-ID: <20130321041927.34AF81C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r749:da80658bb619 Date: 2013-03-20 20:26 -0700 http://bitbucket.org/pypy/buildbot/changeset/da80658bb619/ Log: skeleton class for 'sort by last mod time' diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -103,6 +103,19 @@ def display_in_italic(self): return self.vcs == 'latest' +class PyPyDirectory(object): + def __init__(self, filename): + self.filename = filename + try: + self.parse_filename() + except ValueError: + self.last_mod_time = 0 + + def parse_filename(self): + raise ValueError + + def key(self): + return (self.last_mod_time) class PyPyList(File): From noreply at buildbot.pypy.org Thu Mar 21 05:19:28 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:28 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: simplify test, implement sorting Message-ID: <20130321041928.4F8121C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r750:06b4a174180c Date: 2013-03-20 21:08 -0700 http://bitbucket.org/pypy/buildbot/changeset/06b4a174180c/ Log: simplify test, implement sorting diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -1,11 +1,10 @@ import os.path import datetime import itertools -import re import py import cgi import urllib -from twisted.web import resource +import sys from twisted.web.static import File, DirectoryLister class PyPyTarball(object): @@ -104,15 +103,19 @@ return self.vcs == 'latest' class PyPyDirectory(object): - def __init__(self, filename): - self.filename = filename + def __init__(self, filePath): + self.filename = filePath.basename() + self.filePath = filePath try: self.parse_filename() except ValueError: self.last_mod_time = 0 def parse_filename(self): - raise ValueError + if self.filename == 'trunk': + self.last_mod_time = sys.maxsize + return + self.last_mod_time = self.filePath.getmtime() def key(self): return (self.last_mod_time) @@ -124,23 +127,23 @@ items.sort(key=PyPyTarball.key, reverse=True) return [item.filename for item in items] - def sortDirectoryNames(self, names): - items = map(PyPyTarball, names) - items.sort(key=PyPyTarball.key, reverse=True) + def sortDirectoryNames(self, filePaths): + items = map(PyPyDirectory, filePaths) + items.sort(key=PyPyDirectory.key, reverse=True) return [item.filename for item in items] def directoryListing(self): - def is_pypy_dir(names_unsorted): - for name in names_unsorted: + def is_pypy_dir(names): + for name in names: if name.startswith('pypy-c'): return True return False - names_unsorted = File.listNames(self) - if is_pypy_dir(names_unsorted): - names = self.sortBuildNames(names_unsorted) + names = File.listNames(self) + if is_pypy_dir(names): + names = self.sortBuildNames(names) Listener = PyPyDirectoryLister else: - names = self.sortDirectoryNames(names_unsorted) + names = self.sortDirectoryNames(File.listEntities(self)) Listener = DirectoryLister return Listener(self.path, names, diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -69,22 +69,18 @@ assert os.path.basename(__file__) in files def test_dir_render(tmpdir): - import os, time - from twisted.web.test.test_web import DummyRequest # Create a bunch of directories, including one named trunk, # Make sure the time order is reversed collation order - tmpdir.mkdir('trunk') + trunk = tmpdir.mkdir('trunk') + oldtime = trunk.mtime() for ascii in range(ord('a'), ord('m')): - tmpdir.mkdir(chr(ascii) * 4) - time.sleep(0.1) + newdir = tmpdir.mkdir(chr(ascii) * 4) + newdir.setmtime(oldtime + ascii * 10) pypylist = PyPyList(tmpdir.strpath) listener = pypylist.directoryListing() - request = DummyRequest([os.path.dirname(tmpdir.strpath)]) - page = listener.render(request) - tmpdir.join('index.html').write(page) - for ascii in range(ord('a'), ord('m') - 1): - assert page.find(chr(ascii) * 4) > page.find((chr(ascii + 1)) * 4) - assert page.find('trunk') < page.find('mmm') + assert listener.dirs == ['trunk', 'mmmm', 'llll', + 'kkkk','jjjj','iiii','hhhh','gggg','ffff','eeee', + 'dddd','cccc','bbbb','aaaa'] def load_BuildmasterConfig(): import os From noreply at buildbot.pypy.org Thu Mar 21 05:19:29 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 05:19:29 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: simplify Message-ID: <20130321041929.6AB1A1C019F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r751:a60dfee5eb4b Date: 2013-03-20 21:18 -0700 http://bitbucket.org/pypy/buildbot/changeset/a60dfee5eb4b/ Log: simplify diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -106,10 +106,7 @@ def __init__(self, filePath): self.filename = filePath.basename() self.filePath = filePath - try: - self.parse_filename() - except ValueError: - self.last_mod_time = 0 + self.parse_filename() def parse_filename(self): if self.filename == 'trunk': From noreply at buildbot.pypy.org Thu Mar 21 07:22:58 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 07:22:58 +0100 (CET) Subject: [pypy-commit] buildbot sort-nightly-directories: close about-to-be-merged branch Message-ID: <20130321062258.E54991C04AB@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: sort-nightly-directories Changeset: r752:73a9e7779b04 Date: 2013-03-20 23:21 -0700 http://bitbucket.org/pypy/buildbot/changeset/73a9e7779b04/ Log: close about-to-be-merged branch From noreply at buildbot.pypy.org Thu Mar 21 07:23:00 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Mar 2013 07:23:00 +0100 (CET) Subject: [pypy-commit] buildbot default: merge sort-nightly-directories which sorts the nightly page by mtime of the subdirectories and puts trunk on top Message-ID: <20130321062300.1B2EA1C04AB@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r753:c816177376d6 Date: 2013-03-20 23:22 -0700 http://bitbucket.org/pypy/buildbot/changeset/c816177376d6/ Log: merge sort-nightly-directories which sorts the nightly page by mtime of the subdirectories and puts trunk on top diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -1,11 +1,10 @@ import os.path import datetime import itertools -import re import py import cgi import urllib -from twisted.web import resource +import sys from twisted.web.static import File, DirectoryLister class PyPyTarball(object): @@ -103,25 +102,45 @@ def display_in_italic(self): return self.vcs == 'latest' +class PyPyDirectory(object): + def __init__(self, filePath): + self.filename = filePath.basename() + self.filePath = filePath + self.parse_filename() + + def parse_filename(self): + if self.filename == 'trunk': + self.last_mod_time = sys.maxsize + return + self.last_mod_time = self.filePath.getmtime() + + def key(self): + return (self.last_mod_time) class PyPyList(File): - def listNames(self): - names = File.listNames(self) + def sortBuildNames(self, names): items = map(PyPyTarball, names) items.sort(key=PyPyTarball.key, reverse=True) return [item.filename for item in items] + def sortDirectoryNames(self, filePaths): + items = map(PyPyDirectory, filePaths) + items.sort(key=PyPyDirectory.key, reverse=True) + return [item.filename for item in items] + def directoryListing(self): def is_pypy_dir(names): for name in names: if name.startswith('pypy-c'): return True return False - names = self.listNames() + names = File.listNames(self) if is_pypy_dir(names): + names = self.sortBuildNames(names) Listener = PyPyDirectoryLister else: + names = self.sortDirectoryNames(File.listEntities(self)) Listener = DirectoryLister return Listener(self.path, names, diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -1,5 +1,5 @@ import py -from pypybuildbot.pypylist import PyPyTarball +from pypybuildbot.pypylist import PyPyTarball, PyPyList def test_pypytarball_svn(): t = PyPyTarball('pypy-c-jit-75654-linux.tar.bz2') @@ -12,6 +12,7 @@ assert t.platform == 'linux' assert t.vcs == 'svn' + def test_pypytarball_hg(): t = PyPyTarball('pypy-c-jit-75654-foo-linux.tar.bz2') assert t.filename == 'pypy-c-jit-75654-foo-linux.tar.bz2' @@ -23,6 +24,7 @@ assert t.platform == 'linux' assert t.vcs == 'hg' + def test_invalid_filename(): t = PyPyTarball('foo') assert t.vcs == None @@ -35,8 +37,8 @@ t2 = PyPyTarball('pypy-c-jit-75654-linux.tar.bz2') assert t.key() < t2.key() -def test_sort(): - files = map(PyPyTarball, [ +def test_sort(tmpdir): + files = [ 'pypy-c-jit-10000-linux.tar.bz2', 'pypy-c-jit-20000-linux.tar.bz2', 'pypy-c-nojit-10000-linux.tar.bz2', @@ -45,11 +47,11 @@ 'pypy-c-stackless-10000-linux.tar.bz2', 'pypy-c-jit-1000-e5b73981fc8d-linux.tar.bz2', # this is mercurial based 'pypy-c-jit-10000-linux-armel.tar.bz2', - ]) - - files.sort(key=PyPyTarball.key, reverse=True) - files = [f.filename for f in files] - assert files == [ + ] + [tmpdir.join(f).write(f) for f in files] + pypylist = PyPyList(tmpdir.strpath) + listener = pypylist.directoryListing() + assert listener.dirs == [ 'pypy-c-jit-1000-e5b73981fc8d-linux.tar.bz2', # mercurial first 'pypy-c-jit-20000-linux.tar.bz2', 'pypy-c-jit-10000-linux.tar.bz2', @@ -60,6 +62,26 @@ 'pypy-c-stackless-10000-linux.tar.bz2', ] +def test_pypy_list(tmpdir): + import os + pypylist = PyPyList(os.path.dirname(__file__)) + files = pypylist.listNames() + assert os.path.basename(__file__) in files + +def test_dir_render(tmpdir): + # Create a bunch of directories, including one named trunk, + # Make sure the time order is reversed collation order + trunk = tmpdir.mkdir('trunk') + oldtime = trunk.mtime() + for ascii in range(ord('a'), ord('m')): + newdir = tmpdir.mkdir(chr(ascii) * 4) + newdir.setmtime(oldtime + ascii * 10) + pypylist = PyPyList(tmpdir.strpath) + listener = pypylist.directoryListing() + assert listener.dirs == ['trunk', 'mmmm', 'llll', + 'kkkk','jjjj','iiii','hhhh','gggg','ffff','eeee', + 'dddd','cccc','bbbb','aaaa'] + def load_BuildmasterConfig(): import os from pypybuildbot import summary, builds @@ -70,7 +92,7 @@ return builds else: assert False - + this = py.path.local(__file__) master_py = this.dirpath().dirpath().join('master.py') glob = {'httpPortNumber': 80, @@ -91,13 +113,13 @@ assert app == expected_app assert own in builders or own in known_exceptions assert app in builders or app in known_exceptions - + t = PyPyTarball('pypy-c-jit-76867-linux.tar.bz2') check_builder_names(t, 'own-linux-x86-32', 'pypy-c-jit-linux-x86-32') t = PyPyTarball('pypy-c-nojit-76867-linux.tar.bz2') check_builder_names(t, 'own-linux-x86-32', 'pypy-c-app-level-linux-x86-32') - + t = PyPyTarball('pypy-c-jit-76867-osx.tar.bz2') check_builder_names(t, 'own-macosx-x86-32', 'pypy-c-jit-macosx-x86-32') From noreply at buildbot.pypy.org Thu Mar 21 08:36:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 08:36:14 +0100 (CET) Subject: [pypy-commit] pypy default: move readline to RStringIO Message-ID: <20130321073614.EE7D51C10C2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62606:535f3a9dd3b6 Date: 2013-03-21 03:27 -0400 http://bitbucket.org/pypy/pypy/changeset/535f3a9dd3b6/ Log: move readline to RStringIO diff --git a/pypy/module/cStringIO/interp_stringio.py b/pypy/module/cStringIO/interp_stringio.py --- a/pypy/module/cStringIO/interp_stringio.py +++ b/pypy/module/cStringIO/interp_stringio.py @@ -149,22 +149,6 @@ RStringIO.__init__(self) self.space = space - def readline(self, size=-1): - p = self.tell() - bigbuffer = self.copy_into_bigbuffer() - end = len(bigbuffer) - if size >= 0 and size < end - p: - end = p + size - assert p >= 0 - i = p - while i < end: - finished = bigbuffer[i] == '\n' - i += 1 - if finished: - break - self.seek(i) - return ''.join(bigbuffer[p:i]) - def descr_truncate(self, w_size=None): self.check_closed() space = self.space diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -126,6 +126,22 @@ self.pos = p + count return ''.join(self.bigbuffer[p:p+count]) + def readline(self, size=-1): + p = self.tell() + self.copy_into_bigbuffer() + end = len(self.bigbuffer) + if size >= 0 and size < end - p: + end = p + size + assert p >= 0 + i = p + while i < end: + finished = self.bigbuffer[i] == '\n' + i += 1 + if finished: + break + self.seek(i) + return ''.join(self.bigbuffer[p:i]) + def truncate(self, size): # NB. 'size' is mandatory. This has the same un-Posix-y semantics # than CPython: it never grows the buffer, and it sets the current diff --git a/rpython/rlib/test/test_rStringIO.py b/rpython/rlib/test/test_rStringIO.py --- a/rpython/rlib/test/test_rStringIO.py +++ b/rpython/rlib/test/test_rStringIO.py @@ -77,6 +77,16 @@ assert f.read(2) == '' assert f.tell() == 15 +def test_readline(): + f = RStringIO() + f.write('foo\nbar\nbaz') + f.seek(0) + assert f.readline() == 'foo\n' + assert f.readline(2) == 'ba' + assert f.readline() == 'r\n' + assert f.readline() == 'baz' + assert f.readline() == '' + def test_truncate(): f = RStringIO() f.truncate(20) From noreply at buildbot.pypy.org Thu Mar 21 08:36:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 08:36:13 +0100 (CET) Subject: [pypy-commit] pypy default: simplify/optimize RStringIO by changing it to use StringBuilder Message-ID: <20130321073613.9C5071C0DC9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62605:b4901c26d853 Date: 2013-03-21 03:24 -0400 http://bitbucket.org/pypy/pypy/changeset/b4901c26d853/ Log: simplify/optimize RStringIO by changing it to use StringBuilder diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -1,6 +1,4 @@ - -PIECES = 80 -BIGPIECES = 32 +from rpython.rlib.rstring import StringBuilder AT_END = -1 @@ -8,8 +6,7 @@ class RStringIO(object): """RPython-level StringIO object. The fastest path through this code is for the case of a bunch of write() - followed by getvalue(). For at most PIECES write()s and one getvalue(), - there is one copy of the data done, as if ''.join() was used. + followed by getvalue(). """ _mixin_ = True # for interp_stringio.py @@ -18,20 +15,12 @@ # * the list of characters self.bigbuffer; # * each of the strings in self.strings. # - # Invariants: - # * self.numbigstrings <= self.numstrings; - # * all strings in self.strings[self.numstrings:PIECES] are empty. - # - self.strings = [''] * PIECES - self.numstrings = 0 - self.numbigstrings = 0 + self.strings = StringBuilder() self.bigbuffer = [] self.pos = AT_END def close(self): self.strings = None - self.numstrings = 0 - self.numbigstrings = 0 self.bigbuffer = None def is_closed(self): @@ -40,58 +29,21 @@ def getvalue(self): """If self.strings contains more than 1 string, join all the strings together. Return the final single string.""" - if len(self.bigbuffer) > 0: + if len(self.bigbuffer): self.copy_into_bigbuffer() return ''.join(self.bigbuffer) - if self.numstrings > 1: - result = self.strings[0] = ''.join(self.strings) - for i in range(1, self.numstrings): - self.strings[i] = '' - self.numstrings = 1 - self.numbigstrings = 1 - else: - result = self.strings[0] - return result + return self.strings.build() def getsize(self): result = len(self.bigbuffer) - for i in range(0, self.numstrings): - result += len(self.strings[i]) + result += self.strings.getlength() return result def copy_into_bigbuffer(self): """Copy all the data into the list of characters self.bigbuffer.""" - for i in range(0, self.numstrings): - self.bigbuffer += self.strings[i] - self.strings[i] = '' - self.numstrings = 0 - self.numbigstrings = 0 - return self.bigbuffer - - def reduce(self): - """Reduce the number of (non-empty) strings in self.strings.""" - # When self.pos == AT_END, the calls to write(str) accumulate - # the strings in self.strings until all PIECES slots are filled. - # Then the reduce() method joins all the strings and put the - # result back into self.strings[0]. The next time all the slots - # are filled, we only join self.strings[1:] and put the result - # in self.strings[1]; and so on. The purpose of this is that - # the string resulting from a join is expected to be big, so the - # next join operation should only join the newly added strings. - # When we have done this BIGPIECES times, the next join collects - # all strings again into self.strings[0] and we start from - # scratch. - limit = self.numbigstrings - self.strings[limit] = ''.join(self.strings[limit:]) - for i in range(limit + 1, self.numstrings): - self.strings[i] = '' - self.numstrings = limit + 1 - if limit < BIGPIECES: - self.numbigstrings = limit + 1 - else: - self.numbigstrings = 0 - assert self.numstrings <= BIGPIECES + 1 - return self.numstrings + if self.strings.getlength(): + self.bigbuffer += self.strings.build() + self.strings = StringBuilder() def write(self, buffer): # Idea: for the common case of a sequence of write() followed @@ -110,30 +62,25 @@ else: # slow path: collect all data into self.bigbuffer and # handle the various cases - bigbuffer = self.copy_into_bigbuffer() - fitting = len(bigbuffer) - p + self.copy_into_bigbuffer() + fitting = len(self.bigbuffer) - p if fitting > 0: # the write starts before the end of the data fitting = min(len(buffer), fitting) for i in range(fitting): - bigbuffer[p+i] = buffer[i] + self.bigbuffer[p+i] = buffer[i] if len(buffer) > fitting: # the write extends beyond the end of the data - bigbuffer += buffer[fitting:] + self.bigbuffer += buffer[fitting:] endp = AT_END self.pos = endp return else: # the write starts at or beyond the end of the data - bigbuffer += '\x00' * (-fitting) + self.bigbuffer += '\x00' * (-fitting) self.pos = AT_END # fall-through to the fast path # Fast path. - # See comments in reduce(). - count = self.numstrings - if count == PIECES: - count = self.reduce() - self.strings[count] = buffer - self.numstrings = count + 1 + self.strings.append(buffer) def seek(self, position, mode=0): if mode == 1: @@ -165,8 +112,8 @@ if p == AT_END: return '' assert p >= 0 - bigbuffer = self.copy_into_bigbuffer() - mysize = len(bigbuffer) + self.copy_into_bigbuffer() + mysize = len(self.bigbuffer) count = mysize - p if n >= 0: count = min(n, count) @@ -174,10 +121,10 @@ return '' if p == 0 and count == mysize: self.pos = AT_END - return ''.join(bigbuffer) + return ''.join(self.bigbuffer) else: self.pos = p + count - return ''.join(bigbuffer[p:p+count]) + return ''.join(self.bigbuffer[p:p+count]) def truncate(self, size): # NB. 'size' is mandatory. This has the same un-Posix-y semantics @@ -188,10 +135,8 @@ self.copy_into_bigbuffer() else: # we can drop all extra strings - for i in range(0, self.numstrings): - self.strings[i] = '' - self.numstrings = 0 - self.numbigstrings = 0 + if self.strings.getlength(): + self.strings = StringBuilder() if size < len(self.bigbuffer): del self.bigbuffer[size:] self.pos = AT_END From noreply at buildbot.pypy.org Thu Mar 21 09:53:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 09:53:21 +0100 (CET) Subject: [pypy-commit] pypy default: lazily construct the StringBuilder for RStringIO Message-ID: <20130321085321.B5E4E1C10C2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62607:594d075cf003 Date: 2013-03-21 03:48 -0400 http://bitbucket.org/pypy/pypy/changeset/594d075cf003/ Log: lazily construct the StringBuilder for RStringIO diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -15,7 +15,7 @@ # * the list of characters self.bigbuffer; # * each of the strings in self.strings. # - self.strings = StringBuilder() + self.strings = None self.bigbuffer = [] self.pos = AT_END @@ -24,7 +24,7 @@ self.bigbuffer = None def is_closed(self): - return self.strings is None + return self.bigbuffer is None def getvalue(self): """If self.strings contains more than 1 string, join all the @@ -32,18 +32,21 @@ if len(self.bigbuffer): self.copy_into_bigbuffer() return ''.join(self.bigbuffer) - return self.strings.build() + if self.strings is not None: + return self.strings.build() + return '' def getsize(self): result = len(self.bigbuffer) - result += self.strings.getlength() + if self.strings is not None: + result += self.strings.getlength() return result def copy_into_bigbuffer(self): """Copy all the data into the list of characters self.bigbuffer.""" - if self.strings.getlength(): + if self.strings is not None: self.bigbuffer += self.strings.build() - self.strings = StringBuilder() + self.strings = None def write(self, buffer): # Idea: for the common case of a sequence of write() followed @@ -80,6 +83,8 @@ self.bigbuffer += '\x00' * (-fitting) self.pos = AT_END # fall-through to the fast path # Fast path. + if self.strings is None: + self.strings = StringBuilder() self.strings.append(buffer) def seek(self, position, mode=0): @@ -151,8 +156,8 @@ self.copy_into_bigbuffer() else: # we can drop all extra strings - if self.strings.getlength(): - self.strings = StringBuilder() + if self.strings is not None: + self.strings = None if size < len(self.bigbuffer): del self.bigbuffer[size:] self.pos = AT_END From noreply at buildbot.pypy.org Thu Mar 21 12:09:54 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Mar 2013 12:09:54 +0100 (CET) Subject: [pypy-commit] pypy default: fixes for call_header_with_stack_check Message-ID: <20130321110954.B8DA71C1566@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62608:28bc77433153 Date: 2013-03-21 13:09 +0200 http://bitbucket.org/pypy/pypy/changeset/28bc77433153/ Log: fixes for call_header_with_stack_check diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -242,7 +242,7 @@ # mc = ARMv7Builder() # save argument registers and return address - mc.PUSH([reg.value for reg in r.argument_regs] + [r.lr.value]) + mc.PUSH([reg.value for reg in r.argument_regs] + [r.ip.value, r.lr.value]) # stack is aligned here # Pass current stack pointer as argument to the call mc.MOV_rr(r.r0.value, r.sp.value) @@ -253,21 +253,13 @@ mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) mc.LDR_ri(r.r0.value, r.r0.value) mc.TST_rr(r.r0.value, r.r0.value) + # # restore registers and return # We check for c.EQ here, meaning all bits zero in this case - mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value], cond=c.EQ) - # - # Call the helper, which will return a dead frame object with - # the correct exception set, or MemoryError by default - addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception()) - mc.BL(addr) - # - # footer -- note the ADD, which skips the return address of this - # function, and will instead return to the caller's caller. Note - # also that we completely ignore the saved arguments, because we - # are interrupting the function. - mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 1) * WORD) - mc.POP([r.pc.value]) + mc.POP([reg.value for reg in r.argument_regs] + [r.ip.value, r.pc.value], cond=c.EQ) + # restore sp + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.B(self.propagate_exception_path) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart @@ -311,6 +303,8 @@ else: self._restore_exception(mc, exc0, exc1) mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + assert exc0 is not None + assert exc1 is not None mc.POP([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) # @@ -505,7 +499,7 @@ if self.cpu.supports_floats: mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond) - # push all callee saved registers and IP to keep the alignment + # pop all callee saved registers and IP to keep the alignment mc.POP([reg.value for reg in r.callee_restored_registers] + [r.ip.value], cond=cond) mc.BKPT() @@ -564,11 +558,11 @@ self.gen_func_prolog() def _call_header_with_stack_check(self): + self._call_header() if self.stack_check_slowpath == 0: pass # no stack check (e.g. not translated) else: endaddr, lengthaddr, _ = self.cpu.insert_stack_check() - self.mc.PUSH([r.lr.value]) # load stack end self.mc.gen_load_int(r.ip.value, endaddr) # load ip, [end] self.mc.LDR_ri(r.ip.value, r.ip.value) # LDR ip, ip @@ -580,9 +574,6 @@ # if ofs self.mc.CMP_rr(r.ip.value, r.lr.value) # CMP ip, lr self.mc.BL(self.stack_check_slowpath, c=c.HI) # call if ip > lr - # - self.mc.POP([r.lr.value]) - self._call_header() # cpu interface def assemble_loop(self, loopname, inputargs, operations, looptoken, log): From noreply at buildbot.pypy.org Thu Mar 21 14:32:56 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Mar 2013 14:32:56 +0100 (CET) Subject: [pypy-commit] pypy default: update, finish and enable some calling convetion tests on arm Message-ID: <20130321133256.DFC461C16DD@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62609:7fe3b006e52e Date: 2013-03-21 15:32 +0200 http://bitbucket.org/pypy/pypy/changeset/7fe3b006e52e/ Log: update, finish and enable some calling convetion tests on arm diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -4,12 +4,23 @@ from rpython.rtyper.lltypesystem import lltype from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.backend.arm.codebuilder import ARMv7Builder +from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests skip_unless_run_slow_tests() class TestARMCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py + def make_function_returning_stack_pointer(self): + mc = ARMv7Builder() + mc.MOV_rr(r.r0.value, r.sp.value) + mc.MOV_rr(r.pc.value, r.lr.value) + return mc.materialize(self.cpu.asmmemmgr, []) + + def get_alignment_requirements(self): + return 8 + def test_call_argument_spilling(self): # bug when we have a value in r0, that is overwritten by an argument # and needed after the call, so that the register gets spilled after it @@ -28,12 +39,24 @@ ops = """ [%s] i99 = call(ConstClass(func_ptr), 22, descr=calldescr) - finish(%s, i99)""" % (args, args) + force_spill(i0) + force_spill(i1) + force_spill(i2) + force_spill(i3) + force_spill(i4) + force_spill(i5) + force_spill(i6) + force_spill(i7) + force_spill(i8) + force_spill(i9) + force_spill(i10) + guard_true(i0) [%s, i99] + finish()""" % (args, args) loop = parse(ops, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [x for x in range(11)] - self.cpu.execute_token(looptoken, *args) + deadframe = self.cpu.execute_token(looptoken, *args) for x in range(11): - assert self.cpu.get_latest_value_int(x) == x - assert self.cpu.get_latest_value_int(11) == 38 + assert self.cpu.get_int_value(deadframe, x) == x + assert self.cpu.get_int_value(deadframe, 11) == 38 diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -11,6 +11,7 @@ from rpython.jit.backend.test.runner_test import Runner import py import sys +import platform def boxfloat(x): return BoxFloat(longlong.getfloatstorage(x)) @@ -382,7 +383,8 @@ raise NotImplementedError def test_call_aligned_explicit_check(self): - if sys.maxint == 2 ** 31 - 1: + if (not platform.machine().startswith('arm') and + sys.maxint == 2 ** 31 - 1): # XXX is still necessary on x86? py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: From noreply at buildbot.pypy.org Thu Mar 21 16:12:28 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 21 Mar 2013 16:12:28 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, lwassermann): minor fix to not send empty key-events when there were none Message-ID: <20130321151228.6890F1C14B0@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r229:76bfdbc738e7 Date: 2013-03-21 16:08 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/76bfdbc738e7/ Log: (tfel, lwassermann): minor fix to not send empty key-events when there were none diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -661,11 +661,19 @@ @expose_primitive(KBD_NEXT, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): - return interp.space.wrap_int(interp.space.get_display().next_keycode()) + code = interp.space.get_display().next_keycode() + if code == 0: + return interp.space.w_nil + else: + return interp.space.wrap_int(code) @expose_primitive(KBD_PEEK, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): - return interp.space.wrap_int(interp.space.get_display().peek_keycode()) + code = interp.space.get_display().peek_keycode() + if code == 0: + return interp.space.w_nil + else: + return interp.space.wrap_int(code) # ___________________________________________________________________________ From noreply at buildbot.pypy.org Thu Mar 21 16:12:27 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 21 Mar 2013 16:12:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: method extraction refactoring for does not understand case in _sendSelector Message-ID: <20130321151227.490C91C0DC9@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r228:7e8d4241566a Date: 2013-03-21 16:07 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/7e8d4241566a/ Log: method extraction refactoring for does not understand case in _sendSelector diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -33,7 +33,8 @@ get_printable_location=get_printable_location ) - def __init__(self, space, image=None, image_name="", max_stack_depth=100): + def __init__(self, space, image=None, image_name="", + max_stack_depth=constants.MAX_LOOP_DEPTH): self.space = space self.image = image self.image_name = image_name @@ -118,7 +119,8 @@ if selector == "asSymbol": w_selector = self.image.w_asSymbol else: - w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") + w_selector = self.perform(self.space.wrap_string(selector), + "asSymbol") else: w_selector = selector @@ -281,22 +283,11 @@ interp._last_indent, w_selector.as_string(), receiver, [self.peek(argcount-1-i) for i in range(argcount)]) assert argcount >= 0 + try: s_method = receiverclassshadow.lookup(w_selector) except MethodNotFound: - arguments = self.pop_and_return_n(argcount) - s_message_class = self.space.classtable["w_Message"].as_class_get_shadow(self.space) - w_message = s_message_class.new() - w_message.store(self.space, 0, w_selector) - w_message.store(self.space, 1, self.space.wrap_list(arguments)) - try: - s_method = receiver.shadow_of_my_class(self.space).lookup(self.space.objtable["w_doesNotUnderstand"]) - except MethodNotFound: - print "Missing doesDoesNotUnderstand in hierarchy of %s" % receiverclassshadow.getname() - raise - s_frame = s_method.create_frame(self.space, receiver, [w_message], self) - self.pop() - return interp.stack_frame(s_frame) + return self._doesNotUnderstand(w_selector, argcount, interp, receiver) code = s_method.primitive() if code: @@ -316,6 +307,22 @@ self.pop() return interp.stack_frame(s_frame) + def _doesNotUnderstand(self, w_selector, argcount, interp, receiver): + arguments = self.pop_and_return_n(argcount) + s_message_class = self.space.classtable["w_Message"].as_class_get_shadow(self.space) + w_message = s_message_class.new() + w_message.store(self.space, 0, w_selector) + w_message.store(self.space, 1, self.space.wrap_list(arguments)) + s_class = receiver.shadow_of_my_class(self.space) + try: + s_method = s_class.lookup(self.space.objtable["w_doesNotUnderstand"]) + except MethodNotFound: + print "Missing doesDoesNotUnderstand in hierarchy of %s" % s_class.getname() + raise + s_frame = s_method.create_frame(self.space, receiver, [w_message], self) + self.pop() + return interp.stack_frame(s_frame) + def _return(self, return_value, interp, s_return_to): # for tests, when returning from the top-level context if s_return_to is None: From noreply at buildbot.pypy.org Thu Mar 21 16:12:29 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 21 Mar 2013 16:12:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added SIGNAL_AT_MILLISECONDS primitive and code which checks whether to signal Message-ID: <20130321151229.7EFD51C14B7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r230:1330f5e597fe Date: 2013-03-21 16:11 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/1330f5e597fe/ Log: added SIGNAL_AT_MILLISECONDS primitive and code which checks whether to signal diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -90,7 +90,7 @@ SO_BYTEARRAY_CLASS = 26 SO_PROCESS_CLASS = 27 SO_COMPACT_CLASSES_ARRAY = 28 -SO_DELAY_SEMAPHORE = 29 +SO_TIMER_SEMAPHORE = 29 SO_USER_INTERRUPT_SEMAPHORE = 30 SO_FLOAT_ZERO = 31 SO_LARGEPOSITIVEINTEGER_ZERO = 32 @@ -139,6 +139,7 @@ "display" : SO_DISPLAY_OBJECT, "doesNotUnderstand" : SO_DOES_NOT_UNDERSTAND, "interrupt_semaphore" : SO_USER_INTERRUPT_SEMAPHORE, + "timerSemaphore" : SO_TIMER_SEMAPHORE, } LONG_BIT = 32 @@ -176,3 +177,10 @@ primitive = primitive + (highbit << 10) ##XXX todo, check this assert tempsize >= numargs return primitive, literalsize, islarge, tempsize, numargs + +#___________________________________________________________________________ +# Interpreter constants +# + +MAX_LOOP_DEPTH = 100 +INTERRUPT_COUNTER_SIZE = 1000 \ No newline at end of file diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -41,6 +41,8 @@ self.max_stack_depth = max_stack_depth self.remaining_stack_depth = max_stack_depth self._loop = False + self.next_wakeup_tick = 0 + self.interrupt_check_counter = constants.INTERRUPT_COUNTER_SIZE def interpret_with_w_frame(self, w_frame): try: @@ -80,10 +82,15 @@ # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth) # print padding + s_context.short_str() old_pc = 0 + if not jit.we_are_jitted(): + self.quick_check_for_interrupt(s_context) while True: pc = s_context._pc method = s_context.s_method() if pc < old_pc: + if jit.we_are_jitted(): + self.quick_check_for_interrupt(s_context, + dec=self._get_adapted_tick_counter()) self.jit_driver.can_enter_jit( pc=pc, self=self, method=method, s_context=s_context) @@ -100,6 +107,14 @@ else: s_context.push(nlr.value) + def _get_adapted_tick_counter(self): + # Normally, the tick counter is decremented by 1 for every message send. + # Since we don't know how many messages are called during this trace, we + # just decrement by 10th of the trace length (num of bytecodes). + trace_length = jit.current_trace_length() + decr_by = int(trace_length // 10) + return max(decr_by, 1) + def stack_frame(self, s_new_frame): if not self._loop: return s_new_frame # this test is done to not loop in test, @@ -138,6 +153,36 @@ except ReturnFromTopLevel, e: return e.object + def quick_check_for_interrupt(self, s_frame, dec=1): + self.interrupt_check_counter -= dec + if self.interrupt_check_counter <= 0: + self.interrupt_check_counter = constants.INTERRUPT_COUNTER_SIZE + self.check_for_interrupts(s_frame) + + def check_for_interrupts(self, s_frame): + # parallel to Interpreter>>#checkForInterrupts + import time, math + + # Profiling is skipped + # We don't adjust the check counter size + + # use the same time value as the primitive MILLISECOND_CLOCK + now = int(math.fmod(time.time()*1000, constants.TAGGED_MAXINT/2)) + + # XXX the low space semaphore may be signaled here + # Process inputs + # Process User Interrupt? + if not self.next_wakeup_tick == 0 and now >= self.next_wakeup_tick: + self.next_wakeup_tick = 0 + semaphore = self.space.objtable["w_timerSemaphore"] + if not semaphore.is_same_object(self.space.w_nil): + wrapper.SemaphoreWrapper(self.space, semaphore).signal(s_frame.w_self()) + # We have no finalization process, so far. + # We do not support external semaphores. + # In cog, the method to add such a semaphore is only called in GC. + + + class ReturnFromTopLevel(Exception): def __init__(self, object): self.object = object diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -823,14 +823,26 @@ #____________________________________________________________________________ # Time Primitives (135 - 137) MILLISECOND_CLOCK = 135 +SIGNAL_AT_MILLISECONDS = 136 SECONDS_CLOCK = 137 @expose_primitive(MILLISECOND_CLOCK, unwrap_spec=[object]) def func(interp, s_frame, w_arg): - import time - import math + import time, math return interp.space.wrap_int(int(math.fmod(time.time()*1000, constants.TAGGED_MAXINT/2))) + at expose_primitive(SIGNAL_AT_MILLISECONDS, unwrap_spec=[object, object, int]) +def func(interp, s_frame, w_delay, w_semaphore, timestamp): + if not w_semaphore.getclass(interp.space).is_same_object( + interp.space.w_Semaphore): + interp.space.objtable["w_timerSemaphore"] = interp.space.w_nil + interp.next_wakeup_tick = timestamp + else: + interp.space.objtable["w_timerSemaphore"] = w_semaphore + interp.next_wakeup_tick = timestamp + return w_delay + + secs_between_1901_and_1970 = rarithmetic.r_uint((69 * 365 + 17) * 24 * 3600) @@ -1114,7 +1126,7 @@ return wrapper.SemaphoreWrapper(interp.space, w_rcvr).wait(s_frame.w_self()) @expose_primitive(RESUME, unwrap_spec=[object], result_is_new_frame=True) -def func(interp, s_frame, w_rcvr,): +def func(interp, s_frame, w_rcvr): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( interp.space.w_Process): @@ -1125,7 +1137,7 @@ return w_frame.as_context_get_shadow(interp.space) @expose_primitive(SUSPEND, unwrap_spec=[object], result_is_new_frame=True) -def func(interp, s_frame, w_rcvr, result_is_new_frame=True): +def func(interp, s_frame, w_rcvr): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( interp.space.w_Process): diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -173,7 +173,7 @@ SO_BYTEARRAY_CLASS = 26 SO_PROCESS_CLASS = 27 SO_COMPACT_CLASSES_ARRAY = 28 - SO_DELAY_SEMAPHORE = 29 + SO_TIMER_SEMAPHORE = 29 SO_USER_INTERRUPT_SEMAPHORE = 30 SO_FLOAT_ZERO = 31 SO_LARGEPOSITIVEINTEGER_ZERO = 32 diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -411,6 +411,13 @@ stop = prim(primitives.MILLISECOND_CLOCK, [0]).value assert start + 250 <= stop +def test_signal_at_milliseconds(): + import time + future = prim(primitives.MILLISECOND_CLOCK, [0]).value + 400 + sema = space.w_Semaphore.as_class_get_shadow(space).new() + prim(primitives.SIGNAL_AT_MILLISECONDS, [space.w_nil, sema, future]) + assert space.objtable["w_timerSemaphore"] is sema + def test_inc_gc(): # Should not fail :-) prim(primitives.INC_GC, [42]) # Dummy arg diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -42,7 +42,8 @@ [ ] Implement image writer Shadows: -[ ] Fix invalidation of methoddictshadow when the w_self of its values array changes +[ ] What to do with shadows when their w_self changes class? +[ ] Weak references for subclasses Optimizations: @@ -53,3 +54,5 @@ return model.W_SmallInteger(rerased.erase_int(val)) except OverflowError: raise WrappingError("integer too large to fit into a tagged pointer") + +use special class for 1WordLargeIntegers \ No newline at end of file From noreply at buildbot.pypy.org Thu Mar 21 16:25:04 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 21 Mar 2013 16:25:04 +0100 (CET) Subject: [pypy-commit] lang-gameboy default: (jlincke, timfel) Add a test for blitting surface from pixelbuffer Message-ID: <20130321152504.822891C10C2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r6:c419533d2000 Date: 2013-03-15 17:57 +0100 http://bitbucket.org/pypy/lang-gameboy/changeset/c419533d2000/ Log: (jlincke, timfel) Add a test for blitting surface from pixelbuffer diff --git a/rsdl/test/test_video.py b/rsdl/test/test_video.py --- a/rsdl/test/test_video.py +++ b/rsdl/test/test_video.py @@ -236,6 +236,35 @@ RSDL.FreeSurface(surface) self.check("Half Red/Orange rectangle(150px * 50px) at the top left, 10 pixels from the border") + + def test_blit_pxrect(self): + max = 150 * 50 + surfacepx = lltype.malloc(rffi.VOIDP.TO, max * 4, flavor='raw') + pos = 0 + for i in xrange(max): + surfacepx[pos] = chr(int(float(i) / max * 255)) + surfacepx[pos + 1] = chr(int(float(i) / max * 255)) + surfacepx[pos + 2] = chr(int(float(i) / max * 255)) + surfacepx[pos + 3] = chr(255) + pos += 4 + + pitch = 4 * 150 # 4 byte per line * width + surface = RSDL.CreateRGBSurfaceFrom(surfacepx, 150, 50, 32, pitch, + r_uint(0x000000FF), + r_uint(0x0000FF00), + r_uint(0x00FF0000), + r_uint(0xFF000000)) + + dstrect = RSDL_helper.mallocrect(0, 0, 150, 50) + try: + RSDL.BlitSurface(surface, lltype.nullptr(RSDL.Rect), self.screen, dstrect) + RSDL.Flip(self.screen) + finally: + lltype.free(dstrect, flavor='raw') + RSDL.FreeSurface(surface) + lltype.free(surfacepx, flavor='raw') + self.check("Gradient from black to white rectangle(150px * 50px) at the top left") + def teardown_method(self, meth): RSDL.Quit() From noreply at buildbot.pypy.org Thu Mar 21 16:34:03 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Thu, 21 Mar 2013 16:34:03 +0100 (CET) Subject: [pypy-commit] lang-js default: added annotation Message-ID: <20130321153403.E4CF81C10C2@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r372:1d6b0ccb866f Date: 2013-03-20 17:46 +0100 http://bitbucket.org/pypy/lang-js/changeset/1d6b0ccb866f/ Log: added annotation diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -956,6 +956,7 @@ from js.object_space import object_space _map = object_space.new_obj() mapped_names = new_map() + jit.promote(_len) indx = _len - 1 while indx >= 0: val = args[indx] From noreply at buildbot.pypy.org Thu Mar 21 16:34:05 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Thu, 21 Mar 2013 16:34:05 +0100 (CET) Subject: [pypy-commit] lang-js default: changed version string to include hg id and build time Message-ID: <20130321153405.122781C10C2@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r373:2d3ad1d9eda1 Date: 2013-03-21 16:33 +0100 http://bitbucket.org/pypy/lang-js/changeset/2d3ad1d9eda1/ Log: changed version string to include hg id and build time diff --git a/js/builtins/js_global.py b/js/builtins/js_global.py --- a/js/builtins/js_global.py +++ b/js/builtins/js_global.py @@ -329,9 +329,21 @@ pass +def _make_version_string(): + import subprocess + import time + + repo_id = subprocess.check_output('hg id -i'.split()).strip() + current_time = time.asctime(time.gmtime()) + + return '1.0; Build: %s; %s' % (repo_id, current_time) + +_version_string = _make_version_string() + + @w_return def version(this, args): - return '1.0' + return _version_string # 15.1.2.1 From noreply at buildbot.pypy.org Thu Mar 21 16:34:33 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 21 Mar 2013 16:34:33 +0100 (CET) Subject: [pypy-commit] lang-gameboy default: add external compilation info branch for windows Message-ID: <20130321153433.ADDBC1C10C2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r7:f85b5515ccef Date: 2013-03-21 16:33 +0100 http://bitbucket.org/pypy/lang-gameboy/changeset/f85b5515ccef/ Log: add external compilation info branch for windows diff --git a/rsdl/eci.py b/rsdl/eci.py --- a/rsdl/eci.py +++ b/rsdl/eci.py @@ -2,6 +2,7 @@ from rpython.translator.platform import CompilationError import py import sys +import os def get_rsdl_compilation_info(): if sys.platform == 'darwin': @@ -13,6 +14,31 @@ ], frameworks = ['SDL', 'Cocoa'] ) + elif sys.platform == "win32": + try: + sdl_prefix = os.path.abspath(os.environ["SDL_PREFIX"]) + except KeyError: + print "You need to provide the path to SDL using the SDL_PREFIX environment variable" + exit(1) + + # XXX: SDL_main.h does a #define main SDL_main + # This causes a linker error with the VS C compiler + # The solution is to #undef main before we define our own + this_dir = os.path.dirname(__file__) + f = open(os.path.join(this_dir, "RSDL_undef_main.h"), "w") + print >> f, "#undef main" + f.close() + + eci = ExternalCompilationInfo( + includes = ['SDL.h', 'RSDL_undef_main.h'], + include_dirs = [os.path.join(sdl_prefix, "include"), this_dir], + link_files = [ + os.path.join(sdl_prefix, "lib", "x86", "SDLmain.lib"), + os.path.join(sdl_prefix, "lib", "x86", "SDL.lib") + ], + libraries = ["SDL"], + library_dirs = [os.path.join(sdl_prefix, "lib", "x86")], + ) else: eci = ExternalCompilationInfo( includes=['SDL.h'], From noreply at buildbot.pypy.org Thu Mar 21 16:35:54 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Thu, 21 Mar 2013 16:35:54 +0100 (CET) Subject: [pypy-commit] lang-js default: backed out of 9e9af1fdf61d due to performance issues Message-ID: <20130321153554.8D8441C10C2@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r374:81e6e06fb4aa Date: 2013-03-21 16:35 +0100 http://bitbucket.org/pypy/lang-js/changeset/81e6e06fb4aa/ Log: backed out of 9e9af1fdf61d due to performance issues diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -1187,6 +1187,7 @@ @enforceargs(int) + at jit.elidable def int32(n): if n & (1 << (32 - 1)): res = n | ~MASK_32 @@ -1197,11 +1198,13 @@ @enforceargs(int) + at jit.elidable def uint32(n): return n & MASK_32 @enforceargs(int) + at jit.elidable def uint16(n): return n & MASK_16 From noreply at buildbot.pypy.org Thu Mar 21 17:00:41 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 21 Mar 2013 17:00:41 +0100 (CET) Subject: [pypy-commit] lang-gameboy default: prepare distribution as pip package Message-ID: <20130321160041.9D0591C1502@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r8:8e95abaa7208 Date: 2013-03-21 16:52 +0100 http://bitbucket.org/pypy/lang-gameboy/changeset/8e95abaa7208/ Log: prepare distribution as pip package diff --git a/rsdl/README.txt b/rsdl/README.txt new file mode 100644 --- /dev/null +++ b/rsdl/README.txt @@ -0,0 +1,6 @@ +RSDL +==== + +RSDL is an SDL library for use with RPython. It is used in the Gameboy +emulator "PyGirl" and the Squeak VM "Spy". It currently supports a +useful subset of the video, image, and audio SDL APIs. diff --git a/rsdl/rsdl/RIMG.py b/rsdl/rsdl/RIMG.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/RIMG.py @@ -0,0 +1,25 @@ +import sys +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform as platform +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rsdl import RSDL + + +if sys.platform == 'darwin': + eci = ExternalCompilationInfo( + includes = ['SDL_image.h'], + frameworks = ['SDL_image'], + include_dirs = ['/Library/Frameworks/SDL_image.framework/Headers'] + ) +else: + eci = ExternalCompilationInfo( + includes=['SDL_image.h'], + libraries=['SDL_image'], + ) + +eci = eci.merge(RSDL.eci) + +def external(name, args, result): + return rffi.llexternal(name, args, result, compilation_info=eci) + +Load = external('IMG_Load', [rffi.CCHARP], RSDL.SurfacePtr) diff --git a/rsdl/rsdl/RMix.py b/rsdl/rsdl/RMix.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/RMix.py @@ -0,0 +1,68 @@ +import sys +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform as platform +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rsdl import RSDL + + +if sys.platform == 'darwin': + eci = ExternalCompilationInfo( + includes = ['SDL_mixer.h'], + frameworks = ['SDL_mixer'], + include_dirs = ['/Library/Frameworks/SDL_Mixer.framework/Headers'] + ) +else: + eci = ExternalCompilationInfo( + includes=['SDL_mixer.h'], + libraries=['SDL_mixer'], + ) + +eci = eci.merge(RSDL.eci) +eci = eci.merge(eci) +eci = eci.merge(eci) + +ChunkPtr = lltype.Ptr(lltype.ForwardReference()) + +class CConfig: + _compilation_info_ = eci + + Chunk = platform.Struct('Mix_Chunk', [('allocated', rffi.INT), + ('abuf', RSDL.Uint8P), + ('alen', RSDL.Uint32), + ('volume', RSDL.Uint8)]) + +globals().update(platform.configure(CConfig)) + +ChunkPtr.TO.become(Chunk) + + +Buffer = rffi.CArray(RSDL.Uint8) + +def external(name, args, result): + return rffi.llexternal(name, args, result, compilation_info=eci) + +OpenAudio = external('Mix_OpenAudio', + [rffi.INT, RSDL.Uint16, rffi.INT, rffi.INT], + rffi.INT) + +CloseAudio = external('Mix_CloseAudio', [], lltype.Void) + +LoadWAV_RW = external('Mix_LoadWAV_RW', + [RSDL.RWopsPtr, rffi.INT], + ChunkPtr) + +def LoadWAV(filename_ccharp): + with rffi.scoped_str2charp('rb') as mode: + return LoadWAV_RW(RSDL.RWFromFile(filename_ccharp, mode), 1) + + +PlayChannelTimed = external('Mix_PlayChannelTimed', + [rffi.INT, ChunkPtr, rffi.INT, rffi.INT], + rffi.INT) + +def PlayChannel(channel,chunk,loops): + return PlayChannelTimed(channel, chunk, loops, -1) + +"""Returns zero if the channel is not playing. +Otherwise if you passed in -1, the number of channels playing is returned""" +ChannelPlaying = external('Mix_Playing', [rffi.INT], rffi.INT) diff --git a/rsdl/rsdl/RMix_helper.py b/rsdl/rsdl/RMix_helper.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/RMix_helper.py @@ -0,0 +1,24 @@ +from pypy.rpython.lltypesystem import lltype, rffi +from rsdl import RMix, RSDL +from pypy.rpython.tool import rffi_platform as platform + + +def malloc_buffer_chunk(has_own_allocated_buffer, length_bytes, volume): + buffer_pointer = lltype.malloc(RMix.Buffer, length_bytes, flavor='raw') + return malloc_chunk(has_own_allocated_buffer, length_bytes, volume) + +def malloc_chunk(has_own_allocated_buffer, buffer_pointer, length_bytes, volume): + """ + Creates a new Mix_Chunk. + has_own_allocated_buffer: if 1 struct has its own allocated buffer, + if 0 abuf should not be freed + buffer_pointer: pointer to audio data + length_bytes: length of audio data in bytes + volume: Per-sample volume, 0-128 (normally + MIX_MAX_VOLUME after loading)""" + p = lltype.malloc(RMix.Chunk, flavor='raw') + rffi.setintfield(p, 'c_allocated', has_own_allocated_buffer) + rffi.setintfield(p, 'c_abuf', buffer_pointer) + rffi.setintfield(p, 'c_alen', length_bytes) + rffi.setintfield(p, 'c_volume', volume) + return p diff --git a/rsdl/rsdl/RSDL.py b/rsdl/rsdl/RSDL.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/RSDL.py @@ -0,0 +1,254 @@ +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform as platform +from rsdl.constants import _constants +from rsdl.eci import get_rsdl_compilation_info +from rpython.rlib.objectmodel import we_are_translated +import py +import sys + +# ------------------------------------------------------------------------------ + +eci = get_rsdl_compilation_info() + +def external(name, args, result): + return rffi.llexternal(name, args, result, compilation_info=eci) + +# ------------------------------------------------------------------------------ + +RectPtr = lltype.Ptr(lltype.ForwardReference()) +SurfacePtr = lltype.Ptr(lltype.ForwardReference()) +PixelFormatPtr = lltype.Ptr(lltype.ForwardReference()) +EventPtr = lltype.Ptr(lltype.ForwardReference()) +KeyboardEventPtr = lltype.Ptr(lltype.ForwardReference()) +MouseButtonEventPtr = lltype.Ptr(lltype.ForwardReference()) +MouseMotionEventPtr = lltype.Ptr(lltype.ForwardReference()) +KeyPtr = lltype.Ptr(lltype.ForwardReference()) +RWopsPtr = lltype.Ptr(lltype.ForwardReference()) + +# ------------------------------------------------------------------------------ + +class CConfig: + _compilation_info_ = eci + + Uint8 = platform.SimpleType('Uint8', rffi.INT) + Uint16 = platform.SimpleType('Uint16', rffi.INT) + Sint16 = platform.SimpleType('Sint16', rffi.INT) + Uint32 = platform.SimpleType('Uint32', rffi.INT) + + Rect = platform.Struct('SDL_Rect', + [('x', rffi.INT), + ('y', rffi.INT), + ('w', rffi.INT), + ('h', rffi.INT)]) + + Surface = platform.Struct('SDL_Surface', + [('w', rffi.INT), + ('h', rffi.INT), + ('format', PixelFormatPtr), + ('pitch', rffi.INT), + ('pixels', rffi.UCHARP)]) + + PixelFormat = platform.Struct('SDL_PixelFormat', + [('BitsPerPixel', rffi.INT), + ('BytesPerPixel', rffi.INT), + ('Rmask', rffi.INT), + ('Gmask', rffi.INT), + ('Bmask', rffi.INT), + ('Amask', rffi.INT)]) + + Event = platform.Struct('SDL_Event', + [('type', rffi.INT)]) + + keysym = platform.Struct('SDL_keysym', + [('scancode', rffi.INT), + ('sym', rffi.INT), + ('mod', rffi.INT), + ('unicode', rffi.INT)]) + + KeyboardEvent = platform.Struct('SDL_KeyboardEvent', + [('type', rffi.INT), + ('state', rffi.INT), + ('keysym', keysym)]) + + MouseButtonEvent = platform.Struct('SDL_MouseButtonEvent', + [('type', rffi.INT), + ('button', rffi.INT), + ('state', rffi.INT), + ('x', rffi.INT), + ('y', rffi.INT)]) + + MouseMotionEvent = platform.Struct('SDL_MouseMotionEvent', + [('type', rffi.INT), + ('state', rffi.INT), + ('x', rffi.INT), + ('y', rffi.INT), + ('xrel', rffi.INT), + ('yrel', rffi.INT)]) + + QuitEvent = platform.Struct('SDL_QuitEvent', + [('type', rffi.INT)]) + + RWops = platform.Struct('SDL_RWops', []) + +# ------------------------------------------------------------------------------ + +for _prefix, _list in _constants.items(): + for _name in _list: + setattr(CConfig, _name, platform.ConstantInteger(_prefix+_name)) + +# ------------------------------------------------------------------------------ + +globals().update(platform.configure(CConfig)) + +# ------------------------------------------------------------------------------ + +RectPtr.TO.become(Rect) +SurfacePtr.TO.become(Surface) +PixelFormatPtr.TO.become(PixelFormat) +EventPtr.TO.become(Event) +KeyboardEventPtr.TO.become(KeyboardEvent) +MouseButtonEventPtr.TO.become(MouseButtonEvent) +MouseMotionEventPtr.TO.become(MouseMotionEvent) +RWopsPtr.TO.become(RWops) + +# ------------------------------------------------------------------------------ + +Uint8P = lltype.Ptr(lltype.Array(Uint8, hints={'nolength': True})) +Uint16P = lltype.Ptr(lltype.Array(Uint16, hints={'nolength': True})) +# need to add signed hint here +Sint16P = lltype.Ptr(lltype.Array(Sint16, hints={'nolength': True})) +Uint32P = lltype.Ptr(lltype.Array(Uint32, hints={'nolength': True})) + + +# ------------------------------------------------------------------------------ + +_Init = external('SDL_Init', + [Uint32], + rffi.INT) + +Mac_Init = external('SDL_Init', + [Uint32], + rffi.INT) + +Quit = external('SDL_Quit', [], + lltype.Void) + +SetVideoMode = external('SDL_SetVideoMode', + [rffi.INT, rffi.INT, rffi.INT, Uint32], + SurfacePtr) + +WM_SetCaption = external('SDL_WM_SetCaption', + [rffi.CCHARP, rffi.CCHARP], + lltype.Void) + +EnableUNICODE = external('SDL_EnableUNICODE', + [rffi.INT], + rffi.INT) + +WaitEvent = external('SDL_WaitEvent', + [EventPtr], + rffi.INT) + +PollEvent = external('SDL_PollEvent', + [EventPtr], + rffi.INT) + +Flip = external('SDL_Flip', + [SurfacePtr], + rffi.INT) + +CreateRGBSurface = external('SDL_CreateRGBSurface', + [Uint32, rffi.INT, rffi.INT, rffi.INT, + Uint32, Uint32, Uint32, Uint32], + SurfacePtr) + +CreateRGBSurfaceFrom = external('SDL_CreateRGBSurfaceFrom', + [rffi.VOIDP, rffi.INT, rffi.INT, rffi.INT, rffi.INT, + Uint32, Uint32, Uint32, Uint32], + SurfacePtr) + +LockSurface = external('SDL_LockSurface', + [SurfacePtr], + rffi.INT) + +UnlockSurface = external('SDL_UnlockSurface', + [SurfacePtr], + lltype.Void) + +FreeSurface = external('SDL_FreeSurface', + [SurfacePtr], + lltype.Void) + +MapRGB = external('SDL_MapRGB', + [PixelFormatPtr, Uint8, Uint8, Uint8], + Uint32) + +GetRGB = external('SDL_GetRGB', + [Uint32, PixelFormatPtr, Uint8P, Uint8P, Uint8P], + lltype.Void) + +GetRGBA = external('SDL_GetRGBA', + [Uint32, PixelFormatPtr, Uint8P, Uint8P, + Uint8P, Uint8P], + lltype.Void) + +FillRect = external('SDL_FillRect', + [SurfacePtr, RectPtr, Uint32], + rffi.INT) + +BlitSurface = external('SDL_UpperBlit', + [SurfacePtr, RectPtr, SurfacePtr, RectPtr], + rffi.INT) + +SetAlpha = external('SDL_SetAlpha', + [SurfacePtr, Uint32, Uint8], + rffi.INT) + +SetColorKey = external('SDL_SetColorKey', + [SurfacePtr, Uint32, Uint32], + rffi.INT) + +ShowCursor = external('SDL_ShowCursor', + [rffi.INT], + rffi.INT) + +GetTicks = external('SDL_GetTicks', + [], + Uint32) + +Delay = external('SDL_Delay', + [Uint32], + lltype.Void) + +UpdateRect = external('SDL_UpdateRect', + [SurfacePtr, rffi.INT, rffi.INT, rffi.INT], + lltype.Void) + +GetKeyName = external('SDL_GetKeyName', + [rffi.INT], + rffi.CCHARP) + +GetError = external('SDL_GetError', + [], + rffi.CCHARP) + +RWFromFile = external('SDL_RWFromFile', + [rffi.CCHARP, rffi.CCHARP], + RWopsPtr) + +# ------------------------------------------------------------------------------ + + +if sys.platform == 'darwin': + def Init(flags): + if not we_are_translated(): + from AppKit import NSApplication + NSApplication.sharedApplication() + #CustomApplicationMain(0, " ") + return _Init(flags) + #Mac_Init() +else: + Init = _Init + + + diff --git a/rsdl/rsdl/RSDL.pyc b/rsdl/rsdl/RSDL.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b60a72440a6c9b02f220c47e29d6bdf01c98c65 GIT binary patch [cut] diff --git a/rsdl/rsdl/RSDL_helper.py b/rsdl/rsdl/RSDL_helper.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/RSDL_helper.py @@ -0,0 +1,107 @@ +from rpython.rtyper.lltypesystem import lltype, rffi +from rsdl import RSDL + +def get_rgb(color, format): + rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 3, flavor='raw') + try: + RSDL.GetRGB(color, + format, + rffi.ptradd(rgb, 0), + rffi.ptradd(rgb, 1), + rffi.ptradd(rgb, 2)) + r = rffi.cast(lltype.Signed, rgb[0]) + g = rffi.cast(lltype.Signed, rgb[1]) + b = rffi.cast(lltype.Signed, rgb[2]) + result = r, g, b + finally: + lltype.free(rgb, flavor='raw') + + return result + +def get_rgba(color, format): + rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 4, flavor='raw') + try: + RSDL.GetRGBA(color, + format, + rffi.ptradd(rgb, 0), + rffi.ptradd(rgb, 1), + rffi.ptradd(rgb, 2), + rffi.ptradd(rgb, 3)) + r = rffi.cast(lltype.Signed, rgb[0]) + g = rffi.cast(lltype.Signed, rgb[1]) + b = rffi.cast(lltype.Signed, rgb[2]) + a = rffi.cast(lltype.Signed, rgb[3]) + result = r, g, b, a + finally: + lltype.free(rgb, flavor='raw') + + return result + +def get_pixel(image, x, y): + """Return the pixel value at (x, y) + NOTE: The surface must be locked before calling this! + """ + bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel') + pitch = rffi.getintfield(image, 'c_pitch') + # Here p is the address to the pixel we want to retrieve + p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp) + if bpp == 1: + return rffi.cast(RSDL.Uint32, p[0]) + elif bpp == 2: + p = rffi.cast(RSDL.Uint16P, p) + return rffi.cast(RSDL.Uint32, p[0]) + elif bpp == 3: + p0 = rffi.cast(lltype.Signed, p[0]) + p1 = rffi.cast(lltype.Signed, p[1]) + p2 = rffi.cast(lltype.Signed, p[2]) + if RSDL.BYTEORDER == RSDL.BIG_ENDIAN: + result = p0 << 16 | p1 << 8 | p2 + else: + result = p0 | p1 << 8 | p2 << 16 + return rffi.cast(RSDL.Uint32, result) + elif bpp == 4: + p = rffi.cast(RSDL.Uint32P, p) + return p[0] + else: + raise ValueError("bad BytesPerPixel") + +def set_pixel(image, x, y, pixel): + """Return the pixel value at (x, y) + NOTE: The surface must be locked before calling this! + """ + bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel') + pitch = rffi.getintfield(image, 'c_pitch') + # Here p is the address to the pixel we want to retrieve + p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp) + if bpp == 1: + p[0] = rffi.cast(rffi.UCHAR,pixel) + elif bpp == 2: + p = rffi.cast(RSDL.Uint16P, p) + p[0] = rffi.cast(RSDL.Uint16,pixel) + elif bpp == 3: + if RSDL.BYTEORDER == RSDL.BIG_ENDIAN: + p[0] = rffi.cast(rffi.UCHAR,(pixel >> 16) & 0xFF) + p[1] = rffi.cast(rffi.UCHAR,(pixel >> 8 ) & 0xFF) + p[2] = rffi.cast(rffi.UCHAR,pixel & 0xFF) + else: + p[0] = rffi.cast(rffi.UCHAR,pixel & 0xFF) + p[1] = rffi.cast(rffi.UCHAR,(pixel >> 8 ) & 0xFF) + p[2] = rffi.cast(rffi.UCHAR,(pixel >> 16) & 0xFF) + elif bpp == 4: + p = rffi.cast(RSDL.Uint32P, p) + p[0] = rffi.cast(RSDL.Uint32, pixel) + else: + raise ValueError("bad BytesPerPixel") + +def mallocrect(x, y, w, h): + p = lltype.malloc(RSDL.Rect, flavor='raw') + rffi.setintfield(p, 'c_x', x) + rffi.setintfield(p, 'c_y', y) + rffi.setintfield(p, 'c_w', w) + rffi.setintfield(p, 'c_h', h) + return p + +def blit_complete_surface(src, dst, x, y): + dstrect = mallocrect(x, y, rffi.getintfield(src, 'c_w'), rffi.getintfield(src, 'c_w')) + RSDL.BlitSurface(src, lltype.nullptr(RSDL.Rect), dst, dstrect) + lltype.free(dstrect, flavor='raw') diff --git a/rsdl/rsdl/RSDL_helper.pyc b/rsdl/rsdl/RSDL_helper.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c8e4d7ecfd0506041524c0030651f84045c0725 GIT binary patch [cut] diff --git a/rsdl/rsdl/RSDL_undef_main.h b/rsdl/rsdl/RSDL_undef_main.h new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/RSDL_undef_main.h @@ -0,0 +1,1 @@ +#undef main diff --git a/rsdl/rsdl/__init__.py b/rsdl/rsdl/__init__.py new file mode 100644 diff --git a/rsdl/rsdl/__init__.pyc b/rsdl/rsdl/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6db145d7298e482bf96f0ea0efe087e3ac06f3b8 GIT binary patch [cut] diff --git a/rsdl/rsdl/constants.py b/rsdl/rsdl/constants.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/constants.py @@ -0,0 +1,261 @@ + +_constants = { + 'SDL_': [ # constants with the 'SDL_' prefix in C + "YV12_OVERLAY", + "IYUV_OVERLAY", + "YUY2_OVERLAY", + "UYVY_OVERLAY", + "YVYU_OVERLAY", + + "SWSURFACE", + "HWSURFACE", + "RESIZABLE", + "ASYNCBLIT", + "OPENGL", + "OPENGLBLIT", + "ANYFORMAT", + "HWPALETTE", + "DOUBLEBUF", + "FULLSCREEN", + "HWACCEL", + "SRCCOLORKEY", + "RLEACCELOK", + "RLEACCEL", + "SRCALPHA", + "PREALLOC", + "NOFRAME", + + "GL_RED_SIZE", + "GL_GREEN_SIZE", + "GL_BLUE_SIZE", + "GL_ALPHA_SIZE", + "GL_BUFFER_SIZE", + "GL_DOUBLEBUFFER", + "GL_DEPTH_SIZE", + "GL_STENCIL_SIZE", + "GL_ACCUM_RED_SIZE", + "GL_ACCUM_GREEN_SIZE", + "GL_ACCUM_BLUE_SIZE", + "GL_ACCUM_ALPHA_SIZE", + "GL_STEREO", #if SDL_VERSION_ATLEAST(1, 2, 5) + "GL_MULTISAMPLEBUFFERS", #if SDL_VERSION_ATLEAST(1, 2, 6) + "GL_MULTISAMPLESAMPLES", #if SDL_VERSION_ATLEAST(1, 2, 6) + + "NOEVENT", + "ACTIVEEVENT", + "KEYDOWN", + "KEYUP", + "MOUSEMOTION", + "MOUSEBUTTONDOWN", + "MOUSEBUTTONUP", + "BUTTON_LEFT", + "BUTTON_MIDDLE", + "BUTTON_RIGHT", + "BUTTON_WHEELUP", + "BUTTON_WHEELDOWN", + "JOYAXISMOTION", + "JOYBALLMOTION", + "JOYHATMOTION", + "JOYBUTTONDOWN", + "JOYBUTTONUP", + "VIDEORESIZE", + "VIDEOEXPOSE", + "QUIT", + "SYSWMEVENT", + "USEREVENT", + "NUMEVENTS", + + "HAT_CENTERED", + "HAT_UP", + "HAT_RIGHTUP", + "HAT_RIGHT", + "HAT_RIGHTDOWN", + "HAT_DOWN", + "HAT_LEFTDOWN", + "HAT_LEFT", + "HAT_LEFTUP", + + "DISABLE", + "ENABLE", + + # the following ones are not exposed in Pygame + "INIT_VIDEO", + "BYTEORDER", + "BIG_ENDIAN", + "LIL_ENDIAN", + ], + + '': [ # constants with no prefix in C + "TIMER_RESOLUTION", + "AUDIO_U8", + "AUDIO_S8", + "AUDIO_U16LSB", + "AUDIO_S16LSB", + "AUDIO_U16MSB", + "AUDIO_S16MSB", + "AUDIO_U16", + "AUDIO_S16", + "AUDIO_U16SYS", + "AUDIO_S16SYS", + + "KMOD_NONE", + "KMOD_LSHIFT", + "KMOD_RSHIFT", + "KMOD_LCTRL", + "KMOD_RCTRL", + "KMOD_LALT", + "KMOD_RALT", + "KMOD_LMETA", + "KMOD_RMETA", + "KMOD_NUM", + "KMOD_CAPS", + "KMOD_MODE", + + "KMOD_CTRL", + "KMOD_SHIFT", + "KMOD_ALT", + "KMOD_META", + ], + + 'SDL': [ # constants with the 'SDL' prefix in C + "K_UNKNOWN", + "K_FIRST", + "K_BACKSPACE", + "K_TAB", + "K_CLEAR", + "K_RETURN", + "K_PAUSE", + "K_ESCAPE", + "K_SPACE", + "K_EXCLAIM", + "K_QUOTEDBL", + "K_HASH", + "K_DOLLAR", + "K_AMPERSAND", + "K_QUOTE", + "K_LEFTPAREN", + "K_RIGHTPAREN", + "K_ASTERISK", + "K_PLUS", + "K_COMMA", + "K_MINUS", + "K_PERIOD", + "K_SLASH", + "K_0", + "K_1", + "K_2", + "K_3", + "K_4", + "K_5", + "K_6", + "K_7", + "K_8", + "K_9", + "K_COLON", + "K_SEMICOLON", + "K_LESS", + "K_EQUALS", + "K_GREATER", + "K_QUESTION", + "K_AT", + "K_LEFTBRACKET", + "K_BACKSLASH", + "K_RIGHTBRACKET", + "K_CARET", + "K_UNDERSCORE", + "K_BACKQUOTE", + "K_a", + "K_b", + "K_c", + "K_d", + "K_e", + "K_f", + "K_g", + "K_h", + "K_i", + "K_j", + "K_k", + "K_l", + "K_m", + "K_n", + "K_o", + "K_p", + "K_q", + "K_r", + "K_s", + "K_t", + "K_u", + "K_v", + "K_w", + "K_x", + "K_y", + "K_z", + "K_DELETE", + + "K_KP0", + "K_KP1", + "K_KP2", + "K_KP3", + "K_KP4", + "K_KP5", + "K_KP6", + "K_KP7", + "K_KP8", + "K_KP9", + "K_KP_PERIOD", + "K_KP_DIVIDE", + "K_KP_MULTIPLY", + "K_KP_MINUS", + "K_KP_PLUS", + "K_KP_ENTER", + "K_KP_EQUALS", + "K_UP", + "K_DOWN", + "K_RIGHT", + "K_LEFT", + "K_INSERT", + "K_HOME", + "K_END", + "K_PAGEUP", + "K_PAGEDOWN", + "K_F1", + "K_F2", + "K_F3", + "K_F4", + "K_F5", + "K_F6", + "K_F7", + "K_F8", + "K_F9", + "K_F10", + "K_F11", + "K_F12", + "K_F13", + "K_F14", + "K_F15", + + "K_NUMLOCK", + "K_CAPSLOCK", + "K_SCROLLOCK", + "K_RSHIFT", + "K_LSHIFT", + "K_RCTRL", + "K_LCTRL", + "K_RALT", + "K_LALT", + "K_RMETA", + "K_LMETA", + "K_LSUPER", + "K_RSUPER", + "K_MODE", + + "K_HELP", + "K_PRINT", + "K_SYSREQ", + "K_BREAK", + "K_MENU", + "K_POWER", + "K_EURO", + "K_LAST", + ], + } diff --git a/rsdl/rsdl/constants.pyc b/rsdl/rsdl/constants.pyc new file mode 100644 index 0000000000000000000000000000000000000000..605c92505979ca198c6c419360e78d2600d7397c GIT binary patch [cut] diff --git a/rsdl/rsdl/eci.py b/rsdl/rsdl/eci.py new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/eci.py @@ -0,0 +1,53 @@ +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.translator.platform import CompilationError +import py +import sys +import os + +def get_rsdl_compilation_info(): + if sys.platform == 'darwin': + eci = ExternalCompilationInfo( + includes = ['SDL.h'], + include_dirs = ['/Library/Frameworks/SDL.framework/Headers'], + link_files = [ + str(py.path.local(__file__).dirpath().join('macosx-sdl-main/SDLMain.m')), + ], + frameworks = ['SDL', 'Cocoa'] + ) + elif sys.platform == "win32": + try: + sdl_prefix = os.path.abspath(os.environ["SDL_PREFIX"]) + except KeyError: + print "You need to provide the path to SDL using the SDL_PREFIX environment variable" + exit(1) + + # XXX: SDL_main.h does a #define main SDL_main + # This causes a linker error with the VS C compiler + # The solution is to #undef main before we define our own + this_dir = os.path.dirname(__file__) + f = open(os.path.join(this_dir, "RSDL_undef_main.h"), "w") + print >> f, "#undef main" + f.close() + + eci = ExternalCompilationInfo( + includes = ['SDL.h', 'RSDL_undef_main.h'], + include_dirs = [os.path.join(sdl_prefix, "include"), this_dir], + link_files = [ + os.path.join(sdl_prefix, "lib", "x86", "SDLmain.lib"), + os.path.join(sdl_prefix, "lib", "x86", "SDL.lib") + ], + libraries = ["SDL"], + library_dirs = [os.path.join(sdl_prefix, "lib", "x86")], + ) + else: + eci = ExternalCompilationInfo( + includes=['SDL.h'], + ) + eci = eci.merge(ExternalCompilationInfo.from_config_tool('sdl-config')) + return eci + +def check_sdl_installation(): + from pypy.rpython.tool import rffi_platform as platform + platform.verify_eci(get_rsdl_compilation_info()) + +SDLNotInstalled = (ImportError, CompilationError) diff --git a/rsdl/rsdl/eci.pyc b/rsdl/rsdl/eci.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84505e5610c50940bcf22e110080450460a026cb GIT binary patch [cut] diff --git a/rsdl/rsdl/macosx-sdl-main/SDLMain.h b/rsdl/rsdl/macosx-sdl-main/SDLMain.h new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/macosx-sdl-main/SDLMain.h @@ -0,0 +1,11 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import + + at interface SDLMain : NSObject + at end diff --git a/rsdl/rsdl/macosx-sdl-main/SDLMain.m b/rsdl/rsdl/macosx-sdl-main/SDLMain.m new file mode 100644 --- /dev/null +++ b/rsdl/rsdl/macosx-sdl-main/SDLMain.m @@ -0,0 +1,384 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import "SDL.h" +#import "SDLMain.h" +#import /* for MAXPATHLEN */ +#import + +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ + at interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; + at end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#ifdef SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; +static BOOL gCalledAppMainline = FALSE; + +static NSString *getApplicationName(void) +{ + NSDictionary *dict; + NSString *appName = 0; + + /* Determine the application name */ + dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ + at interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; + at end +#endif + + at interface SDLApplication : NSApplication + at end + + at implementation SDLApplication +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} + at end + +/* The main class of the application, the application's delegate */ + at implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { + assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } + +} + +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } + [ aMenu sizeToFit ]; +} + +#else + +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; +} + +/* Create a window menu */ +static void setupWindowMenu(void) +{ + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; + + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; + + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; +} + +/* Replacement for NSApplicationMain */ +static void CustomApplicationMain (int argc, char **argv) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; + + /* Ensure the application object is initialised */ + [SDLApplication sharedApplication]; + +#ifdef SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [SDLApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ + + /* Set up the menubar */ + [NSApp setMainMenu:[[NSMenu alloc] init]]; + setApplicationMenu(); + setupWindowMenu(); + + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; +} + +#endif + + +/* + * Catch document open requests...this lets us notice files when the app + * was launched by double-clicking a document, or when a document was + * dragged/dropped on the app's icon. You need to have a + * CFBundleDocumentsType section in your Info.plist to get this message, + * apparently. + * + * Files are added to gArgv, so to the app, they'll look like command line + * arguments. Previously, apps launched from the finder had nothing but + * an argv[0]. + * + * This message may be received multiple times to open several docs on launch. + * + * This message is ignored once the app's mainline has been called. + */ +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + const char *temparg; + size_t arglen; + char *arg; + char **newargv; + + if (!gFinderLaunch) /* MacOS is passing command line args. */ + return FALSE; + + if (gCalledAppMainline) /* app has started, ignore this document. */ + return FALSE; + + temparg = [filename UTF8String]; + arglen = SDL_strlen(temparg) + 1; + arg = (char *) SDL_malloc(arglen); + if (arg == NULL) + return FALSE; + + newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); + if (newargv == NULL) + { + SDL_free(arg); + return FALSE; + } + gArgv = newargv; + + SDL_strlcpy(arg, temparg, arglen); + gArgv[gArgc++] = arg; + gArgv[gArgc] = NULL; + return TRUE; +} + + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif + + /* Hand off to main application code */ + gCalledAppMainline = TRUE; + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} + at end + + + at implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + + at end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + /* Copy the arguments into a global variable */ + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgv = (char **) SDL_malloc(sizeof (char *) * 2); + gArgv[0] = argv[0]; + gArgv[1] = NULL; + gArgc = 1; + gFinderLaunch = YES; + } else { + int i; + gArgc = argc; + gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); + for (i = 0; i <= argc; i++) + gArgv[i] = argv[i]; + gFinderLaunch = NO; + } + +#if SDL_USE_NIB_FILE + [SDLApplication poseAsClass:[NSApplication class]]; + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; +} + diff --git a/rsdl/setup.py b/rsdl/setup.py new file mode 100644 --- /dev/null +++ b/rsdl/setup.py @@ -0,0 +1,19 @@ +from distutils.core import setup + + +with open("README.txt") as f: + readme = f.read() + +setup( + name="rsdl", + description="A SDL library that works with RPython", + long_description=readme, + version="0.1", + author="PyPy contributors", + author_email="timfelgentreff+rsdl at gmail.com", + url="https://bitbucket.org/pypy/rsdl/", + packages=["rsdl"], + classifiers=[ + "Programming Language :: RPython", + ] +) From noreply at buildbot.pypy.org Thu Mar 21 17:00:43 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 21 Mar 2013 17:00:43 +0100 (CET) Subject: [pypy-commit] lang-gameboy default: remove moved files Message-ID: <20130321160043.0F60F1C1502@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r9:3dd131846afc Date: 2013-03-21 16:53 +0100 http://bitbucket.org/pypy/lang-gameboy/changeset/3dd131846afc/ Log: remove moved files diff --git a/rsdl/RIMG.py b/rsdl/RIMG.py deleted file mode 100644 --- a/rsdl/RIMG.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform as platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rsdl import RSDL - - -if sys.platform == 'darwin': - eci = ExternalCompilationInfo( - includes = ['SDL_image.h'], - frameworks = ['SDL_image'], - include_dirs = ['/Library/Frameworks/SDL_image.framework/Headers'] - ) -else: - eci = ExternalCompilationInfo( - includes=['SDL_image.h'], - libraries=['SDL_image'], - ) - -eci = eci.merge(RSDL.eci) - -def external(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=eci) - -Load = external('IMG_Load', [rffi.CCHARP], RSDL.SurfacePtr) diff --git a/rsdl/RMix.py b/rsdl/RMix.py deleted file mode 100644 --- a/rsdl/RMix.py +++ /dev/null @@ -1,68 +0,0 @@ -import sys -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform as platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rsdl import RSDL - - -if sys.platform == 'darwin': - eci = ExternalCompilationInfo( - includes = ['SDL_mixer.h'], - frameworks = ['SDL_mixer'], - include_dirs = ['/Library/Frameworks/SDL_Mixer.framework/Headers'] - ) -else: - eci = ExternalCompilationInfo( - includes=['SDL_mixer.h'], - libraries=['SDL_mixer'], - ) - -eci = eci.merge(RSDL.eci) -eci = eci.merge(eci) -eci = eci.merge(eci) - -ChunkPtr = lltype.Ptr(lltype.ForwardReference()) - -class CConfig: - _compilation_info_ = eci - - Chunk = platform.Struct('Mix_Chunk', [('allocated', rffi.INT), - ('abuf', RSDL.Uint8P), - ('alen', RSDL.Uint32), - ('volume', RSDL.Uint8)]) - -globals().update(platform.configure(CConfig)) - -ChunkPtr.TO.become(Chunk) - - -Buffer = rffi.CArray(RSDL.Uint8) - -def external(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=eci) - -OpenAudio = external('Mix_OpenAudio', - [rffi.INT, RSDL.Uint16, rffi.INT, rffi.INT], - rffi.INT) - -CloseAudio = external('Mix_CloseAudio', [], lltype.Void) - -LoadWAV_RW = external('Mix_LoadWAV_RW', - [RSDL.RWopsPtr, rffi.INT], - ChunkPtr) - -def LoadWAV(filename_ccharp): - with rffi.scoped_str2charp('rb') as mode: - return LoadWAV_RW(RSDL.RWFromFile(filename_ccharp, mode), 1) - - -PlayChannelTimed = external('Mix_PlayChannelTimed', - [rffi.INT, ChunkPtr, rffi.INT, rffi.INT], - rffi.INT) - -def PlayChannel(channel,chunk,loops): - return PlayChannelTimed(channel, chunk, loops, -1) - -"""Returns zero if the channel is not playing. -Otherwise if you passed in -1, the number of channels playing is returned""" -ChannelPlaying = external('Mix_Playing', [rffi.INT], rffi.INT) diff --git a/rsdl/RMix_helper.py b/rsdl/RMix_helper.py deleted file mode 100644 --- a/rsdl/RMix_helper.py +++ /dev/null @@ -1,24 +0,0 @@ -from pypy.rpython.lltypesystem import lltype, rffi -from rsdl import RMix, RSDL -from pypy.rpython.tool import rffi_platform as platform - - -def malloc_buffer_chunk(has_own_allocated_buffer, length_bytes, volume): - buffer_pointer = lltype.malloc(RMix.Buffer, length_bytes, flavor='raw') - return malloc_chunk(has_own_allocated_buffer, length_bytes, volume) - -def malloc_chunk(has_own_allocated_buffer, buffer_pointer, length_bytes, volume): - """ - Creates a new Mix_Chunk. - has_own_allocated_buffer: if 1 struct has its own allocated buffer, - if 0 abuf should not be freed - buffer_pointer: pointer to audio data - length_bytes: length of audio data in bytes - volume: Per-sample volume, 0-128 (normally - MIX_MAX_VOLUME after loading)""" - p = lltype.malloc(RMix.Chunk, flavor='raw') - rffi.setintfield(p, 'c_allocated', has_own_allocated_buffer) - rffi.setintfield(p, 'c_abuf', buffer_pointer) - rffi.setintfield(p, 'c_alen', length_bytes) - rffi.setintfield(p, 'c_volume', volume) - return p diff --git a/rsdl/RSDL.py b/rsdl/RSDL.py deleted file mode 100644 --- a/rsdl/RSDL.py +++ /dev/null @@ -1,254 +0,0 @@ -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform as platform -from rsdl.constants import _constants -from rsdl.eci import get_rsdl_compilation_info -from rpython.rlib.objectmodel import we_are_translated -import py -import sys - -# ------------------------------------------------------------------------------ - -eci = get_rsdl_compilation_info() - -def external(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=eci) - -# ------------------------------------------------------------------------------ - -RectPtr = lltype.Ptr(lltype.ForwardReference()) -SurfacePtr = lltype.Ptr(lltype.ForwardReference()) -PixelFormatPtr = lltype.Ptr(lltype.ForwardReference()) -EventPtr = lltype.Ptr(lltype.ForwardReference()) -KeyboardEventPtr = lltype.Ptr(lltype.ForwardReference()) -MouseButtonEventPtr = lltype.Ptr(lltype.ForwardReference()) -MouseMotionEventPtr = lltype.Ptr(lltype.ForwardReference()) -KeyPtr = lltype.Ptr(lltype.ForwardReference()) -RWopsPtr = lltype.Ptr(lltype.ForwardReference()) - -# ------------------------------------------------------------------------------ - -class CConfig: - _compilation_info_ = eci - - Uint8 = platform.SimpleType('Uint8', rffi.INT) - Uint16 = platform.SimpleType('Uint16', rffi.INT) - Sint16 = platform.SimpleType('Sint16', rffi.INT) - Uint32 = platform.SimpleType('Uint32', rffi.INT) - - Rect = platform.Struct('SDL_Rect', - [('x', rffi.INT), - ('y', rffi.INT), - ('w', rffi.INT), - ('h', rffi.INT)]) - - Surface = platform.Struct('SDL_Surface', - [('w', rffi.INT), - ('h', rffi.INT), - ('format', PixelFormatPtr), - ('pitch', rffi.INT), - ('pixels', rffi.UCHARP)]) - - PixelFormat = platform.Struct('SDL_PixelFormat', - [('BitsPerPixel', rffi.INT), - ('BytesPerPixel', rffi.INT), - ('Rmask', rffi.INT), - ('Gmask', rffi.INT), - ('Bmask', rffi.INT), - ('Amask', rffi.INT)]) - - Event = platform.Struct('SDL_Event', - [('type', rffi.INT)]) - - keysym = platform.Struct('SDL_keysym', - [('scancode', rffi.INT), - ('sym', rffi.INT), - ('mod', rffi.INT), - ('unicode', rffi.INT)]) - - KeyboardEvent = platform.Struct('SDL_KeyboardEvent', - [('type', rffi.INT), - ('state', rffi.INT), - ('keysym', keysym)]) - - MouseButtonEvent = platform.Struct('SDL_MouseButtonEvent', - [('type', rffi.INT), - ('button', rffi.INT), - ('state', rffi.INT), - ('x', rffi.INT), - ('y', rffi.INT)]) - - MouseMotionEvent = platform.Struct('SDL_MouseMotionEvent', - [('type', rffi.INT), - ('state', rffi.INT), - ('x', rffi.INT), - ('y', rffi.INT), - ('xrel', rffi.INT), - ('yrel', rffi.INT)]) - - QuitEvent = platform.Struct('SDL_QuitEvent', - [('type', rffi.INT)]) - - RWops = platform.Struct('SDL_RWops', []) - -# ------------------------------------------------------------------------------ - -for _prefix, _list in _constants.items(): - for _name in _list: - setattr(CConfig, _name, platform.ConstantInteger(_prefix+_name)) - -# ------------------------------------------------------------------------------ - -globals().update(platform.configure(CConfig)) - -# ------------------------------------------------------------------------------ - -RectPtr.TO.become(Rect) -SurfacePtr.TO.become(Surface) -PixelFormatPtr.TO.become(PixelFormat) -EventPtr.TO.become(Event) -KeyboardEventPtr.TO.become(KeyboardEvent) -MouseButtonEventPtr.TO.become(MouseButtonEvent) -MouseMotionEventPtr.TO.become(MouseMotionEvent) -RWopsPtr.TO.become(RWops) - -# ------------------------------------------------------------------------------ - -Uint8P = lltype.Ptr(lltype.Array(Uint8, hints={'nolength': True})) -Uint16P = lltype.Ptr(lltype.Array(Uint16, hints={'nolength': True})) -# need to add signed hint here -Sint16P = lltype.Ptr(lltype.Array(Sint16, hints={'nolength': True})) -Uint32P = lltype.Ptr(lltype.Array(Uint32, hints={'nolength': True})) - - -# ------------------------------------------------------------------------------ - -_Init = external('SDL_Init', - [Uint32], - rffi.INT) - -Mac_Init = external('SDL_Init', - [Uint32], - rffi.INT) - -Quit = external('SDL_Quit', [], - lltype.Void) - -SetVideoMode = external('SDL_SetVideoMode', - [rffi.INT, rffi.INT, rffi.INT, Uint32], - SurfacePtr) - -WM_SetCaption = external('SDL_WM_SetCaption', - [rffi.CCHARP, rffi.CCHARP], - lltype.Void) - -EnableUNICODE = external('SDL_EnableUNICODE', - [rffi.INT], - rffi.INT) - -WaitEvent = external('SDL_WaitEvent', - [EventPtr], - rffi.INT) - -PollEvent = external('SDL_PollEvent', - [EventPtr], - rffi.INT) - -Flip = external('SDL_Flip', - [SurfacePtr], - rffi.INT) - -CreateRGBSurface = external('SDL_CreateRGBSurface', - [Uint32, rffi.INT, rffi.INT, rffi.INT, - Uint32, Uint32, Uint32, Uint32], - SurfacePtr) - -CreateRGBSurfaceFrom = external('SDL_CreateRGBSurfaceFrom', - [rffi.VOIDP, rffi.INT, rffi.INT, rffi.INT, rffi.INT, - Uint32, Uint32, Uint32, Uint32], - SurfacePtr) - -LockSurface = external('SDL_LockSurface', - [SurfacePtr], - rffi.INT) - -UnlockSurface = external('SDL_UnlockSurface', - [SurfacePtr], - lltype.Void) - -FreeSurface = external('SDL_FreeSurface', - [SurfacePtr], - lltype.Void) - -MapRGB = external('SDL_MapRGB', - [PixelFormatPtr, Uint8, Uint8, Uint8], - Uint32) - -GetRGB = external('SDL_GetRGB', - [Uint32, PixelFormatPtr, Uint8P, Uint8P, Uint8P], - lltype.Void) - -GetRGBA = external('SDL_GetRGBA', - [Uint32, PixelFormatPtr, Uint8P, Uint8P, - Uint8P, Uint8P], - lltype.Void) - -FillRect = external('SDL_FillRect', - [SurfacePtr, RectPtr, Uint32], - rffi.INT) - -BlitSurface = external('SDL_UpperBlit', - [SurfacePtr, RectPtr, SurfacePtr, RectPtr], - rffi.INT) - -SetAlpha = external('SDL_SetAlpha', - [SurfacePtr, Uint32, Uint8], - rffi.INT) - -SetColorKey = external('SDL_SetColorKey', - [SurfacePtr, Uint32, Uint32], - rffi.INT) - -ShowCursor = external('SDL_ShowCursor', - [rffi.INT], - rffi.INT) - -GetTicks = external('SDL_GetTicks', - [], - Uint32) - -Delay = external('SDL_Delay', - [Uint32], - lltype.Void) - -UpdateRect = external('SDL_UpdateRect', - [SurfacePtr, rffi.INT, rffi.INT, rffi.INT], - lltype.Void) - -GetKeyName = external('SDL_GetKeyName', - [rffi.INT], - rffi.CCHARP) - -GetError = external('SDL_GetError', - [], - rffi.CCHARP) - -RWFromFile = external('SDL_RWFromFile', - [rffi.CCHARP, rffi.CCHARP], - RWopsPtr) - -# ------------------------------------------------------------------------------ - - -if sys.platform == 'darwin': - def Init(flags): - if not we_are_translated(): - from AppKit import NSApplication - NSApplication.sharedApplication() - #CustomApplicationMain(0, " ") - return _Init(flags) - #Mac_Init() -else: - Init = _Init - - - diff --git a/rsdl/RSDL_helper.py b/rsdl/RSDL_helper.py deleted file mode 100644 --- a/rsdl/RSDL_helper.py +++ /dev/null @@ -1,107 +0,0 @@ -from rpython.rtyper.lltypesystem import lltype, rffi -from rsdl import RSDL - -def get_rgb(color, format): - rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 3, flavor='raw') - try: - RSDL.GetRGB(color, - format, - rffi.ptradd(rgb, 0), - rffi.ptradd(rgb, 1), - rffi.ptradd(rgb, 2)) - r = rffi.cast(lltype.Signed, rgb[0]) - g = rffi.cast(lltype.Signed, rgb[1]) - b = rffi.cast(lltype.Signed, rgb[2]) - result = r, g, b - finally: - lltype.free(rgb, flavor='raw') - - return result - -def get_rgba(color, format): - rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 4, flavor='raw') - try: - RSDL.GetRGBA(color, - format, - rffi.ptradd(rgb, 0), - rffi.ptradd(rgb, 1), - rffi.ptradd(rgb, 2), - rffi.ptradd(rgb, 3)) - r = rffi.cast(lltype.Signed, rgb[0]) - g = rffi.cast(lltype.Signed, rgb[1]) - b = rffi.cast(lltype.Signed, rgb[2]) - a = rffi.cast(lltype.Signed, rgb[3]) - result = r, g, b, a - finally: - lltype.free(rgb, flavor='raw') - - return result - -def get_pixel(image, x, y): - """Return the pixel value at (x, y) - NOTE: The surface must be locked before calling this! - """ - bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel') - pitch = rffi.getintfield(image, 'c_pitch') - # Here p is the address to the pixel we want to retrieve - p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp) - if bpp == 1: - return rffi.cast(RSDL.Uint32, p[0]) - elif bpp == 2: - p = rffi.cast(RSDL.Uint16P, p) - return rffi.cast(RSDL.Uint32, p[0]) - elif bpp == 3: - p0 = rffi.cast(lltype.Signed, p[0]) - p1 = rffi.cast(lltype.Signed, p[1]) - p2 = rffi.cast(lltype.Signed, p[2]) - if RSDL.BYTEORDER == RSDL.BIG_ENDIAN: - result = p0 << 16 | p1 << 8 | p2 - else: - result = p0 | p1 << 8 | p2 << 16 - return rffi.cast(RSDL.Uint32, result) - elif bpp == 4: - p = rffi.cast(RSDL.Uint32P, p) - return p[0] - else: - raise ValueError("bad BytesPerPixel") - -def set_pixel(image, x, y, pixel): - """Return the pixel value at (x, y) - NOTE: The surface must be locked before calling this! - """ - bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel') - pitch = rffi.getintfield(image, 'c_pitch') - # Here p is the address to the pixel we want to retrieve - p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp) - if bpp == 1: - p[0] = rffi.cast(rffi.UCHAR,pixel) - elif bpp == 2: - p = rffi.cast(RSDL.Uint16P, p) - p[0] = rffi.cast(RSDL.Uint16,pixel) - elif bpp == 3: - if RSDL.BYTEORDER == RSDL.BIG_ENDIAN: - p[0] = rffi.cast(rffi.UCHAR,(pixel >> 16) & 0xFF) - p[1] = rffi.cast(rffi.UCHAR,(pixel >> 8 ) & 0xFF) - p[2] = rffi.cast(rffi.UCHAR,pixel & 0xFF) - else: - p[0] = rffi.cast(rffi.UCHAR,pixel & 0xFF) - p[1] = rffi.cast(rffi.UCHAR,(pixel >> 8 ) & 0xFF) - p[2] = rffi.cast(rffi.UCHAR,(pixel >> 16) & 0xFF) - elif bpp == 4: - p = rffi.cast(RSDL.Uint32P, p) - p[0] = rffi.cast(RSDL.Uint32, pixel) - else: - raise ValueError("bad BytesPerPixel") - -def mallocrect(x, y, w, h): - p = lltype.malloc(RSDL.Rect, flavor='raw') - rffi.setintfield(p, 'c_x', x) - rffi.setintfield(p, 'c_y', y) - rffi.setintfield(p, 'c_w', w) - rffi.setintfield(p, 'c_h', h) - return p - -def blit_complete_surface(src, dst, x, y): - dstrect = mallocrect(x, y, rffi.getintfield(src, 'c_w'), rffi.getintfield(src, 'c_w')) - RSDL.BlitSurface(src, lltype.nullptr(RSDL.Rect), dst, dstrect) - lltype.free(dstrect, flavor='raw') diff --git a/rsdl/__init__.py b/rsdl/__init__.py deleted file mode 100644 diff --git a/rsdl/constants.py b/rsdl/constants.py deleted file mode 100644 --- a/rsdl/constants.py +++ /dev/null @@ -1,261 +0,0 @@ - -_constants = { - 'SDL_': [ # constants with the 'SDL_' prefix in C - "YV12_OVERLAY", - "IYUV_OVERLAY", - "YUY2_OVERLAY", - "UYVY_OVERLAY", - "YVYU_OVERLAY", - - "SWSURFACE", - "HWSURFACE", - "RESIZABLE", - "ASYNCBLIT", - "OPENGL", - "OPENGLBLIT", - "ANYFORMAT", - "HWPALETTE", - "DOUBLEBUF", - "FULLSCREEN", - "HWACCEL", - "SRCCOLORKEY", - "RLEACCELOK", - "RLEACCEL", - "SRCALPHA", - "PREALLOC", - "NOFRAME", - - "GL_RED_SIZE", - "GL_GREEN_SIZE", - "GL_BLUE_SIZE", - "GL_ALPHA_SIZE", - "GL_BUFFER_SIZE", - "GL_DOUBLEBUFFER", - "GL_DEPTH_SIZE", - "GL_STENCIL_SIZE", - "GL_ACCUM_RED_SIZE", - "GL_ACCUM_GREEN_SIZE", - "GL_ACCUM_BLUE_SIZE", - "GL_ACCUM_ALPHA_SIZE", - "GL_STEREO", #if SDL_VERSION_ATLEAST(1, 2, 5) - "GL_MULTISAMPLEBUFFERS", #if SDL_VERSION_ATLEAST(1, 2, 6) - "GL_MULTISAMPLESAMPLES", #if SDL_VERSION_ATLEAST(1, 2, 6) - - "NOEVENT", - "ACTIVEEVENT", - "KEYDOWN", - "KEYUP", - "MOUSEMOTION", - "MOUSEBUTTONDOWN", - "MOUSEBUTTONUP", - "BUTTON_LEFT", - "BUTTON_MIDDLE", - "BUTTON_RIGHT", - "BUTTON_WHEELUP", - "BUTTON_WHEELDOWN", - "JOYAXISMOTION", - "JOYBALLMOTION", - "JOYHATMOTION", - "JOYBUTTONDOWN", - "JOYBUTTONUP", - "VIDEORESIZE", - "VIDEOEXPOSE", - "QUIT", - "SYSWMEVENT", - "USEREVENT", - "NUMEVENTS", - - "HAT_CENTERED", - "HAT_UP", - "HAT_RIGHTUP", - "HAT_RIGHT", - "HAT_RIGHTDOWN", - "HAT_DOWN", - "HAT_LEFTDOWN", - "HAT_LEFT", - "HAT_LEFTUP", - - "DISABLE", - "ENABLE", - - # the following ones are not exposed in Pygame - "INIT_VIDEO", - "BYTEORDER", - "BIG_ENDIAN", - "LIL_ENDIAN", - ], - - '': [ # constants with no prefix in C - "TIMER_RESOLUTION", - "AUDIO_U8", - "AUDIO_S8", - "AUDIO_U16LSB", - "AUDIO_S16LSB", - "AUDIO_U16MSB", - "AUDIO_S16MSB", - "AUDIO_U16", - "AUDIO_S16", - "AUDIO_U16SYS", - "AUDIO_S16SYS", - - "KMOD_NONE", - "KMOD_LSHIFT", - "KMOD_RSHIFT", - "KMOD_LCTRL", - "KMOD_RCTRL", - "KMOD_LALT", - "KMOD_RALT", - "KMOD_LMETA", - "KMOD_RMETA", - "KMOD_NUM", - "KMOD_CAPS", - "KMOD_MODE", - - "KMOD_CTRL", - "KMOD_SHIFT", - "KMOD_ALT", - "KMOD_META", - ], - - 'SDL': [ # constants with the 'SDL' prefix in C - "K_UNKNOWN", - "K_FIRST", - "K_BACKSPACE", - "K_TAB", - "K_CLEAR", - "K_RETURN", - "K_PAUSE", - "K_ESCAPE", - "K_SPACE", - "K_EXCLAIM", - "K_QUOTEDBL", - "K_HASH", - "K_DOLLAR", - "K_AMPERSAND", - "K_QUOTE", - "K_LEFTPAREN", - "K_RIGHTPAREN", - "K_ASTERISK", - "K_PLUS", - "K_COMMA", - "K_MINUS", - "K_PERIOD", - "K_SLASH", - "K_0", - "K_1", - "K_2", - "K_3", - "K_4", - "K_5", - "K_6", - "K_7", - "K_8", - "K_9", - "K_COLON", - "K_SEMICOLON", - "K_LESS", - "K_EQUALS", - "K_GREATER", - "K_QUESTION", - "K_AT", - "K_LEFTBRACKET", - "K_BACKSLASH", - "K_RIGHTBRACKET", - "K_CARET", - "K_UNDERSCORE", - "K_BACKQUOTE", - "K_a", - "K_b", - "K_c", - "K_d", - "K_e", - "K_f", - "K_g", - "K_h", - "K_i", - "K_j", - "K_k", - "K_l", - "K_m", - "K_n", - "K_o", - "K_p", - "K_q", - "K_r", - "K_s", - "K_t", - "K_u", - "K_v", - "K_w", - "K_x", - "K_y", - "K_z", - "K_DELETE", - - "K_KP0", - "K_KP1", - "K_KP2", - "K_KP3", - "K_KP4", - "K_KP5", - "K_KP6", - "K_KP7", - "K_KP8", - "K_KP9", - "K_KP_PERIOD", - "K_KP_DIVIDE", - "K_KP_MULTIPLY", - "K_KP_MINUS", - "K_KP_PLUS", - "K_KP_ENTER", - "K_KP_EQUALS", - "K_UP", - "K_DOWN", - "K_RIGHT", - "K_LEFT", - "K_INSERT", - "K_HOME", - "K_END", - "K_PAGEUP", - "K_PAGEDOWN", - "K_F1", - "K_F2", - "K_F3", - "K_F4", - "K_F5", - "K_F6", - "K_F7", - "K_F8", - "K_F9", - "K_F10", - "K_F11", - "K_F12", - "K_F13", - "K_F14", - "K_F15", - - "K_NUMLOCK", - "K_CAPSLOCK", - "K_SCROLLOCK", - "K_RSHIFT", - "K_LSHIFT", - "K_RCTRL", - "K_LCTRL", - "K_RALT", - "K_LALT", - "K_RMETA", - "K_LMETA", - "K_LSUPER", - "K_RSUPER", - "K_MODE", - - "K_HELP", - "K_PRINT", - "K_SYSREQ", - "K_BREAK", - "K_MENU", - "K_POWER", - "K_EURO", - "K_LAST", - ], - } diff --git a/rsdl/eci.py b/rsdl/eci.py deleted file mode 100644 --- a/rsdl/eci.py +++ /dev/null @@ -1,53 +0,0 @@ -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rpython.translator.platform import CompilationError -import py -import sys -import os - -def get_rsdl_compilation_info(): - if sys.platform == 'darwin': - eci = ExternalCompilationInfo( - includes = ['SDL.h'], - include_dirs = ['/Library/Frameworks/SDL.framework/Headers'], - link_files = [ - str(py.path.local(__file__).dirpath().join('macosx-sdl-main/SDLMain.m')), - ], - frameworks = ['SDL', 'Cocoa'] - ) - elif sys.platform == "win32": - try: - sdl_prefix = os.path.abspath(os.environ["SDL_PREFIX"]) - except KeyError: - print "You need to provide the path to SDL using the SDL_PREFIX environment variable" - exit(1) - - # XXX: SDL_main.h does a #define main SDL_main - # This causes a linker error with the VS C compiler - # The solution is to #undef main before we define our own - this_dir = os.path.dirname(__file__) - f = open(os.path.join(this_dir, "RSDL_undef_main.h"), "w") - print >> f, "#undef main" - f.close() - - eci = ExternalCompilationInfo( - includes = ['SDL.h', 'RSDL_undef_main.h'], - include_dirs = [os.path.join(sdl_prefix, "include"), this_dir], - link_files = [ - os.path.join(sdl_prefix, "lib", "x86", "SDLmain.lib"), - os.path.join(sdl_prefix, "lib", "x86", "SDL.lib") - ], - libraries = ["SDL"], - library_dirs = [os.path.join(sdl_prefix, "lib", "x86")], - ) - else: - eci = ExternalCompilationInfo( - includes=['SDL.h'], - ) - eci = eci.merge(ExternalCompilationInfo.from_config_tool('sdl-config')) - return eci - -def check_sdl_installation(): - from pypy.rpython.tool import rffi_platform as platform - platform.verify_eci(get_rsdl_compilation_info()) - -SDLNotInstalled = (ImportError, CompilationError) diff --git a/rsdl/macosx-sdl-main/SDLMain.h b/rsdl/macosx-sdl-main/SDLMain.h deleted file mode 100644 --- a/rsdl/macosx-sdl-main/SDLMain.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import - - at interface SDLMain : NSObject - at end diff --git a/rsdl/macosx-sdl-main/SDLMain.m b/rsdl/macosx-sdl-main/SDLMain.m deleted file mode 100644 --- a/rsdl/macosx-sdl-main/SDLMain.m +++ /dev/null @@ -1,384 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import "SDL.h" -#import "SDLMain.h" -#import /* for MAXPATHLEN */ -#import - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ - at interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; - at end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ - at interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; - at end -#endif - - at interface SDLApplication : NSApplication - at end - - at implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} - at end - -/* The main class of the application, the application's delegate */ - at implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { - assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } - -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} - at end - - - at implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - - at end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - From noreply at buildbot.pypy.org Thu Mar 21 17:16:49 2013 From: noreply at buildbot.pypy.org (timfel) Date: Thu, 21 Mar 2013 17:16:49 +0100 (CET) Subject: [pypy-commit] lang-gameboy default: rsdl moved into it's own repository Message-ID: <20130321161649.1F0CC1C10C2@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r10:410e34ee2cff Date: 2013-03-21 17:15 +0100 http://bitbucket.org/pypy/lang-gameboy/changeset/410e34ee2cff/ Log: rsdl moved into it's own repository diff --git a/rsdl/README.txt b/rsdl/README.txt deleted file mode 100644 --- a/rsdl/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -RSDL -==== - -RSDL is an SDL library for use with RPython. It is used in the Gameboy -emulator "PyGirl" and the Squeak VM "Spy". It currently supports a -useful subset of the video, image, and audio SDL APIs. diff --git a/rsdl/rsdl/RIMG.py b/rsdl/rsdl/RIMG.py deleted file mode 100644 --- a/rsdl/rsdl/RIMG.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform as platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rsdl import RSDL - - -if sys.platform == 'darwin': - eci = ExternalCompilationInfo( - includes = ['SDL_image.h'], - frameworks = ['SDL_image'], - include_dirs = ['/Library/Frameworks/SDL_image.framework/Headers'] - ) -else: - eci = ExternalCompilationInfo( - includes=['SDL_image.h'], - libraries=['SDL_image'], - ) - -eci = eci.merge(RSDL.eci) - -def external(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=eci) - -Load = external('IMG_Load', [rffi.CCHARP], RSDL.SurfacePtr) diff --git a/rsdl/rsdl/RMix.py b/rsdl/rsdl/RMix.py deleted file mode 100644 --- a/rsdl/rsdl/RMix.py +++ /dev/null @@ -1,68 +0,0 @@ -import sys -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform as platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rsdl import RSDL - - -if sys.platform == 'darwin': - eci = ExternalCompilationInfo( - includes = ['SDL_mixer.h'], - frameworks = ['SDL_mixer'], - include_dirs = ['/Library/Frameworks/SDL_Mixer.framework/Headers'] - ) -else: - eci = ExternalCompilationInfo( - includes=['SDL_mixer.h'], - libraries=['SDL_mixer'], - ) - -eci = eci.merge(RSDL.eci) -eci = eci.merge(eci) -eci = eci.merge(eci) - -ChunkPtr = lltype.Ptr(lltype.ForwardReference()) - -class CConfig: - _compilation_info_ = eci - - Chunk = platform.Struct('Mix_Chunk', [('allocated', rffi.INT), - ('abuf', RSDL.Uint8P), - ('alen', RSDL.Uint32), - ('volume', RSDL.Uint8)]) - -globals().update(platform.configure(CConfig)) - -ChunkPtr.TO.become(Chunk) - - -Buffer = rffi.CArray(RSDL.Uint8) - -def external(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=eci) - -OpenAudio = external('Mix_OpenAudio', - [rffi.INT, RSDL.Uint16, rffi.INT, rffi.INT], - rffi.INT) - -CloseAudio = external('Mix_CloseAudio', [], lltype.Void) - -LoadWAV_RW = external('Mix_LoadWAV_RW', - [RSDL.RWopsPtr, rffi.INT], - ChunkPtr) - -def LoadWAV(filename_ccharp): - with rffi.scoped_str2charp('rb') as mode: - return LoadWAV_RW(RSDL.RWFromFile(filename_ccharp, mode), 1) - - -PlayChannelTimed = external('Mix_PlayChannelTimed', - [rffi.INT, ChunkPtr, rffi.INT, rffi.INT], - rffi.INT) - -def PlayChannel(channel,chunk,loops): - return PlayChannelTimed(channel, chunk, loops, -1) - -"""Returns zero if the channel is not playing. -Otherwise if you passed in -1, the number of channels playing is returned""" -ChannelPlaying = external('Mix_Playing', [rffi.INT], rffi.INT) diff --git a/rsdl/rsdl/RMix_helper.py b/rsdl/rsdl/RMix_helper.py deleted file mode 100644 --- a/rsdl/rsdl/RMix_helper.py +++ /dev/null @@ -1,24 +0,0 @@ -from pypy.rpython.lltypesystem import lltype, rffi -from rsdl import RMix, RSDL -from pypy.rpython.tool import rffi_platform as platform - - -def malloc_buffer_chunk(has_own_allocated_buffer, length_bytes, volume): - buffer_pointer = lltype.malloc(RMix.Buffer, length_bytes, flavor='raw') - return malloc_chunk(has_own_allocated_buffer, length_bytes, volume) - -def malloc_chunk(has_own_allocated_buffer, buffer_pointer, length_bytes, volume): - """ - Creates a new Mix_Chunk. - has_own_allocated_buffer: if 1 struct has its own allocated buffer, - if 0 abuf should not be freed - buffer_pointer: pointer to audio data - length_bytes: length of audio data in bytes - volume: Per-sample volume, 0-128 (normally - MIX_MAX_VOLUME after loading)""" - p = lltype.malloc(RMix.Chunk, flavor='raw') - rffi.setintfield(p, 'c_allocated', has_own_allocated_buffer) - rffi.setintfield(p, 'c_abuf', buffer_pointer) - rffi.setintfield(p, 'c_alen', length_bytes) - rffi.setintfield(p, 'c_volume', volume) - return p diff --git a/rsdl/rsdl/RSDL.py b/rsdl/rsdl/RSDL.py deleted file mode 100644 --- a/rsdl/rsdl/RSDL.py +++ /dev/null @@ -1,254 +0,0 @@ -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform as platform -from rsdl.constants import _constants -from rsdl.eci import get_rsdl_compilation_info -from rpython.rlib.objectmodel import we_are_translated -import py -import sys - -# ------------------------------------------------------------------------------ - -eci = get_rsdl_compilation_info() - -def external(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=eci) - -# ------------------------------------------------------------------------------ - -RectPtr = lltype.Ptr(lltype.ForwardReference()) -SurfacePtr = lltype.Ptr(lltype.ForwardReference()) -PixelFormatPtr = lltype.Ptr(lltype.ForwardReference()) -EventPtr = lltype.Ptr(lltype.ForwardReference()) -KeyboardEventPtr = lltype.Ptr(lltype.ForwardReference()) -MouseButtonEventPtr = lltype.Ptr(lltype.ForwardReference()) -MouseMotionEventPtr = lltype.Ptr(lltype.ForwardReference()) -KeyPtr = lltype.Ptr(lltype.ForwardReference()) -RWopsPtr = lltype.Ptr(lltype.ForwardReference()) - -# ------------------------------------------------------------------------------ - -class CConfig: - _compilation_info_ = eci - - Uint8 = platform.SimpleType('Uint8', rffi.INT) - Uint16 = platform.SimpleType('Uint16', rffi.INT) - Sint16 = platform.SimpleType('Sint16', rffi.INT) - Uint32 = platform.SimpleType('Uint32', rffi.INT) - - Rect = platform.Struct('SDL_Rect', - [('x', rffi.INT), - ('y', rffi.INT), - ('w', rffi.INT), - ('h', rffi.INT)]) - - Surface = platform.Struct('SDL_Surface', - [('w', rffi.INT), - ('h', rffi.INT), - ('format', PixelFormatPtr), - ('pitch', rffi.INT), - ('pixels', rffi.UCHARP)]) - - PixelFormat = platform.Struct('SDL_PixelFormat', - [('BitsPerPixel', rffi.INT), - ('BytesPerPixel', rffi.INT), - ('Rmask', rffi.INT), - ('Gmask', rffi.INT), - ('Bmask', rffi.INT), - ('Amask', rffi.INT)]) - - Event = platform.Struct('SDL_Event', - [('type', rffi.INT)]) - - keysym = platform.Struct('SDL_keysym', - [('scancode', rffi.INT), - ('sym', rffi.INT), - ('mod', rffi.INT), - ('unicode', rffi.INT)]) - - KeyboardEvent = platform.Struct('SDL_KeyboardEvent', - [('type', rffi.INT), - ('state', rffi.INT), - ('keysym', keysym)]) - - MouseButtonEvent = platform.Struct('SDL_MouseButtonEvent', - [('type', rffi.INT), - ('button', rffi.INT), - ('state', rffi.INT), - ('x', rffi.INT), - ('y', rffi.INT)]) - - MouseMotionEvent = platform.Struct('SDL_MouseMotionEvent', - [('type', rffi.INT), - ('state', rffi.INT), - ('x', rffi.INT), - ('y', rffi.INT), - ('xrel', rffi.INT), - ('yrel', rffi.INT)]) - - QuitEvent = platform.Struct('SDL_QuitEvent', - [('type', rffi.INT)]) - - RWops = platform.Struct('SDL_RWops', []) - -# ------------------------------------------------------------------------------ - -for _prefix, _list in _constants.items(): - for _name in _list: - setattr(CConfig, _name, platform.ConstantInteger(_prefix+_name)) - -# ------------------------------------------------------------------------------ - -globals().update(platform.configure(CConfig)) - -# ------------------------------------------------------------------------------ - -RectPtr.TO.become(Rect) -SurfacePtr.TO.become(Surface) -PixelFormatPtr.TO.become(PixelFormat) -EventPtr.TO.become(Event) -KeyboardEventPtr.TO.become(KeyboardEvent) -MouseButtonEventPtr.TO.become(MouseButtonEvent) -MouseMotionEventPtr.TO.become(MouseMotionEvent) -RWopsPtr.TO.become(RWops) - -# ------------------------------------------------------------------------------ - -Uint8P = lltype.Ptr(lltype.Array(Uint8, hints={'nolength': True})) -Uint16P = lltype.Ptr(lltype.Array(Uint16, hints={'nolength': True})) -# need to add signed hint here -Sint16P = lltype.Ptr(lltype.Array(Sint16, hints={'nolength': True})) -Uint32P = lltype.Ptr(lltype.Array(Uint32, hints={'nolength': True})) - - -# ------------------------------------------------------------------------------ - -_Init = external('SDL_Init', - [Uint32], - rffi.INT) - -Mac_Init = external('SDL_Init', - [Uint32], - rffi.INT) - -Quit = external('SDL_Quit', [], - lltype.Void) - -SetVideoMode = external('SDL_SetVideoMode', - [rffi.INT, rffi.INT, rffi.INT, Uint32], - SurfacePtr) - -WM_SetCaption = external('SDL_WM_SetCaption', - [rffi.CCHARP, rffi.CCHARP], - lltype.Void) - -EnableUNICODE = external('SDL_EnableUNICODE', - [rffi.INT], - rffi.INT) - -WaitEvent = external('SDL_WaitEvent', - [EventPtr], - rffi.INT) - -PollEvent = external('SDL_PollEvent', - [EventPtr], - rffi.INT) - -Flip = external('SDL_Flip', - [SurfacePtr], - rffi.INT) - -CreateRGBSurface = external('SDL_CreateRGBSurface', - [Uint32, rffi.INT, rffi.INT, rffi.INT, - Uint32, Uint32, Uint32, Uint32], - SurfacePtr) - -CreateRGBSurfaceFrom = external('SDL_CreateRGBSurfaceFrom', - [rffi.VOIDP, rffi.INT, rffi.INT, rffi.INT, rffi.INT, - Uint32, Uint32, Uint32, Uint32], - SurfacePtr) - -LockSurface = external('SDL_LockSurface', - [SurfacePtr], - rffi.INT) - -UnlockSurface = external('SDL_UnlockSurface', - [SurfacePtr], - lltype.Void) - -FreeSurface = external('SDL_FreeSurface', - [SurfacePtr], - lltype.Void) - -MapRGB = external('SDL_MapRGB', - [PixelFormatPtr, Uint8, Uint8, Uint8], - Uint32) - -GetRGB = external('SDL_GetRGB', - [Uint32, PixelFormatPtr, Uint8P, Uint8P, Uint8P], - lltype.Void) - -GetRGBA = external('SDL_GetRGBA', - [Uint32, PixelFormatPtr, Uint8P, Uint8P, - Uint8P, Uint8P], - lltype.Void) - -FillRect = external('SDL_FillRect', - [SurfacePtr, RectPtr, Uint32], - rffi.INT) - -BlitSurface = external('SDL_UpperBlit', - [SurfacePtr, RectPtr, SurfacePtr, RectPtr], - rffi.INT) - -SetAlpha = external('SDL_SetAlpha', - [SurfacePtr, Uint32, Uint8], - rffi.INT) - -SetColorKey = external('SDL_SetColorKey', - [SurfacePtr, Uint32, Uint32], - rffi.INT) - -ShowCursor = external('SDL_ShowCursor', - [rffi.INT], - rffi.INT) - -GetTicks = external('SDL_GetTicks', - [], - Uint32) - -Delay = external('SDL_Delay', - [Uint32], - lltype.Void) - -UpdateRect = external('SDL_UpdateRect', - [SurfacePtr, rffi.INT, rffi.INT, rffi.INT], - lltype.Void) - -GetKeyName = external('SDL_GetKeyName', - [rffi.INT], - rffi.CCHARP) - -GetError = external('SDL_GetError', - [], - rffi.CCHARP) - -RWFromFile = external('SDL_RWFromFile', - [rffi.CCHARP, rffi.CCHARP], - RWopsPtr) - -# ------------------------------------------------------------------------------ - - -if sys.platform == 'darwin': - def Init(flags): - if not we_are_translated(): - from AppKit import NSApplication - NSApplication.sharedApplication() - #CustomApplicationMain(0, " ") - return _Init(flags) - #Mac_Init() -else: - Init = _Init - - - diff --git a/rsdl/rsdl/RSDL.pyc b/rsdl/rsdl/RSDL.pyc deleted file mode 100644 Binary file rsdl/rsdl/RSDL.pyc has changed diff --git a/rsdl/rsdl/RSDL_helper.py b/rsdl/rsdl/RSDL_helper.py deleted file mode 100644 --- a/rsdl/rsdl/RSDL_helper.py +++ /dev/null @@ -1,107 +0,0 @@ -from rpython.rtyper.lltypesystem import lltype, rffi -from rsdl import RSDL - -def get_rgb(color, format): - rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 3, flavor='raw') - try: - RSDL.GetRGB(color, - format, - rffi.ptradd(rgb, 0), - rffi.ptradd(rgb, 1), - rffi.ptradd(rgb, 2)) - r = rffi.cast(lltype.Signed, rgb[0]) - g = rffi.cast(lltype.Signed, rgb[1]) - b = rffi.cast(lltype.Signed, rgb[2]) - result = r, g, b - finally: - lltype.free(rgb, flavor='raw') - - return result - -def get_rgba(color, format): - rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 4, flavor='raw') - try: - RSDL.GetRGBA(color, - format, - rffi.ptradd(rgb, 0), - rffi.ptradd(rgb, 1), - rffi.ptradd(rgb, 2), - rffi.ptradd(rgb, 3)) - r = rffi.cast(lltype.Signed, rgb[0]) - g = rffi.cast(lltype.Signed, rgb[1]) - b = rffi.cast(lltype.Signed, rgb[2]) - a = rffi.cast(lltype.Signed, rgb[3]) - result = r, g, b, a - finally: - lltype.free(rgb, flavor='raw') - - return result - -def get_pixel(image, x, y): - """Return the pixel value at (x, y) - NOTE: The surface must be locked before calling this! - """ - bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel') - pitch = rffi.getintfield(image, 'c_pitch') - # Here p is the address to the pixel we want to retrieve - p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp) - if bpp == 1: - return rffi.cast(RSDL.Uint32, p[0]) - elif bpp == 2: - p = rffi.cast(RSDL.Uint16P, p) - return rffi.cast(RSDL.Uint32, p[0]) - elif bpp == 3: - p0 = rffi.cast(lltype.Signed, p[0]) - p1 = rffi.cast(lltype.Signed, p[1]) - p2 = rffi.cast(lltype.Signed, p[2]) - if RSDL.BYTEORDER == RSDL.BIG_ENDIAN: - result = p0 << 16 | p1 << 8 | p2 - else: - result = p0 | p1 << 8 | p2 << 16 - return rffi.cast(RSDL.Uint32, result) - elif bpp == 4: - p = rffi.cast(RSDL.Uint32P, p) - return p[0] - else: - raise ValueError("bad BytesPerPixel") - -def set_pixel(image, x, y, pixel): - """Return the pixel value at (x, y) - NOTE: The surface must be locked before calling this! - """ - bpp = rffi.getintfield(image.c_format, 'c_BytesPerPixel') - pitch = rffi.getintfield(image, 'c_pitch') - # Here p is the address to the pixel we want to retrieve - p = rffi.ptradd(image.c_pixels, y * pitch + x * bpp) - if bpp == 1: - p[0] = rffi.cast(rffi.UCHAR,pixel) - elif bpp == 2: - p = rffi.cast(RSDL.Uint16P, p) - p[0] = rffi.cast(RSDL.Uint16,pixel) - elif bpp == 3: - if RSDL.BYTEORDER == RSDL.BIG_ENDIAN: - p[0] = rffi.cast(rffi.UCHAR,(pixel >> 16) & 0xFF) - p[1] = rffi.cast(rffi.UCHAR,(pixel >> 8 ) & 0xFF) - p[2] = rffi.cast(rffi.UCHAR,pixel & 0xFF) - else: - p[0] = rffi.cast(rffi.UCHAR,pixel & 0xFF) - p[1] = rffi.cast(rffi.UCHAR,(pixel >> 8 ) & 0xFF) - p[2] = rffi.cast(rffi.UCHAR,(pixel >> 16) & 0xFF) - elif bpp == 4: - p = rffi.cast(RSDL.Uint32P, p) - p[0] = rffi.cast(RSDL.Uint32, pixel) - else: - raise ValueError("bad BytesPerPixel") - -def mallocrect(x, y, w, h): - p = lltype.malloc(RSDL.Rect, flavor='raw') - rffi.setintfield(p, 'c_x', x) - rffi.setintfield(p, 'c_y', y) - rffi.setintfield(p, 'c_w', w) - rffi.setintfield(p, 'c_h', h) - return p - -def blit_complete_surface(src, dst, x, y): - dstrect = mallocrect(x, y, rffi.getintfield(src, 'c_w'), rffi.getintfield(src, 'c_w')) - RSDL.BlitSurface(src, lltype.nullptr(RSDL.Rect), dst, dstrect) - lltype.free(dstrect, flavor='raw') diff --git a/rsdl/rsdl/RSDL_helper.pyc b/rsdl/rsdl/RSDL_helper.pyc deleted file mode 100644 Binary file rsdl/rsdl/RSDL_helper.pyc has changed diff --git a/rsdl/rsdl/RSDL_undef_main.h b/rsdl/rsdl/RSDL_undef_main.h deleted file mode 100644 --- a/rsdl/rsdl/RSDL_undef_main.h +++ /dev/null @@ -1,1 +0,0 @@ -#undef main diff --git a/rsdl/rsdl/__init__.py b/rsdl/rsdl/__init__.py deleted file mode 100644 diff --git a/rsdl/rsdl/__init__.pyc b/rsdl/rsdl/__init__.pyc deleted file mode 100644 Binary file rsdl/rsdl/__init__.pyc has changed diff --git a/rsdl/rsdl/constants.py b/rsdl/rsdl/constants.py deleted file mode 100644 --- a/rsdl/rsdl/constants.py +++ /dev/null @@ -1,261 +0,0 @@ - -_constants = { - 'SDL_': [ # constants with the 'SDL_' prefix in C - "YV12_OVERLAY", - "IYUV_OVERLAY", - "YUY2_OVERLAY", - "UYVY_OVERLAY", - "YVYU_OVERLAY", - - "SWSURFACE", - "HWSURFACE", - "RESIZABLE", - "ASYNCBLIT", - "OPENGL", - "OPENGLBLIT", - "ANYFORMAT", - "HWPALETTE", - "DOUBLEBUF", - "FULLSCREEN", - "HWACCEL", - "SRCCOLORKEY", - "RLEACCELOK", - "RLEACCEL", - "SRCALPHA", - "PREALLOC", - "NOFRAME", - - "GL_RED_SIZE", - "GL_GREEN_SIZE", - "GL_BLUE_SIZE", - "GL_ALPHA_SIZE", - "GL_BUFFER_SIZE", - "GL_DOUBLEBUFFER", - "GL_DEPTH_SIZE", - "GL_STENCIL_SIZE", - "GL_ACCUM_RED_SIZE", - "GL_ACCUM_GREEN_SIZE", - "GL_ACCUM_BLUE_SIZE", - "GL_ACCUM_ALPHA_SIZE", - "GL_STEREO", #if SDL_VERSION_ATLEAST(1, 2, 5) - "GL_MULTISAMPLEBUFFERS", #if SDL_VERSION_ATLEAST(1, 2, 6) - "GL_MULTISAMPLESAMPLES", #if SDL_VERSION_ATLEAST(1, 2, 6) - - "NOEVENT", - "ACTIVEEVENT", - "KEYDOWN", - "KEYUP", - "MOUSEMOTION", - "MOUSEBUTTONDOWN", - "MOUSEBUTTONUP", - "BUTTON_LEFT", - "BUTTON_MIDDLE", - "BUTTON_RIGHT", - "BUTTON_WHEELUP", - "BUTTON_WHEELDOWN", - "JOYAXISMOTION", - "JOYBALLMOTION", - "JOYHATMOTION", - "JOYBUTTONDOWN", - "JOYBUTTONUP", - "VIDEORESIZE", - "VIDEOEXPOSE", - "QUIT", - "SYSWMEVENT", - "USEREVENT", - "NUMEVENTS", - - "HAT_CENTERED", - "HAT_UP", - "HAT_RIGHTUP", - "HAT_RIGHT", - "HAT_RIGHTDOWN", - "HAT_DOWN", - "HAT_LEFTDOWN", - "HAT_LEFT", - "HAT_LEFTUP", - - "DISABLE", - "ENABLE", - - # the following ones are not exposed in Pygame - "INIT_VIDEO", - "BYTEORDER", - "BIG_ENDIAN", - "LIL_ENDIAN", - ], - - '': [ # constants with no prefix in C - "TIMER_RESOLUTION", - "AUDIO_U8", - "AUDIO_S8", - "AUDIO_U16LSB", - "AUDIO_S16LSB", - "AUDIO_U16MSB", - "AUDIO_S16MSB", - "AUDIO_U16", - "AUDIO_S16", - "AUDIO_U16SYS", - "AUDIO_S16SYS", - - "KMOD_NONE", - "KMOD_LSHIFT", - "KMOD_RSHIFT", - "KMOD_LCTRL", - "KMOD_RCTRL", - "KMOD_LALT", - "KMOD_RALT", - "KMOD_LMETA", - "KMOD_RMETA", - "KMOD_NUM", - "KMOD_CAPS", - "KMOD_MODE", - - "KMOD_CTRL", - "KMOD_SHIFT", - "KMOD_ALT", - "KMOD_META", - ], - - 'SDL': [ # constants with the 'SDL' prefix in C - "K_UNKNOWN", - "K_FIRST", - "K_BACKSPACE", - "K_TAB", - "K_CLEAR", - "K_RETURN", - "K_PAUSE", - "K_ESCAPE", - "K_SPACE", - "K_EXCLAIM", - "K_QUOTEDBL", - "K_HASH", - "K_DOLLAR", - "K_AMPERSAND", - "K_QUOTE", - "K_LEFTPAREN", - "K_RIGHTPAREN", - "K_ASTERISK", - "K_PLUS", - "K_COMMA", - "K_MINUS", - "K_PERIOD", - "K_SLASH", - "K_0", - "K_1", - "K_2", - "K_3", - "K_4", - "K_5", - "K_6", - "K_7", - "K_8", - "K_9", - "K_COLON", - "K_SEMICOLON", - "K_LESS", - "K_EQUALS", - "K_GREATER", - "K_QUESTION", - "K_AT", - "K_LEFTBRACKET", - "K_BACKSLASH", - "K_RIGHTBRACKET", - "K_CARET", - "K_UNDERSCORE", - "K_BACKQUOTE", - "K_a", - "K_b", - "K_c", - "K_d", - "K_e", - "K_f", - "K_g", - "K_h", - "K_i", - "K_j", - "K_k", - "K_l", - "K_m", - "K_n", - "K_o", - "K_p", - "K_q", - "K_r", - "K_s", - "K_t", - "K_u", - "K_v", - "K_w", - "K_x", - "K_y", - "K_z", - "K_DELETE", - - "K_KP0", - "K_KP1", - "K_KP2", - "K_KP3", - "K_KP4", - "K_KP5", - "K_KP6", - "K_KP7", - "K_KP8", - "K_KP9", - "K_KP_PERIOD", - "K_KP_DIVIDE", - "K_KP_MULTIPLY", - "K_KP_MINUS", - "K_KP_PLUS", - "K_KP_ENTER", - "K_KP_EQUALS", - "K_UP", - "K_DOWN", - "K_RIGHT", - "K_LEFT", - "K_INSERT", - "K_HOME", - "K_END", - "K_PAGEUP", - "K_PAGEDOWN", - "K_F1", - "K_F2", - "K_F3", - "K_F4", - "K_F5", - "K_F6", - "K_F7", - "K_F8", - "K_F9", - "K_F10", - "K_F11", - "K_F12", - "K_F13", - "K_F14", - "K_F15", - - "K_NUMLOCK", - "K_CAPSLOCK", - "K_SCROLLOCK", - "K_RSHIFT", - "K_LSHIFT", - "K_RCTRL", - "K_LCTRL", - "K_RALT", - "K_LALT", - "K_RMETA", - "K_LMETA", - "K_LSUPER", - "K_RSUPER", - "K_MODE", - - "K_HELP", - "K_PRINT", - "K_SYSREQ", - "K_BREAK", - "K_MENU", - "K_POWER", - "K_EURO", - "K_LAST", - ], - } diff --git a/rsdl/rsdl/constants.pyc b/rsdl/rsdl/constants.pyc deleted file mode 100644 Binary file rsdl/rsdl/constants.pyc has changed diff --git a/rsdl/rsdl/eci.py b/rsdl/rsdl/eci.py deleted file mode 100644 --- a/rsdl/rsdl/eci.py +++ /dev/null @@ -1,53 +0,0 @@ -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rpython.translator.platform import CompilationError -import py -import sys -import os - -def get_rsdl_compilation_info(): - if sys.platform == 'darwin': - eci = ExternalCompilationInfo( - includes = ['SDL.h'], - include_dirs = ['/Library/Frameworks/SDL.framework/Headers'], - link_files = [ - str(py.path.local(__file__).dirpath().join('macosx-sdl-main/SDLMain.m')), - ], - frameworks = ['SDL', 'Cocoa'] - ) - elif sys.platform == "win32": - try: - sdl_prefix = os.path.abspath(os.environ["SDL_PREFIX"]) - except KeyError: - print "You need to provide the path to SDL using the SDL_PREFIX environment variable" - exit(1) - - # XXX: SDL_main.h does a #define main SDL_main - # This causes a linker error with the VS C compiler - # The solution is to #undef main before we define our own - this_dir = os.path.dirname(__file__) - f = open(os.path.join(this_dir, "RSDL_undef_main.h"), "w") - print >> f, "#undef main" - f.close() - - eci = ExternalCompilationInfo( - includes = ['SDL.h', 'RSDL_undef_main.h'], - include_dirs = [os.path.join(sdl_prefix, "include"), this_dir], - link_files = [ - os.path.join(sdl_prefix, "lib", "x86", "SDLmain.lib"), - os.path.join(sdl_prefix, "lib", "x86", "SDL.lib") - ], - libraries = ["SDL"], - library_dirs = [os.path.join(sdl_prefix, "lib", "x86")], - ) - else: - eci = ExternalCompilationInfo( - includes=['SDL.h'], - ) - eci = eci.merge(ExternalCompilationInfo.from_config_tool('sdl-config')) - return eci - -def check_sdl_installation(): - from pypy.rpython.tool import rffi_platform as platform - platform.verify_eci(get_rsdl_compilation_info()) - -SDLNotInstalled = (ImportError, CompilationError) diff --git a/rsdl/rsdl/eci.pyc b/rsdl/rsdl/eci.pyc deleted file mode 100644 Binary file rsdl/rsdl/eci.pyc has changed diff --git a/rsdl/rsdl/macosx-sdl-main/SDLMain.h b/rsdl/rsdl/macosx-sdl-main/SDLMain.h deleted file mode 100644 --- a/rsdl/rsdl/macosx-sdl-main/SDLMain.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import - - at interface SDLMain : NSObject - at end diff --git a/rsdl/rsdl/macosx-sdl-main/SDLMain.m b/rsdl/rsdl/macosx-sdl-main/SDLMain.m deleted file mode 100644 --- a/rsdl/rsdl/macosx-sdl-main/SDLMain.m +++ /dev/null @@ -1,384 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import "SDL.h" -#import "SDLMain.h" -#import /* for MAXPATHLEN */ -#import - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ - at interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; - at end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ - at interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; - at end -#endif - - at interface SDLApplication : NSApplication - at end - - at implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} - at end - -/* The main class of the application, the application's delegate */ - at implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { - assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } - -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} - at end - - - at implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - - at end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - diff --git a/rsdl/setup.py b/rsdl/setup.py deleted file mode 100644 --- a/rsdl/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -from distutils.core import setup - - -with open("README.txt") as f: - readme = f.read() - -setup( - name="rsdl", - description="A SDL library that works with RPython", - long_description=readme, - version="0.1", - author="PyPy contributors", - author_email="timfelgentreff+rsdl at gmail.com", - url="https://bitbucket.org/pypy/rsdl/", - packages=["rsdl"], - classifiers=[ - "Programming Language :: RPython", - ] -) diff --git a/rsdl/test/__init__.py b/rsdl/test/__init__.py deleted file mode 100644 diff --git a/rsdl/test/applause.wav b/rsdl/test/applause.wav deleted file mode 100644 Binary file rsdl/test/applause.wav has changed diff --git a/rsdl/test/conftest.py b/rsdl/test/conftest.py deleted file mode 100644 --- a/rsdl/test/conftest.py +++ /dev/null @@ -1,10 +0,0 @@ -from rsdl.eci import check_sdl_installation, SDLNotInstalled -import py - -def pytest_ignore_collect(path): - try: - check_sdl_installation() - except SDLNotInstalled, e: - return True - else: - return False diff --git a/rsdl/test/demo.jpg b/rsdl/test/demo.jpg deleted file mode 100644 Binary file rsdl/test/demo.jpg has changed diff --git a/rsdl/test/demo.png b/rsdl/test/demo.png deleted file mode 100644 Binary file rsdl/test/demo.png has changed diff --git a/rsdl/test/test_basic.py b/rsdl/test/test_basic.py deleted file mode 100644 --- a/rsdl/test/test_basic.py +++ /dev/null @@ -1,37 +0,0 @@ -import py -from rsdl import RSDL -from rpython.rlib.rarithmetic import r_uint -from rpython.rtyper.lltypesystem import rffi - - -def test_sdl_init(): - assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 - RSDL.Quit() - -def test_surface_basic(): - assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 - surface = RSDL.CreateRGBSurface(0, 150, 50, 32, - r_uint(0x000000FF), - r_uint(0x0000FF00), - r_uint(0x00FF0000), - r_uint(0xFF000000)) - assert surface - assert rffi.getintfield(surface, 'c_w') == 150 - assert rffi.getintfield(surface, 'c_h') == 50 - RSDL.FreeSurface(surface) - RSDL.Quit() - - -def test_get_keyname(): - assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 - assert RSDL.GetKeyName(RSDL.K_PLUS)[0] == '+' - assert RSDL.GetKeyName(RSDL.K_RIGHTPAREN)[0] == ')' - assert RSDL.GetKeyName(RSDL.K_z)[0] == 'z' - -def test_delay_getticks(): - assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 - RSDL.Delay(10) - i = RSDL.GetTicks() - assert i >= 10 - RSDL.Quit() - diff --git a/rsdl/test/test_sdl_image.py b/rsdl/test/test_sdl_image.py deleted file mode 100644 --- a/rsdl/test/test_sdl_image.py +++ /dev/null @@ -1,50 +0,0 @@ -import py, os -from rsdl import RSDL, RIMG, RSDL_helper, test -from rpython.rtyper.lltypesystem import lltype, rffi -this_dir = test.__path__[0] - - -def test_load_image(): - for filename in ["demo.jpg", "demo.png"]: - image = RIMG.Load(os.path.join(this_dir, filename)) - assert image - assert rffi.getintfield(image, 'c_w') == 17 - assert rffi.getintfield(image, 'c_h') == 23 - RSDL.FreeSurface(image) - -def test_image_pixels(): - for filename in ["demo.jpg", "demo.png"]: - image = RIMG.Load(os.path.join(this_dir, filename)) - assert image - assert rffi.getintfield(image.c_format, 'c_BytesPerPixel') in (3, 4) - RSDL.LockSurface(image) - result = {} - try: - rgb = lltype.malloc(rffi.CArray(RSDL.Uint8), 3, flavor='raw') - try: - for y in range(23): - for x in range(y % 13, 17, 13): - color = RSDL_helper.get_pixel(image, x, y) - RSDL.GetRGB(color, - image.c_format, - rffi.ptradd(rgb, 0), - rffi.ptradd(rgb, 1), - rffi.ptradd(rgb, 2)) - r = rffi.cast(lltype.Signed, rgb[0]) - g = rffi.cast(lltype.Signed, rgb[1]) - b = rffi.cast(lltype.Signed, rgb[2]) - result[x, y] = r, g, b - finally: - lltype.free(rgb, flavor='raw') - finally: - RSDL.UnlockSurface(image) - RSDL.FreeSurface(image) - for x, y in result: - f = (x*17 + y*23) / float(17*17+23*23) - expected_r = int(255.0 * (1.0-f)) - expected_g = 0 - expected_b = int(255.0 * f) - r, g, b = result[x, y] - assert abs(r-expected_r) < 10 - assert abs(g-expected_g) < 10 - assert abs(b-expected_b) < 10 diff --git a/rsdl/test/test_sdl_mixer.py b/rsdl/test/test_sdl_mixer.py deleted file mode 100644 --- a/rsdl/test/test_sdl_mixer.py +++ /dev/null @@ -1,32 +0,0 @@ -import py -import os -import time -from rsdl import RSDL, RMix, RSDL_helper -from rpython.rtyper.lltypesystem import lltype, rffi - -def test_open_mixer(): - if RMix.OpenAudio(22050, RSDL.AUDIO_S16LSB, 2, 1024) != 0: - error = rffi.charp2str(RSDL.GetError()) - raise Exception(error) - RMix.CloseAudio() - -def test_load_wav(): - if RMix.OpenAudio(22050, RSDL.AUDIO_S16LSB, 2, 1024) != 0: - error = rffi.charp2str(RSDL.GetError()) - raise Exception(error) - filename = rffi.str2charp('applause.wav') - RMix.LoadWAV(filename) - rffi.free_charp(filename) - RMix.CloseAudio() - -def test_play_wav(): - if RMix.OpenAudio(22050, RSDL.AUDIO_S16LSB, 2, 1024) != 0: - error = rffi.charp2str(RSDL.GetError()) - raise Exception(error) - filename = rffi.str2charp('applause.wav') - applause = RMix.LoadWAV(filename) - rffi.free_charp(filename) - RMix.PlayChannel(-1, applause, -1) - time.sleep(1) - RMix.CloseAudio() - diff --git a/rsdl/test/test_surface.py b/rsdl/test/test_surface.py deleted file mode 100644 --- a/rsdl/test/test_surface.py +++ /dev/null @@ -1,75 +0,0 @@ -import py, sys -from rsdl import RSDL, RSDL_helper -from rpython.rlib.rarithmetic import r_uint -from rpython.rtyper.lltypesystem import lltype, rffi - -class TestSurface: - - def setup_method(self, meth): - self.dst_surf = RSDL.CreateRGBSurface(0, 300, 300, 32, - r_uint(0x000000FF), - r_uint(0x0000FF00), - r_uint(0x00FF0000), - r_uint(0x00000000)) - self.src_surf = RSDL.CreateRGBSurface(0, 50, 50, 32, - r_uint(0x000000FF), - r_uint(0x0000FF00), - r_uint(0x00FF0000), - r_uint(0x00000000)) - fmt = self.src_surf.c_format - self.black = RSDL.MapRGB(fmt, 0, 0, 0) - self.red = RSDL.MapRGB(fmt, 255, 0, 0) - self.blue = RSDL.MapRGB(fmt, 0, 0, 255) - RSDL.FillRect(self.src_surf, lltype.nullptr(RSDL.Rect), self.red) - - def test_simple(self): - pass # only checks that creating the surfaces works - - def test_set_alpha(self): - # prepare - assert RSDL.SetAlpha(self.src_surf, RSDL.SRCALPHA, 128) == 0 - - # draw - RSDL_helper.blit_complete_surface( - self.src_surf, - self.dst_surf, - 10, 10) - RSDL_helper.blit_complete_surface( - self.src_surf, - self.dst_surf, - 20, 20) - - # check - for position, color in ( - (( 0, 0), ( 0,0,0)), # no rect - ((10,10), (127,0,0)), # one rect - ((20,20), (191,0,0)) # two overlapping rects - ): - fetched_color = RSDL_helper.get_pixel(self.dst_surf, position[0], position[1]) - assert RSDL_helper.get_rgb(fetched_color, self.dst_surf.c_format) == color - - def test_set_color_key(self): - # prepare - fillrect = RSDL_helper.mallocrect(10, 10, 30, 30) - RSDL.FillRect(self.src_surf, fillrect, self.blue) - lltype.free(fillrect, flavor='raw') - assert RSDL.SetColorKey(self.src_surf, RSDL.SRCCOLORKEY, self.blue) == 0 - - # draw - RSDL_helper.blit_complete_surface(self.src_surf, self.dst_surf, 0, 0) - - # check - for position, color in ( - (( 0, 0), self.red), - ((10,10), self.black), - ((20,20), self.black), - ((40,40), self.red) - ): - fetched_color = RSDL_helper.get_pixel(self.dst_surf, position[0], position[1]) - assert fetched_color == color - - def teardown_method(self, meth): - RSDL.FreeSurface(self.src_surf) - RSDL.FreeSurface(self.dst_surf) - RSDL.Quit() - diff --git a/rsdl/test/test_video.py b/rsdl/test/test_video.py deleted file mode 100644 --- a/rsdl/test/test_video.py +++ /dev/null @@ -1,270 +0,0 @@ - -import py, sys -from rsdl import RSDL, RSDL_helper -from rpython.rlib.rarithmetic import r_uint -from rpython.rtyper.lltypesystem import lltype, rffi - -# -# This test file is skipped unless run with "py.test --view". -# If it is run as "py.test --view -s", then it interactively asks -# for confirmation that the window looks as expected. -# XXX always run for now. -# - - -class TestVideo: - - def setup_method(self, meth): - #if not conftest.option.view: - # py.test.skip("'--view' not specified, " - # "skipping tests that open a window") - assert RSDL.Init(RSDL.INIT_VIDEO) >= 0 - self.screen = RSDL.SetVideoMode(640, 480, 32, 0) - assert self.screen - self.is_interactive = sys.stdout.isatty() - - def check(self, msg): - if self.is_interactive: - print - answer = raw_input('Interactive test: %s - ok? [Y] ' % msg) - if answer and not answer.upper().startswith('Y'): - py.test.fail(msg) - else: - print msg - - def test_simple(self): - pass # only checks that opening and closing the window works - - def test_fillrect_full(self): - fmt = self.screen.c_format - for colorname, r, g, b in [('dark red', 128, 0, 0), - ('yellow', 255, 255, 0), - ('blue', 0, 0, 255)]: - color = RSDL.MapRGB(fmt, r, g, b) - RSDL.FillRect(self.screen, lltype.nullptr(RSDL.Rect), color) - RSDL.Flip(self.screen) - self.check("Screen filled with %s" % colorname) - - def test_caption(self): - RSDL.WM_SetCaption("Hello World!", "Hello World!") - self.check('The window caption is "Hello World!"') - - def test_keypresses(self): - if not self.is_interactive: - py.test.skip("interactive test only") - RSDL.EnableUNICODE(1) - print - print "Keys pressed in the Pygame window should be printed below." - print " Use Escape to quit." - event = lltype.malloc(RSDL.Event, flavor='raw') - try: - while True: - ok = RSDL.WaitEvent(event) - assert rffi.cast(lltype.Signed, ok) == 1 - c_type = rffi.getintfield(event, 'c_type') - if c_type == RSDL.KEYDOWN: - p = rffi.cast(RSDL.KeyboardEventPtr, event) - if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: - print 'Escape key' - break - char = rffi.getintfield(p.c_keysym, 'c_unicode') - if char != 0: - print 'Key:', unichr(char).encode('utf-8') - else: - print 'Some special key' - else: - print '(event of type %d)' % c_type - finally: - lltype.free(event, flavor='raw') - - def test_poll(self): - if not self.is_interactive: - py.test.skip("interactive test only") - import time, sys - RSDL.EnableUNICODE(1) - print - print "Keys pressed in the Pygame window give a dot." - print " Wait 3 seconds to quit." - timeout = time.time() + 3 - event = lltype.malloc(RSDL.Event, flavor='raw') - try: - while True: - # busy polling - ok = RSDL.PollEvent(event) - ok = rffi.cast(lltype.Signed, ok) - assert ok >= 0 - if ok > 0: - c_type = rffi.getintfield(event, 'c_type') - if c_type == RSDL.KEYDOWN: - sys.stderr.write('.') - p = rffi.cast(RSDL.KeyboardEventPtr, event) - if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: - print 'Escape key' - break - timeout = time.time() + 3 - else: - if time.time() > timeout: - break - time.sleep(0.05) - finally: - lltype.free(event, flavor='raw') - - def test_mousemove(self): - if not self.is_interactive: - py.test.skip("interactive test only") - print - print "Move the Mouse up and down:" - print " Use Escape to quit." - event = lltype.malloc(RSDL.Event, flavor="raw") - directions = [False]*4 - try: - while True: - ok = RSDL.WaitEvent(event) - assert rffi.cast(lltype.Signed, ok) == 1 - c_type = rffi.getintfield(event, "c_type") - if c_type == RSDL.MOUSEMOTION: - m = rffi.cast(RSDL.MouseMotionEventPtr, event) - assert rffi.getintfield(m, "c_x") >= 0 - assert rffi.getintfield(m, "c_y") >= 0 - print rffi.getintfield(m, "c_xrel") - directions[0] |= rffi.getintfield(m, "c_xrel")>0 - directions[1] |= rffi.getintfield(m, "c_xrel")<0 - directions[2] |= rffi.getintfield(m, "c_yrel")>0 - directions[3] |= rffi.getintfield(m, "c_yrel")<0 - if False not in directions: - break - elif c_type == RSDL.KEYUP: - p = rffi.cast(RSDL.KeyboardEventPtr, event) - if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: - print " test manually aborted" - py.test.fail(" mousemovement test aborted") - break - finally: - lltype.free(event, flavor='raw') - - - def test_mousebutton_wheel(self): - if not self.is_interactive: - py.test.skip("interactive test only") - print - print "Press the given MouseButtons:" - print " Use Escape to pass tests." - - event_tests = [("left button", RSDL.BUTTON_LEFT), - ("middle button", RSDL.BUTTON_MIDDLE), - ("right button", RSDL.BUTTON_RIGHT), - ("scroll up", RSDL.BUTTON_WHEELUP), - ("scroll down", RSDL.BUTTON_WHEELDOWN)] - test_success = [] - event = lltype.malloc(RSDL.Event, flavor='raw') - try: - for button_test in event_tests: - print " press %s:" % button_test[0] - while True: - ok = RSDL.WaitEvent(event) - assert rffi.cast(lltype.Signed, ok) == 1 - c_type = rffi.getintfield(event, 'c_type') - if c_type == RSDL.MOUSEBUTTONDOWN: - pass - elif c_type == RSDL.MOUSEBUTTONUP: - b = rffi.cast(RSDL.MouseButtonEventPtr, event) - if rffi.getintfield(b, 'c_button') == button_test[1]: - test_success.append(True) - break - elif c_type == RSDL.KEYUP: - p = rffi.cast(RSDL.KeyboardEventPtr, event) - if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: - test_success.append(False) - print " manually aborted" - break - #break - if False in test_success: - py.test.fail("") - finally: - lltype.free(event, flavor='raw') - - - def test_show_hide_cursor(self): - RSDL.ShowCursor(RSDL.DISABLE) - self.check("Is the cursor hidden? ") - RSDL.ShowCursor(RSDL.ENABLE) - self.check("Is the cursor shown? ") - - def test_bit_pattern(self): - HEIGHT = WIDTH = 10 - fmt = self.screen.c_format - white = RSDL.MapRGB(fmt, 255, 255, 255) - black = RSDL.MapRGB(fmt, 0, 0, 0) - RSDL.LockSurface(self.screen) - for i in xrange(WIDTH): - for j in xrange(HEIGHT): - k = j*WIDTH + i - if k % 2: - c = white - else: - c = black - RSDL_helper.set_pixel(self.screen, i, j, c) - RSDL.UnlockSurface(self.screen) - RSDL.Flip(self.screen) - self.check("Upper left corner 10x10 field with vertical black/white stripes") - - def test_blit_rect(self): - surface = RSDL.CreateRGBSurface(0, 150, 50, 32, - r_uint(0x000000FF), - r_uint(0x0000FF00), - r_uint(0x00FF0000), - r_uint(0xFF000000)) - fmt = surface.c_format - color = RSDL.MapRGB(fmt, 255, 0, 0) - RSDL.FillRect(surface, lltype.nullptr(RSDL.Rect), color) - - paintrect = RSDL_helper.mallocrect(75, 0, 150, 50) - dstrect = lltype.malloc(RSDL.Rect, flavor='raw') - try: - color = RSDL.MapRGB(fmt, 255, 128, 0) - RSDL.FillRect(surface, paintrect, color) - - rffi.setintfield(dstrect, 'c_x', 10) - rffi.setintfield(dstrect, 'c_y', 10) - rffi.setintfield(dstrect, 'c_w', 150) - rffi.setintfield(dstrect, 'c_h', 50) - RSDL.BlitSurface(surface, lltype.nullptr(RSDL.Rect), self.screen, dstrect) - RSDL.Flip(self.screen) - finally: - lltype.free(dstrect, flavor='raw') - lltype.free(paintrect, flavor='raw') - RSDL.FreeSurface(surface) - self.check("Half Red/Orange rectangle(150px * 50px) at the top left, 10 pixels from the border") - - - def test_blit_pxrect(self): - max = 150 * 50 - surfacepx = lltype.malloc(rffi.VOIDP.TO, max * 4, flavor='raw') - pos = 0 - for i in xrange(max): - surfacepx[pos] = chr(int(float(i) / max * 255)) - surfacepx[pos + 1] = chr(int(float(i) / max * 255)) - surfacepx[pos + 2] = chr(int(float(i) / max * 255)) - surfacepx[pos + 3] = chr(255) - pos += 4 - - pitch = 4 * 150 # 4 byte per line * width - surface = RSDL.CreateRGBSurfaceFrom(surfacepx, 150, 50, 32, pitch, - r_uint(0x000000FF), - r_uint(0x0000FF00), - r_uint(0x00FF0000), - r_uint(0xFF000000)) - - dstrect = RSDL_helper.mallocrect(0, 0, 150, 50) - try: - RSDL.BlitSurface(surface, lltype.nullptr(RSDL.Rect), self.screen, dstrect) - RSDL.Flip(self.screen) - finally: - lltype.free(dstrect, flavor='raw') - RSDL.FreeSurface(surface) - lltype.free(surfacepx, flavor='raw') - self.check("Gradient from black to white rectangle(150px * 50px) at the top left") - - def teardown_method(self, meth): - RSDL.Quit() - From noreply at buildbot.pypy.org Thu Mar 21 18:23:34 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Thu, 21 Mar 2013 18:23:34 +0100 (CET) Subject: [pypy-commit] pypy numpy-pickle: Add a failing test for record dtypes Message-ID: <20130321172334.6A5131C10C2@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: numpy-pickle Changeset: r62610:b13ea8b17e8b Date: 2013-03-21 18:23 +0100 http://bitbucket.org/pypy/pypy/changeset/b13ea8b17e8b/ Log: Add a failing test for record dtypes 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 @@ -275,7 +275,13 @@ from cPickle import loads, dumps a = array([1,2,3]) assert a.dtype.__reduce__() == (dtype, ('i8', 0, 1), (3, '<', None, None, None, -1, -1, 0)) - import pdb; pdb.set_trace() + assert loads(dumps(a.dtype)) == a.dtype + + def test_pickle_record(self): + from numpypy import array, dtype + from cPickle import loads, dumps + skip("TODO") + a = array(([0, 0], [0, 0]), dtype=[('x', ' Author: Brian Kearns Branch: Changeset: r62612:9cb237badb3b Date: 2013-03-21 07:03 -0400 http://bitbucket.org/pypy/pypy/changeset/9cb237badb3b/ Log: small tweaks for RStringIO diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -120,7 +120,7 @@ if p == 0 and n < 0: self.pos = AT_END return self.getvalue() # reading everything - if p == AT_END: + if p == AT_END or n == 0: return '' assert p >= 0 self.copy_into_bigbuffer() @@ -138,12 +138,14 @@ return ''.join(self.bigbuffer[p:p+count]) def readline(self, size=-1): - p = self.tell() + p = self.pos + if p == AT_END or size == 0: + return '' + assert p >= 0 self.copy_into_bigbuffer() end = len(self.bigbuffer) if size >= 0 and size < end - p: end = p + size - assert p >= 0 i = p while i < end: finished = self.bigbuffer[i] == '\n' From noreply at buildbot.pypy.org Thu Mar 21 20:18:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 20:18:21 +0100 (CET) Subject: [pypy-commit] pypy default: also lazily construct bigbuffer object in RStringIO Message-ID: <20130321191821.C475E1C10C2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62611:2922803f28f3 Date: 2013-03-21 06:45 -0400 http://bitbucket.org/pypy/pypy/changeset/2922803f28f3/ Log: also lazily construct bigbuffer object in RStringIO diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -15,21 +15,23 @@ # * the list of characters self.bigbuffer; # * each of the strings in self.strings. # + self.closed = False self.strings = None - self.bigbuffer = [] + self.bigbuffer = None self.pos = AT_END def close(self): + self.closed = True self.strings = None self.bigbuffer = None def is_closed(self): - return self.bigbuffer is None + return self.closed def getvalue(self): """If self.strings contains more than 1 string, join all the strings together. Return the final single string.""" - if len(self.bigbuffer): + if self.bigbuffer is not None: self.copy_into_bigbuffer() return ''.join(self.bigbuffer) if self.strings is not None: @@ -37,13 +39,17 @@ return '' def getsize(self): - result = len(self.bigbuffer) + result = 0 + if self.bigbuffer is not None: + result += len(self.bigbuffer) if self.strings is not None: result += self.strings.getlength() return result def copy_into_bigbuffer(self): """Copy all the data into the list of characters self.bigbuffer.""" + if self.bigbuffer is None: + self.bigbuffer = [] if self.strings is not None: self.bigbuffer += self.strings.build() self.strings = None @@ -56,7 +62,7 @@ if p != AT_END: # slow or semi-fast paths assert p >= 0 endp = p + len(buffer) - if len(self.bigbuffer) >= endp: + if self.bigbuffer is not None and len(self.bigbuffer) >= endp: # semi-fast path: the write is entirely inside self.bigbuffer for i in range(len(buffer)): self.bigbuffer[p + i] = buffer[i] @@ -152,7 +158,7 @@ # than CPython: it never grows the buffer, and it sets the current # position to the end. assert size >= 0 - if size > len(self.bigbuffer): + if self.bigbuffer is None or size > len(self.bigbuffer): self.copy_into_bigbuffer() else: # we can drop all extra strings @@ -160,4 +166,6 @@ self.strings = None if size < len(self.bigbuffer): del self.bigbuffer[size:] + if len(self.bigbuffer) == 0: + self.bigbuffer = None self.pos = AT_END From noreply at buildbot.pypy.org Thu Mar 21 20:18:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 20:18:24 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130321191824.53F941C10C2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62613:b1a1549418d9 Date: 2013-03-21 15:05 -0400 http://bitbucket.org/pypy/pypy/changeset/b1a1549418d9/ Log: merge heads diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -242,7 +242,7 @@ # mc = ARMv7Builder() # save argument registers and return address - mc.PUSH([reg.value for reg in r.argument_regs] + [r.lr.value]) + mc.PUSH([reg.value for reg in r.argument_regs] + [r.ip.value, r.lr.value]) # stack is aligned here # Pass current stack pointer as argument to the call mc.MOV_rr(r.r0.value, r.sp.value) @@ -253,21 +253,13 @@ mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) mc.LDR_ri(r.r0.value, r.r0.value) mc.TST_rr(r.r0.value, r.r0.value) + # # restore registers and return # We check for c.EQ here, meaning all bits zero in this case - mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value], cond=c.EQ) - # - # Call the helper, which will return a dead frame object with - # the correct exception set, or MemoryError by default - addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception()) - mc.BL(addr) - # - # footer -- note the ADD, which skips the return address of this - # function, and will instead return to the caller's caller. Note - # also that we completely ignore the saved arguments, because we - # are interrupting the function. - mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 1) * WORD) - mc.POP([r.pc.value]) + mc.POP([reg.value for reg in r.argument_regs] + [r.ip.value, r.pc.value], cond=c.EQ) + # restore sp + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.B(self.propagate_exception_path) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart @@ -311,6 +303,8 @@ else: self._restore_exception(mc, exc0, exc1) mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + assert exc0 is not None + assert exc1 is not None mc.POP([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) # @@ -505,7 +499,7 @@ if self.cpu.supports_floats: mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond) - # push all callee saved registers and IP to keep the alignment + # pop all callee saved registers and IP to keep the alignment mc.POP([reg.value for reg in r.callee_restored_registers] + [r.ip.value], cond=cond) mc.BKPT() @@ -564,11 +558,11 @@ self.gen_func_prolog() def _call_header_with_stack_check(self): + self._call_header() if self.stack_check_slowpath == 0: pass # no stack check (e.g. not translated) else: endaddr, lengthaddr, _ = self.cpu.insert_stack_check() - self.mc.PUSH([r.lr.value]) # load stack end self.mc.gen_load_int(r.ip.value, endaddr) # load ip, [end] self.mc.LDR_ri(r.ip.value, r.ip.value) # LDR ip, ip @@ -580,9 +574,6 @@ # if ofs self.mc.CMP_rr(r.ip.value, r.lr.value) # CMP ip, lr self.mc.BL(self.stack_check_slowpath, c=c.HI) # call if ip > lr - # - self.mc.POP([r.lr.value]) - self._call_header() # cpu interface def assemble_loop(self, loopname, inputargs, operations, looptoken, log): diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -4,12 +4,23 @@ from rpython.rtyper.lltypesystem import lltype from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.backend.arm.codebuilder import ARMv7Builder +from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests skip_unless_run_slow_tests() class TestARMCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py + def make_function_returning_stack_pointer(self): + mc = ARMv7Builder() + mc.MOV_rr(r.r0.value, r.sp.value) + mc.MOV_rr(r.pc.value, r.lr.value) + return mc.materialize(self.cpu.asmmemmgr, []) + + def get_alignment_requirements(self): + return 8 + def test_call_argument_spilling(self): # bug when we have a value in r0, that is overwritten by an argument # and needed after the call, so that the register gets spilled after it @@ -28,12 +39,24 @@ ops = """ [%s] i99 = call(ConstClass(func_ptr), 22, descr=calldescr) - finish(%s, i99)""" % (args, args) + force_spill(i0) + force_spill(i1) + force_spill(i2) + force_spill(i3) + force_spill(i4) + force_spill(i5) + force_spill(i6) + force_spill(i7) + force_spill(i8) + force_spill(i9) + force_spill(i10) + guard_true(i0) [%s, i99] + finish()""" % (args, args) loop = parse(ops, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [x for x in range(11)] - self.cpu.execute_token(looptoken, *args) + deadframe = self.cpu.execute_token(looptoken, *args) for x in range(11): - assert self.cpu.get_latest_value_int(x) == x - assert self.cpu.get_latest_value_int(11) == 38 + assert self.cpu.get_int_value(deadframe, x) == x + assert self.cpu.get_int_value(deadframe, 11) == 38 diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -11,6 +11,7 @@ from rpython.jit.backend.test.runner_test import Runner import py import sys +import platform def boxfloat(x): return BoxFloat(longlong.getfloatstorage(x)) @@ -382,7 +383,8 @@ raise NotImplementedError def test_call_aligned_explicit_check(self): - if sys.maxint == 2 ** 31 - 1: + if (not platform.machine().startswith('arm') and + sys.maxint == 2 ** 31 - 1): # XXX is still necessary on x86? py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: From noreply at buildbot.pypy.org Thu Mar 21 20:45:13 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 21 Mar 2013 20:45:13 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed bitBlit primitive and test Message-ID: <20130321194513.BF94F1C14B7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r231:4398592999e8 Date: 2013-03-21 18:01 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4398592999e8/ Log: fixed bitBlit primitive and test fixed some problems with testing sequence diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -62,20 +62,18 @@ self._loop = True s_new_context = w_active_context.as_context_get_shadow(self.space) while True: + assert self.remaining_stack_depth == self.max_stack_depth s_sender = s_new_context.s_sender() try: s_new_context = self.c_loop(s_new_context) except StackOverflow, e: - self.remaining_stack_depth = self.max_stack_depth s_new_context = e.s_context except Return, nlr: while s_new_context is not nlr.s_target_context: s_new_context.mark_returned() s_new_context = s_sender - self.remaining_stack_depth = self.max_stack_depth s_new_context.push(nlr.value) except ProcessSwitch, p: - self.remaining_stack_depth = self.max_stack_depth s_new_context = p.s_new_context def c_loop(self, s_context): @@ -119,7 +117,7 @@ if not self._loop: return s_new_frame # this test is done to not loop in test, # but rather step just once where wanted - if self.remaining_stack_depth == 1: + if self.remaining_stack_depth <= 1: raise StackOverflow(s_new_frame) self.remaining_stack_depth -= 1 diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -557,11 +557,13 @@ if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15: raise PrimitiveFailedError - interp.perform(w_rcvr, "simulateCopyBits") + space = interp.space + s_frame.push(w_rcvr) + s_frame._sendSelfSelector(interp.image.w_simulateCopyBits, 0, interp) - w_dest_form = w_rcvr.fetch(interp.space, 0) - if w_dest_form.is_same_object(interp.space.objtable['w_display']): - w_bitmap = w_dest_form.fetch(interp.space, 0) + w_dest_form = w_rcvr.fetch(space, 0) + if w_dest_form.is_same_object(space.objtable['w_display']): + w_bitmap = w_dest_form.fetch(space, 0) assert isinstance(w_bitmap, model.W_DisplayBitmap) w_bitmap.flush_to_screen() diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -369,9 +369,10 @@ for name, idx in constants.objects_in_special_object_table.items(): space.objtable["w_" + name] = self.special_objects[idx] - self.w_asSymbol = self.find_asSymbol(space, reader) + self.w_asSymbol = self.find_symbol(space, reader, "asSymbol") + self.w_simulateCopyBits = self.find_symbol(space, reader, "simulateCopyBits") - def find_asSymbol(self, space, reader): + def find_symbol(self, space, reader, symbol): w_dnu = self.special(constants.SO_DOES_NOT_UNDERSTAND) assert isinstance(w_dnu, model.W_BytesObject) assert w_dnu.as_string() == "doesNotUnderstand:" @@ -384,7 +385,7 @@ continue if not w_obj.getclass(space).is_same_object(w_Symbol): continue - if w_obj.as_string() == "asSymbol": + if w_obj.as_string() == symbol: break assert w_obj is not None return w_obj diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -314,26 +314,6 @@ size = prim(primitives.PERFORM_WITH_ARGS, [w_o, w_sel, []]) assert size.value == 3 -def test_step_run_something(): - from spyvm.test import test_miniimage - setup_module(test_miniimage, filename='running-something-mini.image') - from spyvm import wrapper - ap = wrapper.ProcessWrapper(space, wrapper.scheduler(space).active_process()) - w_ctx = ap.suspended_context() - s_ctx = w_ctx.as_context_get_shadow(space) - ap.store_suspended_context(space.w_nil) - - interp = interpreter.Interpreter(space) - assert isinstance(s_ctx, shadow.MethodContextShadow) - assert s_ctx.top().is_same_object(space.w_true) - interp.step(s_ctx) - interp.step(s_ctx) - assert s_ctx.top().value == 1 - interp.step(s_ctx) - assert s_ctx.top().value == 2 - interp.step(s_ctx) - assert s_ctx.top().value == 3 - def test_create_new_symbol(): w_result = perform(w("someString"), "asSymbol") assert w_result is not None @@ -404,3 +384,23 @@ assert s_message_cls.getname() == "Message class" w_message = s_message_cls.new() assert isinstance(w_message, model.W_PointersObject) + +def test_step_run_something(): + from spyvm.test import test_miniimage + setup_module(test_miniimage, filename='running-something-mini.image') + from spyvm import wrapper + ap = wrapper.ProcessWrapper(space, wrapper.scheduler(space).active_process()) + w_ctx = ap.suspended_context() + s_ctx = w_ctx.as_context_get_shadow(space) + ap.store_suspended_context(space.w_nil) + + interp = interpreter.Interpreter(space) + assert isinstance(s_ctx, shadow.MethodContextShadow) + assert s_ctx.top().is_same_object(space.w_true) + interp.step(s_ctx) + interp.step(s_ctx) + assert s_ctx.top().value == 1 + interp.step(s_ctx) + assert s_ctx.top().value == 2 + interp.step(s_ctx) + assert s_ctx.top().value == 3 \ No newline at end of file diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -688,21 +688,29 @@ def test_bitblt_copy_bits(monkeypatch): class CallCopyBitsSimulation(Exception): pass + class Image(): + def __init__(self): + self.w_simulateCopyBits = "simulateCopyBits" mock_bitblt = model.W_PointersObject(space.w_Point, 15) - def perform_mock(w_rcvr, string): - if w_rcvr is mock_bitblt and string == "simulateCopyBits": + def perform_mock(w_selector, argcount, interp): + if w_selector == "simulateCopyBits" or w_selector.as_string() == "simulateCopyBits": + assert argcount == 0 raise CallCopyBitsSimulation interp, w_frame, argument_count = mock([mock_bitblt], None) + if interp.image is None: + interp.image = Image() try: - monkeypatch.setattr(interp, "perform", perform_mock) + monkeypatch.setattr(w_frame._shadow, "_sendSelfSelector", perform_mock) with py.test.raises(CallCopyBitsSimulation): prim_table[primitives.BITBLT_COPY_BITS](interp, w_frame.as_context_get_shadow(space), argument_count-1) finally: monkeypatch.undo() + assert w_frame._shadow.pop() is mock_bitblt # the new receiver + assert w_frame._shadow.pop() is mock_bitblt # previous state is still there # Note: # primitives.NEXT is unimplemented as it is a performance optimization From noreply at buildbot.pypy.org Thu Mar 21 21:22:56 2013 From: noreply at buildbot.pypy.org (chrish42) Date: Thu, 21 Mar 2013 21:22:56 +0100 (CET) Subject: [pypy-commit] pypy default: Fix gethostbyaddr() test on some versions of MacOSX. Message-ID: <20130321202256.DC17E1C0171@cobra.cs.uni-duesseldorf.de> Author: Christian Hudon Branch: Changeset: r62614:efd767a61b59 Date: 2013-03-19 14:11 -0700 http://bitbucket.org/pypy/pypy/changeset/efd767a61b59/ Log: Fix gethostbyaddr() test on some versions of MacOSX. diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -35,13 +35,15 @@ def test_gethostbyaddr(): host = "localhost" expected = socket.gethostbyaddr(host) - expecteds = (expected, expected[:2]+(['0.0.0.0'],)) + # On some versions of MacOSX, we get two '0.0.0.0' entries in the addresslist. + expecteds = (expected, expected[:2] + (['0.0.0.0'], ), expected[:2] + (['0.0.0.0']*2, )) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) in expecteds host = "127.0.0.1" expected = socket.gethostbyaddr(host) - expecteds = (expected, expected[:2]+(['0.0.0.0'],)) + # On some versions of MacOSX, we get two '0.0.0.0' entries in the addresslist. + expecteds = (expected, expected[:2] + (['0.0.0.0'], ), expected[:2] + (['0.0.0.0']*2, )) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) in expecteds From noreply at buildbot.pypy.org Thu Mar 21 21:22:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Mar 2013 21:22:58 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in chrish42/pypy (pull request #139) Message-ID: <20130321202258.3B4FE1C0171@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62615:93bc1578182f Date: 2013-03-21 13:22 -0700 http://bitbucket.org/pypy/pypy/changeset/93bc1578182f/ Log: Merged in chrish42/pypy (pull request #139) Fix gethostbyaddr() test on some versions of MacOSX. diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -35,13 +35,15 @@ def test_gethostbyaddr(): host = "localhost" expected = socket.gethostbyaddr(host) - expecteds = (expected, expected[:2]+(['0.0.0.0'],)) + # On some versions of MacOSX, we get two '0.0.0.0' entries in the addresslist. + expecteds = (expected, expected[:2] + (['0.0.0.0'], ), expected[:2] + (['0.0.0.0']*2, )) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) in expecteds host = "127.0.0.1" expected = socket.gethostbyaddr(host) - expecteds = (expected, expected[:2]+(['0.0.0.0'],)) + # On some versions of MacOSX, we get two '0.0.0.0' entries in the addresslist. + expecteds = (expected, expected[:2] + (['0.0.0.0'], ), expected[:2] + (['0.0.0.0']*2, )) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) in expecteds From noreply at buildbot.pypy.org Thu Mar 21 22:03:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 22:03:22 +0100 (CET) Subject: [pypy-commit] pypy default: remove this random/unexplained loosening of test, it represents bogus behavior Message-ID: <20130321210322.7C6191C0DC9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62616:95f16920996f Date: 2013-03-21 17:02 -0400 http://bitbucket.org/pypy/pypy/changeset/95f16920996f/ Log: remove this random/unexplained loosening of test, it represents bogus behavior diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -35,18 +35,14 @@ def test_gethostbyaddr(): host = "localhost" expected = socket.gethostbyaddr(host) - # On some versions of MacOSX, we get two '0.0.0.0' entries in the addresslist. - expecteds = (expected, expected[:2] + (['0.0.0.0'], ), expected[:2] + (['0.0.0.0']*2, )) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) in expecteds + assert space.unwrap(ip) == socket.gethostbyaddr(host) + host = "127.0.0.1" - expected = socket.gethostbyaddr(host) - # On some versions of MacOSX, we get two '0.0.0.0' entries in the addresslist. - expecteds = (expected, expected[:2] + (['0.0.0.0'], ), expected[:2] + (['0.0.0.0']*2, )) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) in expecteds + assert space.unwrap(ip) == socket.gethostbyaddr(host) def test_getservbyname(): name = "smtp" From noreply at buildbot.pypy.org Thu Mar 21 22:47:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 21 Mar 2013 22:47:26 +0100 (CET) Subject: [pypy-commit] pypy default: further improve socket.gethostby{name, addr} tests Message-ID: <20130321214726.C6C961C04AB@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62617:1247527d5553 Date: 2013-03-21 17:39 -0400 http://bitbucket.org/pypy/pypy/changeset/1247527d5553/ Log: further improve socket.gethostby{name,addr} tests diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -20,29 +20,22 @@ assert space.unwrap(host) == socket.gethostname() def test_gethostbyname(): - host = "localhost" - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyname(host)") - assert space.unwrap(ip) == socket.gethostbyname(host) + for host in ["localhost", "127.0.0.1"]: + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyname(host)") + assert space.unwrap(ip) == socket.gethostbyname(host) def test_gethostbyname_ex(): - host = "localhost" - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyname_ex(host)") - assert isinstance(space.unwrap(ip), tuple) - assert space.unwrap(ip) == socket.gethostbyname_ex(host) + for host in ["localhost", "127.0.0.1"]: + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyname_ex(host)") + assert space.unwrap(ip) == socket.gethostbyname_ex(host) def test_gethostbyaddr(): - host = "localhost" - expected = socket.gethostbyaddr(host) - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) - - host = "127.0.0.1" - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + for host in ["localhost", "127.0.0.1"]: + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + assert space.unwrap(ip) == socket.gethostbyaddr(host) def test_getservbyname(): name = "smtp" diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -40,55 +40,49 @@ a = NETLINKAddress(pid, group_mask) assert a.get_pid() == pid assert a.get_groups() == group_mask - + def test_gethostname(): s = gethostname() assert isinstance(s, str) def test_gethostbyname(): - a = gethostbyname('localhost') - assert isinstance(a, INETAddress) - assert a.get_host() == "127.0.0.1" + for host in ["localhost", "127.0.0.1"]: + a = gethostbyname(host) + assert isinstance(a, INETAddress) + assert a.get_host() == "127.0.0.1" def test_gethostbyname_ex(): - name, aliases, address_list = gethostbyname_ex('localhost') - allnames = [name] + aliases - for n in allnames: - assert isinstance(n, str) - if sys.platform != 'win32': - assert 'localhost' in allnames - for a in address_list: - if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": - break # ok - else: - py.test.fail("could not find the 127.0.0.1 IPv4 address in %r" - % (address_list,)) + for host in ["localhost", "127.0.0.1"]: + name, aliases, address_list = gethostbyname_ex(host) + allnames = [name] + aliases + for n in allnames: + assert isinstance(n, str) + if sys.platform != 'win32': + assert host in allnames + for a in address_list: + if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": + break # ok + # no IPV6, should always return IPV4 + else: + py.test.fail("could not find the localhost address in %r" + % (address_list,)) def test_gethostbyaddr(): - name, aliases, address_list = gethostbyaddr('127.0.0.1') - allnames = [name] + aliases - for n in allnames: - assert isinstance(n, str) - if sys.platform != 'win32': - assert 'localhost' in allnames - for a in address_list: - if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": - break # ok - else: - py.test.fail("could not find the 127.0.0.1 IPv4 address in %r" - % (address_list,)) - - name, aliases, address_list = gethostbyaddr('localhost') + for host in ["localhost", "127.0.0.1"]: + name, aliases, address_list = gethostbyaddr(host) allnames = [name] + aliases for n in allnames: assert isinstance(n, str) if sys.platform != 'win32': assert 'localhost' in allnames for a in address_list: - if isinstance(a, INET6Address) and a.get_host() == "::1": + if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": break # ok + if host == 'localhost': # name lookup might return IPV6 + if isinstance(a, INET6Address) and a.get_host() == "::1": + break # ok else: - py.test.fail("could not find the ::1 IPv6 address in %r" + py.test.fail("could not find the localhost address in %r" % (address_list,)) def test_getservbyname(): @@ -124,7 +118,7 @@ def as_str(self): return self.x - + if sys.platform == "win32": py.test.skip('No socketpair on Windows') s1, s2 = socketpair() From noreply at buildbot.pypy.org Thu Mar 21 22:52:46 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 21 Mar 2013 22:52:46 +0100 (CET) Subject: [pypy-commit] pypy default: implement .all() and .any() for numpy.bool_ objects Message-ID: <20130321215246.8E6231C0DC9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62618:26d70090eda4 Date: 2013-03-21 22:52 +0100 http://bitbucket.org/pypy/pypy/changeset/26d70090eda4/ Log: implement .all() and .any() for numpy.bool_ objects 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 @@ -175,6 +175,12 @@ class W_BoolBox(W_GenericBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("bool") + def descr_any(self, space): + return self + + def descr_all(self, space): + return self + class W_NumberBox(W_GenericBox): _attrs_ = () @@ -422,8 +428,9 @@ W_BoolBox.typedef = TypeDef("bool_", W_GenericBox.typedef, __module__ = "numpypy", __new__ = interp2app(W_BoolBox.descr__new__.im_func), - __index__ = interp2app(descr_index), + any = interp2app(W_BoolBox.descr_any), + all = interp2app(W_BoolBox.descr_all), ) W_NumberBox.typedef = TypeDef("number", W_GenericBox.typedef, 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 @@ -335,6 +335,15 @@ assert X(True) is numpy.True_ assert numpy.bool_("False") is numpy.True_ + def test_bool_any_all(self): + import numpypy as numpy + x = numpy.bool_(True) + assert x.any() + assert x.all() + x = numpy.bool_(False) + assert not x.any() + assert not x.all() + def test_int8(self): import numpypy as numpy From noreply at buildbot.pypy.org Fri Mar 22 00:29:04 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 00:29:04 +0100 (CET) Subject: [pypy-commit] pypy default: fixes for RSocket IPV6 support Message-ID: <20130321232904.135C91C10C2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62619:bd0e0b2b11bb Date: 2013-03-21 19:28 -0400 http://bitbucket.org/pypy/pypy/changeset/bd0e0b2b11bb/ Log: fixes for RSocket IPV6 support diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py --- a/rpython/rlib/_rsocket_rffi.py +++ b/rpython/rlib/_rsocket_rffi.py @@ -262,7 +262,7 @@ CConfig.in_addr = platform.Struct('struct in_addr', [('s_addr', rffi.UINT)]) CConfig.in6_addr = platform.Struct('struct in6_addr', - []) + [('s6_addr', rffi.CFixedArray(rffi.CHAR, 16))]) CConfig.sockaddr_in = platform.Struct('struct sockaddr_in', [('sin_family', rffi.INT), ('sin_port', rffi.USHORT), diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -339,7 +339,7 @@ # to avoid leaks if an exception occurs inbetween sin = lltype.malloc(_c.sockaddr_in6, flavor='raw', zero=True) result.setdata(sin, sizeof(_c.sockaddr_in6)) - rffi.setintfield(sin, 'c_sin6_family', AF_INET) + rffi.setintfield(sin, 'c_sin6_family', AF_INET6) rffi.structcopy(sin.c_sin6_addr, in6_addr) return result from_in6_addr = staticmethod(from_in6_addr) diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -68,17 +68,17 @@ % (address_list,)) def test_gethostbyaddr(): - for host in ["localhost", "127.0.0.1"]: + for host in ["localhost", "127.0.0.1", "::1"]: name, aliases, address_list = gethostbyaddr(host) allnames = [name] + aliases for n in allnames: assert isinstance(n, str) if sys.platform != 'win32': - assert 'localhost' in allnames + assert 'localhost' in allnames or 'ip6-localhost' in allnames for a in address_list: if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": break # ok - if host == 'localhost': # name lookup might return IPV6 + if host != '127.0.0.1': # name lookup might return IPV6 if isinstance(a, INET6Address) and a.get_host() == "::1": break # ok else: From noreply at buildbot.pypy.org Fri Mar 22 00:35:39 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 00:35:39 +0100 (CET) Subject: [pypy-commit] pypy default: test ip6-loopback here too Message-ID: <20130321233539.4260E1C10C2@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62620:ec25836976ee Date: 2013-03-21 19:35 -0400 http://bitbucket.org/pypy/pypy/changeset/ec25836976ee/ Log: test ip6-loopback here too diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -32,7 +32,7 @@ assert space.unwrap(ip) == socket.gethostbyname_ex(host) def test_gethostbyaddr(): - for host in ["localhost", "127.0.0.1"]: + for host in ["localhost", "127.0.0.1", "::1"]: ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) == socket.gethostbyaddr(host) From noreply at buildbot.pypy.org Fri Mar 22 00:43:11 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Fri, 22 Mar 2013 00:43:11 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Remove undeed SMM definition. Message-ID: <20130321234311.3760E1C14B0@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62621:a05eeef6cfb0 Date: 2013-03-22 01:09 +0200 http://bitbucket.org/pypy/pypy/changeset/a05eeef6cfb0/ Log: Remove undeed SMM definition. diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -19,7 +19,6 @@ from pypy.objspace.std.bytearrayinterface import bytearray_interface_methods -str_ljust = SMM('ljust', 3, defaults=(' ',)) str_join = SMM('join', 2, defaults=(None,-1)) bytearray_insert = SMM('insert', 3, From noreply at buildbot.pypy.org Fri Mar 22 00:43:12 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Fri, 22 Mar 2013 00:43:12 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Re-implement bytearray.insert. Message-ID: <20130321234312.892C61C14B0@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62622:c7554e6db542 Date: 2013-03-22 01:42 +0200 http://bitbucket.org/pypy/pypy/changeset/c7554e6db542/ Log: Re-implement bytearray.insert. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1322,6 +1322,11 @@ return None return self.str_w(w_obj) + def str_or_int_w(self, w_obj): + if self.is_true(self.isinstance(w_obj, self.w_str)): + return self.str_w(w_obj) + return self.int_w(w_obj) + def str_w(self, w_obj): return w_obj.str_w(self) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -129,6 +129,9 @@ def visit_str_or_None(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_str_or_int(self, el, app_sig): + self.checked_space_method(el, app_sig) + def visit_str0(self, el, app_sig): self.checked_space_method(el, app_sig) @@ -247,6 +250,9 @@ def visit_str_or_None(self, typ): self.run_args.append("space.str_or_None_w(%s)" % (self.scopenext(),)) + def visit_str_or_int(self, typ): + self.run_args.append("space.str_or_int_w(%s)" % (self.scopenext(),)) + def visit_str0(self, typ): self.run_args.append("space.str0_w(%s)" % (self.scopenext(),)) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -397,14 +397,6 @@ w_str = str__Bytearray(space, w_bytearray) return stringobject.str_isspace__String(space, w_str) -def bytearray_insert__Bytearray_Int_ANY(space, w_bytearray, w_idx, w_other): - where = space.int_w(w_idx) - length = len(w_bytearray.data) - index = get_positive_index(where, length) - val = getbytevalue(space, w_other) - w_bytearray.data.insert(index, val) - return space.w_None - def bytearray_pop__Bytearray_Int(space, w_bytearray, w_idx): index = space.int_w(w_idx) try: diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -1,8 +1,9 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import interp2app +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM +from pypy.objspace.std.listobject import get_positive_index from pypy.objspace.std.stringtype import ( str_decode, @@ -21,10 +22,21 @@ str_join = SMM('join', 2, defaults=(None,-1)) -bytearray_insert = SMM('insert', 3, - doc="B.insert(index, int) -> None\n\n" - "Insert a single item into the bytearray before " - "the given index.") + + at unwrap_spec(w_self=W_Root, index=int, val='str_or_int') +def bytearray_insert(w_self, space, index, val): + """B.insert(index, int) -> None + + Insert a single item into the bytearray before the given index. + """ + if isinstance(val, int): + val = chr(val) + elif len(val) != 1: + raise OperationError(space.w_ValueError, + space.wrap("string must be of size 1")) + w_self.data.insert(index, val) + return space.w_None + bytearray_pop = SMM('pop', 2, defaults=(-1,), doc="B.pop([index]) -> int\n\nRemove and return a " @@ -175,6 +187,7 @@ __hash__ = None, __reduce__ = interp2app(descr_bytearray__reduce__), fromhex = interp2app(descr_fromhex, as_classmethod=True), + insert = interp2app(bytearray_insert), **bytearray_interface_methods() ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Fri Mar 22 00:53:38 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Fri, 22 Mar 2013 00:53:38 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Re-implement bytearray.pop. Message-ID: <20130321235338.7F5D11C14B0@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62623:47ef3c341a14 Date: 2013-03-22 01:53 +0200 http://bitbucket.org/pypy/pypy/changeset/47ef3c341a14/ Log: Re-implement bytearray.pop. diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -397,18 +397,6 @@ w_str = str__Bytearray(space, w_bytearray) return stringobject.str_isspace__String(space, w_str) -def bytearray_pop__Bytearray_Int(space, w_bytearray, w_idx): - index = space.int_w(w_idx) - try: - result = w_bytearray.data.pop(index) - except IndexError: - if not w_bytearray.data: - raise OperationError(space.w_IndexError, space.wrap( - "pop from empty bytearray")) - raise OperationError(space.w_IndexError, space.wrap( - "pop index out of range")) - return space.wrap(ord(result)) - def bytearray_remove__Bytearray_ANY(space, w_bytearray, w_char): char = space.int_w(space.index(w_char)) try: diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -38,10 +38,23 @@ return space.w_None -bytearray_pop = SMM('pop', 2, defaults=(-1,), - doc="B.pop([index]) -> int\n\nRemove and return a " - "single item from B. If no index\nargument is given, " - "will pop the last value.") + at unwrap_spec(w_self=W_Root, index=int) +def bytearray_pop(w_self, space, index=-1): + """B.pop([index]) -> int + + Remove and return a single item from B. If no index + argument is given, will pop the last value. + """ + try: + result = w_self.data.pop(index) + except IndexError: + if not w_self.data: + raise OperationError(space.w_IndexError, space.wrap( + "pop from empty bytearray")) + raise OperationError(space.w_IndexError, space.wrap( + "pop index out of range")) + return space.wrap(ord(result)) + bytearray_remove = SMM('remove', 2, doc="B.remove(int) -> None\n\n" @@ -188,6 +201,7 @@ __reduce__ = interp2app(descr_bytearray__reduce__), fromhex = interp2app(descr_fromhex, as_classmethod=True), insert = interp2app(bytearray_insert), + pop = interp2app(bytearray_pop), **bytearray_interface_methods() ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Fri Mar 22 01:01:29 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 01:01:29 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: (arigo, fijal) fix the descr test Message-ID: <20130322000129.1C5001C14B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62624:b1beccb7c94f Date: 2013-03-21 16:55 -0700 http://bitbucket.org/pypy/pypy/changeset/b1beccb7c94f/ Log: (arigo, fijal) fix the descr test diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -57,11 +57,15 @@ def call_args(self, args): # delegate activation to code - return self.getcode().funcrun(self, args) + w_res = self.getcode().funcrun(self, args) + assert isinstance(w_res, W_Root) + return w_res def call_obj_args(self, w_obj, args): # delegate activation to code - return self.getcode().funcrun_obj(self, w_obj, args) + w_res = self.getcode().funcrun_obj(self, w_obj, args) + assert isinstance(w_res, W_Root) + return w_res def getcode(self): if jit.we_are_jitted(): diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -212,7 +212,11 @@ self.run_args.append('space') def visit__W_Root(self, el): - self.run_args.append(self.scopenext()) + if el is not W_Root: + self.run_args.append("space.interp_w(%s, %s)" % (self.use(el), + self.scopenext())) + else: + self.run_args.append(self.scopenext()) def visit__Arguments(self, el): self.miniglobals['Arguments'] = Arguments diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -146,8 +146,6 @@ # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None - if isinstance(x, model.W_Object): - raise TypeError, "attempt to wrap already wrapped object: %s"%(x,) if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% (x,)) From noreply at buildbot.pypy.org Fri Mar 22 01:01:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 01:01:30 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: (arigo, fijal) fix the descr test Message-ID: <20130322000130.4BA731C14B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62625:b24c7cb07f42 Date: 2013-03-21 16:58 -0700 http://bitbucket.org/pypy/pypy/changeset/b24c7cb07f42/ Log: (arigo, fijal) fix the descr test diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -153,11 +153,9 @@ def visit__W_Root(self, el, app_sig): argname = self.orig_arg() if argname == 'self': - # for W_ListObject and similar to be possible to have - # unwrap_spec in methods + assert el is not W_Root app_sig.append(argname) return - assert el is W_Root, "%s is not W_Root (forgotten to put .im_func in interp2app argument?)" % (el,) assert argname.startswith('w_'), ( "argument %s of built-in function %r should " "start with 'w_'" % (argname, self.func)) @@ -351,7 +349,11 @@ self.unwrap.append("space") def visit__W_Root(self, el): - self.unwrap.append(self.nextarg()) + if el is not W_Root: + self.unwrap.append("space.interp_w(%s, %s)" % (self.use(el), + self.nextarg())) + else: + self.unwrap.append(self.nextarg()) def visit__Arguments(self, el): raise FastFuncNotSupported From noreply at buildbot.pypy.org Fri Mar 22 01:01:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 01:01:31 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: (arigo, fijal) fix naming Message-ID: <20130322000131.873BA1C14B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62626:ad506216bd78 Date: 2013-03-21 17:00 -0700 http://bitbucket.org/pypy/pypy/changeset/ad506216bd78/ Log: (arigo, fijal) fix naming diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -591,7 +591,7 @@ return False - at unwrap_spec(file=W_File, encoding="str_or_None", errors="str_or_None") -def set_file_encoding(space, file, encoding=None, errors=None): - file.encoding = encoding - file.errors = errors + at unwrap_spec(w_file=W_File, encoding="str_or_None", errors="str_or_None") +def set_file_encoding(space, w_file, encoding=None, errors=None): + w_file.encoding = encoding + w_file.errors = errors From noreply at buildbot.pypy.org Fri Mar 22 01:08:59 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Fri, 22 Mar 2013 01:08:59 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Re-implement bytearray.remove. Message-ID: <20130322000859.BD8CA1C14B7@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62627:67ef049cda7e Date: 2013-03-22 02:08 +0200 http://bitbucket.org/pypy/pypy/changeset/67ef049cda7e/ Log: Re-implement bytearray.remove. diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -397,14 +397,6 @@ w_str = str__Bytearray(space, w_bytearray) return stringobject.str_isspace__String(space, w_str) -def bytearray_remove__Bytearray_ANY(space, w_bytearray, w_char): - char = space.int_w(space.index(w_char)) - try: - result = w_bytearray.data.remove(chr(char)) - except ValueError: - raise OperationError(space.w_ValueError, space.wrap( - "value not found in bytearray")) - def bytearray_reverse__Bytearray(space, w_bytearray): w_bytearray.data.reverse() return space.w_None diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -56,9 +56,19 @@ return space.wrap(ord(result)) -bytearray_remove = SMM('remove', 2, - doc="B.remove(int) -> None\n\n" - "Remove the first occurance of a value in B.") + at unwrap_spec(w_self=W_Root) +def bytearray_remove(w_self, space, w_index): + """B.remove(int) -> None + + Remove the first occurance of a value in B. + """ + val = space.int_w(space.index(w_index)) + try: + w_self.data.remove(chr(val)) + except ValueError: + raise OperationError(space.w_ValueError, space.wrap( + "value not found in bytearray")) + bytearray_reverse = SMM('reverse', 1, doc="B.reverse() -> None\n\n" @@ -200,8 +210,9 @@ __hash__ = None, __reduce__ = interp2app(descr_bytearray__reduce__), fromhex = interp2app(descr_fromhex, as_classmethod=True), - insert = interp2app(bytearray_insert), - pop = interp2app(bytearray_pop), + insert=interp2app(bytearray_insert), + pop=interp2app(bytearray_pop), + remove=interp2app(bytearray_remove), **bytearray_interface_methods() ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Fri Mar 22 01:17:26 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Fri, 22 Mar 2013 01:17:26 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Use index unwrap_spec type for index in bytearray.remove. Message-ID: <20130322001726.770BD1C04AB@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62628:e1b6bf1f9b9b Date: 2013-03-22 02:17 +0200 http://bitbucket.org/pypy/pypy/changeset/e1b6bf1f9b9b/ Log: Use index unwrap_spec type for index in bytearray.remove. diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -56,15 +56,14 @@ return space.wrap(ord(result)) - at unwrap_spec(w_self=W_Root) -def bytearray_remove(w_self, space, w_index): + at unwrap_spec(w_self=W_Root, value='index') +def bytearray_remove(w_self, space, value): """B.remove(int) -> None Remove the first occurance of a value in B. """ - val = space.int_w(space.index(w_index)) try: - w_self.data.remove(chr(val)) + w_self.data.remove(chr(value)) except ValueError: raise OperationError(space.w_ValueError, space.wrap( "value not found in bytearray")) From noreply at buildbot.pypy.org Fri Mar 22 01:18:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 01:18:32 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: fix fix fix Message-ID: <20130322001832.3E3FC1C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62629:9aebaf686e8e Date: 2013-03-21 17:18 -0700 http://bitbucket.org/pypy/pypy/changeset/9aebaf686e8e/ Log: fix fix fix diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -116,8 +116,8 @@ def checked_space_method(self, typname, app_sig): argname = self.orig_arg() assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typname, argname, self.func)) + "unwrapped %s argument %s of built-in function %r in %r should " + "not start with 'w_'" % (typname, argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname) def visit_index(self, index, app_sig): @@ -157,8 +157,8 @@ app_sig.append(argname) return assert argname.startswith('w_'), ( - "argument %s of built-in function %r should " - "start with 'w_'" % (argname, self.func)) + "argument %s of built-in function %r in %r should " + "start with 'w_'" % (argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -72,15 +72,15 @@ MiniBuffer.typedef.acceptable_as_base_class = False - at unwrap_spec(cdata=cdataobj.W_CData, size=int) -def buffer(space, cdata, size=-1): - ctype = cdata.ctype + at unwrap_spec(w_cdata=cdataobj.W_CData, size=int) +def buffer(space, w_cdata, size=-1): + ctype = w_cdata.ctype if isinstance(ctype, ctypeptr.W_CTypePointer): if size < 0: size = ctype.ctitem.size elif isinstance(ctype, ctypearray.W_CTypeArray): if size < 0: - size = cdata._sizeof() + size = w_cdata._sizeof() else: raise operationerrfmt(space.w_TypeError, "expected a pointer or array cdata, got '%s'", @@ -89,4 +89,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata)) + return space.wrap(MiniBuffer(LLBuffer(w_cdata._cdata, size), w_cdata)) diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -5,28 +5,28 @@ # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType, w_init=WrappedDefault(None)) -def newp(space, ctype, w_init): - return ctype.newp(w_init) + at unwrap_spec(w_ctype=ctypeobj.W_CType, w_init=WrappedDefault(None)) +def newp(space, w_ctype, w_init): + return w_ctype.newp(w_init) # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType) -def cast(space, ctype, w_ob): - return ctype.cast(w_ob) + at unwrap_spec(w_ctype=ctypeobj.W_CType) +def cast(space, w_ctype, w_ob): + return w_ctype.cast(w_ob) # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType) -def callback(space, ctype, w_callable, w_error=None): + at unwrap_spec(w_ctype=ctypeobj.W_CType) +def callback(space, w_ctype, w_callable, w_error=None): from pypy.module._cffi_backend.ccallback import W_CDataCallback - return W_CDataCallback(space, ctype, w_callable, w_error) + return W_CDataCallback(space, w_ctype, w_callable, w_error) # ____________________________________________________________ - at unwrap_spec(cdata=cdataobj.W_CData) -def typeof(space, cdata): - return cdata.ctype + at unwrap_spec(w_cdata=cdataobj.W_CData) +def typeof(space, w_cdata): + return w_cdata.ctype # ____________________________________________________________ @@ -44,33 +44,33 @@ space.wrap("expected a 'cdata' or 'ctype' object")) return space.wrap(size) - at unwrap_spec(ctype=ctypeobj.W_CType) -def alignof(space, ctype): - align = ctype.alignof() + at unwrap_spec(w_ctype=ctypeobj.W_CType) +def alignof(space, w_ctype): + align = w_ctype.alignof() return space.wrap(align) - at unwrap_spec(ctype=ctypeobj.W_CType, fieldname="str_or_None") -def typeoffsetof(space, ctype, fieldname): - ctype, offset = ctype.typeoffsetof(fieldname) + at unwrap_spec(w_ctype=ctypeobj.W_CType, fieldname="str_or_None") +def typeoffsetof(space, w_ctype, fieldname): + ctype, offset = w_ctype.typeoffsetof(fieldname) return space.newtuple([space.wrap(ctype), space.wrap(offset)]) - at unwrap_spec(ctype=ctypeobj.W_CType, cdata=cdataobj.W_CData, offset=int) -def rawaddressof(space, ctype, cdata, offset=0): - return ctype.rawaddressof(cdata, offset) + at unwrap_spec(w_ctype=ctypeobj.W_CType, w_cdata=cdataobj.W_CData, offset=int) +def rawaddressof(space, w_ctype, w_cdata, offset=0): + return w_ctype.rawaddressof(w_cdata, offset) # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType, replace_with=str) -def getcname(space, ctype, replace_with): - p = ctype.name_position - s = '%s%s%s' % (ctype.name[:p], replace_with, ctype.name[p:]) + at unwrap_spec(w_ctype=ctypeobj.W_CType, replace_with=str) +def getcname(space, w_ctype, replace_with): + p = w_ctype.name_position + s = '%s%s%s' % (w_ctype.name[:p], replace_with, w_ctype.name[p:]) return space.wrap(s) # ____________________________________________________________ - at unwrap_spec(cdata=cdataobj.W_CData, maxlen=int) -def string(space, cdata, maxlen=-1): - return cdata.ctype.string(cdata, maxlen) + at unwrap_spec(w_cdata=cdataobj.W_CData, maxlen=int) +def string(space, w_cdata, maxlen=-1): + return w_cdata.ctype.string(w_cdata, maxlen) # ____________________________________________________________ diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -39,21 +39,21 @@ space = self.space return space.wrap("" % self.name) - @unwrap_spec(ctype=W_CType, name=str) - def load_function(self, ctype, name): + @unwrap_spec(w_ctype=W_CType, name=str) + def load_function(self, w_ctype, name): from pypy.module._cffi_backend import ctypefunc, ctypeptr, ctypevoid space = self.space # ok = False - if isinstance(ctype, ctypefunc.W_CTypeFunc): + if isinstance(w_ctype, ctypefunc.W_CTypeFunc): ok = True - if (isinstance(ctype, ctypeptr.W_CTypePointer) and - isinstance(ctype.ctitem, ctypevoid.W_CTypeVoid)): + if (isinstance(w_ctype, ctypeptr.W_CTypePointer) and + isinstance(w_ctype.ctitem, ctypevoid.W_CTypeVoid)): ok = True if not ok: raise operationerrfmt(space.w_TypeError, "function cdata expected, got '%s'", - ctype.name) + w_ctype.name) # try: cdata = dlsym(self.handle, name) @@ -61,10 +61,10 @@ raise operationerrfmt(space.w_KeyError, "function '%s' not found in library '%s'", name, self.name) - return W_CData(space, rffi.cast(rffi.CCHARP, cdata), ctype) + return W_CData(space, rffi.cast(rffi.CCHARP, cdata), w_ctype) - @unwrap_spec(ctype=W_CType, name=str) - def read_variable(self, ctype, name): + @unwrap_spec(w_ctype=W_CType, name=str) + def read_variable(self, w_ctype, name): space = self.space try: cdata = dlsym(self.handle, name) @@ -72,10 +72,10 @@ raise operationerrfmt(space.w_KeyError, "variable '%s' not found in library '%s'", name, self.name) - return ctype.convert_to_object(rffi.cast(rffi.CCHARP, cdata)) + return w_ctype.convert_to_object(rffi.cast(rffi.CCHARP, cdata)) - @unwrap_spec(ctype=W_CType, name=str) - def write_variable(self, ctype, name, w_value): + @unwrap_spec(w_ctype=W_CType, name=str) + def write_variable(self, w_ctype, name, w_value): space = self.space try: cdata = dlsym(self.handle, name) @@ -83,7 +83,7 @@ raise operationerrfmt(space.w_KeyError, "variable '%s' not found in library '%s'", name, self.name) - ctype.convert_from_object(rffi.cast(rffi.CCHARP, cdata), w_value) + w_ctype.convert_from_object(rffi.cast(rffi.CCHARP, cdata), w_value) W_Library.typedef = TypeDef( diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -75,19 +75,19 @@ # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType) -def new_pointer_type(space, ctype): - ctypepointer = ctypeptr.W_CTypePointer(space, ctype) + at unwrap_spec(w_ctype=ctypeobj.W_CType) +def new_pointer_type(space, w_ctype): + ctypepointer = ctypeptr.W_CTypePointer(space, w_ctype) return ctypepointer # ____________________________________________________________ - at unwrap_spec(ctptr=ctypeobj.W_CType) -def new_array_type(space, ctptr, w_length): - if not isinstance(ctptr, ctypeptr.W_CTypePointer): + at unwrap_spec(w_ctptr=ctypeobj.W_CType) +def new_array_type(space, w_ctptr, w_length): + if not isinstance(w_ctptr, ctypeptr.W_CTypePointer): raise OperationError(space.w_TypeError, space.wrap("first arg must be a pointer ctype")) - ctitem = ctptr.ctitem + ctitem = w_ctptr.ctitem if ctitem.size < 0: raise operationerrfmt(space.w_ValueError, "array item of unknown size: '%s'", @@ -108,7 +108,7 @@ space.wrap("array size would overflow a ssize_t")) extra = '[%d]' % length # - ctype = ctypearray.W_CTypeArray(space, ctptr, length, arraysize, extra) + ctype = ctypearray.W_CTypeArray(space, w_ctptr, length, arraysize, extra) return ctype # ____________________________________________________________ @@ -121,16 +121,16 @@ def new_union_type(space, name): return ctypestruct.W_CTypeUnion(space, name) - at unwrap_spec(ctype=ctypeobj.W_CType, totalsize=int, totalalignment=int) -def complete_struct_or_union(space, ctype, w_fields, w_ignored=None, + at unwrap_spec(w_ctype=ctypeobj.W_CType, totalsize=int, totalalignment=int) +def complete_struct_or_union(space, w_ctype, w_fields, w_ignored=None, totalsize=-1, totalalignment=-1): - if (not isinstance(ctype, ctypestruct.W_CTypeStructOrUnion) - or ctype.size >= 0): + if (not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion) + or w_ctype.size >= 0): raise OperationError(space.w_TypeError, space.wrap("first arg must be a non-initialized" " struct or union ctype")) - is_union = isinstance(ctype, ctypestruct.W_CTypeUnion) + is_union = isinstance(w_ctype, ctypestruct.W_CTypeUnion) maxsize = 1 alignment = 1 offset = 0 @@ -159,7 +159,7 @@ if ftype.size < 0: raise operationerrfmt(space.w_TypeError, "field '%s.%s' has ctype '%s' of unknown size", - ctype.name, fname, ftype.name) + w_ctype.name, fname, ftype.name) # falign = ftype.alignof() if alignment < falign: @@ -246,15 +246,15 @@ elif totalsize < offset: raise operationerrfmt(space.w_TypeError, "%s cannot be of size %d: there are fields at least " - "up to %d", ctype.name, totalsize, offset) + "up to %d", w_ctype.name, totalsize, offset) if totalalignment < 0: totalalignment = alignment - ctype.size = totalsize - ctype.alignment = totalalignment - ctype.fields_list = fields_list - ctype.fields_dict = fields_dict - ctype.custom_field_pos = custom_field_pos + w_ctype.size = totalsize + w_ctype.alignment = totalalignment + w_ctype.fields_list = fields_list + w_ctype.fields_dict = fields_dict + w_ctype.custom_field_pos = custom_field_pos # ____________________________________________________________ @@ -264,8 +264,8 @@ # ____________________________________________________________ - at unwrap_spec(name=str, basectype=ctypeobj.W_CType) -def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): + at unwrap_spec(name=str, w_basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, w_basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): @@ -273,22 +273,22 @@ space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] # - if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and - not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + if (not isinstance(w_basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(w_basectype, ctypeprim.W_CTypePrimitiveUnsigned)): raise OperationError(space.w_TypeError, space.wrap("expected a primitive signed or unsigned base type")) # - lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') + lvalue = lltype.malloc(rffi.CCHARP.TO, w_basectype.size, flavor='raw') try: for w in enumvalues_w: # detects out-of-range or badly typed values - basectype.convert_from_object(lvalue, w) + w_basectype.convert_from_object(lvalue, w) finally: lltype.free(lvalue, flavor='raw') # - size = basectype.size - align = basectype.align - if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): + size = w_basectype.size + align = w_basectype.align + if isinstance(w_basectype, ctypeprim.W_CTypePrimitiveSigned): enumvalues = [space.int_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, enumerators, enumvalues) @@ -300,8 +300,8 @@ # ____________________________________________________________ - at unwrap_spec(fresult=ctypeobj.W_CType, ellipsis=int) -def new_function_type(space, w_fargs, fresult, ellipsis=0): + at unwrap_spec(w_fresult=ctypeobj.W_CType, ellipsis=int) +def new_function_type(space, w_fargs, w_fresult, ellipsis=0): from pypy.module._cffi_backend import ctypefunc fargs = [] for w_farg in space.fixedview(w_fargs): @@ -312,15 +312,16 @@ w_farg = w_farg.ctptr fargs.append(w_farg) # - if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid)) - or isinstance(fresult, ctypearray.W_CTypeArray)): - if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion) and - fresult.size < 0): + if ((w_fresult.size < 0 and + not isinstance(w_fresult, ctypevoid.W_CTypeVoid)) + or isinstance(w_fresult, ctypearray.W_CTypeArray)): + if (isinstance(w_fresult, ctypestruct.W_CTypeStructOrUnion) and + w_fresult.size < 0): raise operationerrfmt(space.w_TypeError, - "result type '%s' is opaque", fresult.name) + "result type '%s' is opaque", w_fresult.name) else: raise operationerrfmt(space.w_TypeError, - "invalid result type: '%s'", fresult.name) + "invalid result type: '%s'", w_fresult.name) # - fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis) + fct = ctypefunc.W_CTypeFunc(space, fargs, w_fresult, ellipsis) return fct From noreply at buildbot.pypy.org Fri Mar 22 01:19:26 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Fri, 22 Mar 2013 01:19:26 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Remove bogus w_self=W_Root in bytearraytype unwrap_specs. Message-ID: <20130322001926.366591C04AB@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62630:632f4fdd4857 Date: 2013-03-22 02:19 +0200 http://bitbucket.org/pypy/pypy/changeset/632f4fdd4857/ Log: Remove bogus w_self=W_Root in bytearraytype unwrap_specs. diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -23,7 +23,7 @@ str_join = SMM('join', 2, defaults=(None,-1)) - at unwrap_spec(w_self=W_Root, index=int, val='str_or_int') + at unwrap_spec(index=int, val='str_or_int') def bytearray_insert(w_self, space, index, val): """B.insert(index, int) -> None @@ -38,7 +38,7 @@ return space.w_None - at unwrap_spec(w_self=W_Root, index=int) + at unwrap_spec(index=int) def bytearray_pop(w_self, space, index=-1): """B.pop([index]) -> int @@ -56,7 +56,7 @@ return space.wrap(ord(result)) - at unwrap_spec(w_self=W_Root, value='index') + at unwrap_spec(value='index') def bytearray_remove(w_self, space, value): """B.remove(int) -> None From noreply at buildbot.pypy.org Fri Mar 22 01:54:12 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 01:54:12 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: (arigo, fijal) fix fix fix Message-ID: <20130322005412.88EE61C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62631:a8616e7bc663 Date: 2013-03-21 17:53 -0700 http://bitbucket.org/pypy/pypy/changeset/a8616e7bc663/ Log: (arigo, fijal) fix fix fix diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -466,6 +466,7 @@ def __init__(self, default_value): self.default_value = default_value + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ diff --git a/pypy/module/parser/__init__.py b/pypy/module/parser/__init__.py --- a/pypy/module/parser/__init__.py +++ b/pypy/module/parser/__init__.py @@ -17,12 +17,12 @@ 'expr' : 'pyparser.expr', 'issuite' : 'pyparser.issuite', 'isexpr' : 'pyparser.isexpr', - 'STType' : 'pyparser.STType', + 'STType' : 'pyparser.W_STType', 'ast2tuple' : 'pyparser.st2tuple', 'st2tuple' : 'pyparser.st2tuple', 'ast2list' : 'pyparser.st2list', 'ast2tuple' : 'pyparser.st2tuple', - 'ASTType' : 'pyparser.STType', + 'ASTType' : 'pyparser.W_STType', 'compilest' : 'pyparser.compilest', 'compileast' : 'pyparser.compilest', 'ParserError' : 'space.new_exception_class("parser.ParserError")', diff --git a/pypy/module/parser/pyparser.py b/pypy/module/parser/pyparser.py --- a/pypy/module/parser/pyparser.py +++ b/pypy/module/parser/pyparser.py @@ -8,7 +8,7 @@ from rpython.rlib.objectmodel import specialize -class STType(W_Root): +class W_STType(W_Root): def __init__(self, tree, mode): self.tree = tree self.mode = mode @@ -62,12 +62,12 @@ e.wrap_info(space)) return space.wrap(result) -STType.typedef = TypeDef("parser.st", - issuite=interp2app(STType.descr_issuite), - isexpr=interp2app(STType.descr_isexpr), - totuple=interp2app(STType.descr_totuple), - tolist=interp2app(STType.descr_tolist), - compile=interp2app(STType.descr_compile) +W_STType.typedef = TypeDef("parser.st", + issuite=interp2app(W_STType.descr_issuite), + isexpr=interp2app(W_STType.descr_isexpr), + totuple=interp2app(W_STType.descr_totuple), + tolist=interp2app(W_STType.descr_tolist), + compile=interp2app(W_STType.descr_compile) ) @@ -82,7 +82,7 @@ except error.SyntaxError, e: raise OperationError(space.w_SyntaxError, e.wrap_info(space)) - return space.wrap(STType(tree, mode)) + return space.wrap(W_STType(tree, mode)) @unwrap_spec(source=str) @@ -95,22 +95,22 @@ return parse_python(space, source, 'eval') - at unwrap_spec(st=STType) -def isexpr(space, st): - return space.call_method(st, "isexpr") + at unwrap_spec(w_st=W_STType) +def isexpr(space, w_st): + return w_st.descr_isexpr(space) - at unwrap_spec(st=STType) -def issuite(space, st): - return space.call_method(st, "issuite") + at unwrap_spec(w_st=W_STType) +def issuite(space, w_st): + return w_st.descr_issuite(space) - at unwrap_spec(st=STType) -def st2tuple(space, st, __args__): - return space.call_args(space.getattr(st, space.wrap("totuple")), __args__) + at unwrap_spec(w_st=W_STType) +def st2tuple(space, w_st, __args__): + return space.call_args(space.getattr(w_st, space.wrap("totuple")), __args__) - at unwrap_spec(st=STType) -def st2list(space, st, __args__): - return space.call_args(space.getattr(st, space.wrap("tolist")), __args__) + at unwrap_spec(w_st=W_STType) +def st2list(space, w_st, __args__): + return space.call_args(space.getattr(w_st, space.wrap("tolist")), __args__) - at unwrap_spec(st=STType) -def compilest(space, st, __args__): - return space.call_args(space.getattr(st, space.wrap("compile")), __args__) + at unwrap_spec(w_st=W_STType) +def compilest(space, w_st, __args__): + return space.call_args(space.getattr(w_st, space.wrap("compile")), __args__) 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 @@ -134,15 +134,18 @@ getint = interp2app(WrappedBox.descr_getint), ) - at unwrap_spec(num=int, offset=int, repr=str, res=WrappedBox) -def descr_new_resop(space, w_tp, num, w_args, res, offset=-1, + at unwrap_spec(num=int, offset=int, repr=str, w_res=W_Root) +def descr_new_resop(space, w_tp, num, w_args, w_res, offset=-1, repr=''): args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in space.listview(w_args)] - if res is None: + if space.is_none(w_res): llres = jit_hooks.emptyval() else: - llres = res.llbox + if not isinstance(w_res, WrappedBox): + raise OperationError(space.w_TypeError, space.wrap( + "expected box type, got %s" % space.type(w_res))) + llres = w_res.llbox return WrappedOp(jit_hooks.resop_new(num, args, llres), offset, repr) @unwrap_spec(repr=str, jd_name=str, call_depth=int, call_id=int) @@ -178,9 +181,9 @@ def descr_getarg(self, space, no): return WrappedBox(jit_hooks.resop_getarg(self.op, no)) - @unwrap_spec(no=int, box=WrappedBox) - def descr_setarg(self, space, no, box): - jit_hooks.resop_setarg(self.op, no, box.llbox) + @unwrap_spec(no=int, w_box=WrappedBox) + def descr_setarg(self, space, no, w_box): + jit_hooks.resop_setarg(self.op, no, w_box.llbox) def descr_getresult(self, space): return WrappedBox(jit_hooks.resop_getresult(self.op)) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -571,7 +571,7 @@ w_bytearray.data += makebytearraydata_w(space, w_other) def inplace_add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2): - list_extend__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2) + bytearray_extend__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2) return w_bytearray1 def inplace_add__Bytearray_ANY(space, w_bytearray1, w_iterable2): diff --git a/pypy/objspace/std/test/test_proxy_internals.py b/pypy/objspace/std/test/test_proxy_internals.py --- a/pypy/objspace/std/test/test_proxy_internals.py +++ b/pypy/objspace/std/test/test_proxy_internals.py @@ -140,10 +140,13 @@ def test_proxy_get(self): from __pypy__ import tproxy, get_tproxy_controller - l = [1,2,3] + + class A(object): + pass + def f(name, *args, **kwargs): - return getattr(l, name)(*args, **kwargs) - lst = tproxy(list, f) + pass + lst = tproxy(A, f) assert get_tproxy_controller(lst) is f def test_proxy_file(self): diff --git a/pypy/objspace/std/test/test_proxy_object.py b/pypy/objspace/std/test/test_proxy_object.py --- a/pypy/objspace/std/test/test_proxy_object.py +++ b/pypy/objspace/std/test/test_proxy_object.py @@ -34,8 +34,9 @@ def test_simple_obj(self): class AT(self.A): pass - + c = self.Controller(self.A()) + obj = self.proxy(self.A, c.perform) obj = self.proxy(AT, c.perform) assert type(obj) is AT diff --git a/pypy/objspace/std/transparent.py b/pypy/objspace/std/transparent.py --- a/pypy/objspace/std/transparent.py +++ b/pypy/objspace/std/transparent.py @@ -37,7 +37,7 @@ PyCode, GeneratorIterator if not space.is_true(space.callable(w_controller)): raise OperationError(space.w_TypeError, space.wrap("controller should be function")) - + if isinstance(w_type, W_TypeObject): if space.is_true(space.issubtype(w_type, space.gettypeobject(Function.typedef))): return W_TransparentFunction(space, w_type, w_controller) @@ -57,7 +57,7 @@ for k, v in type_cache.cache: if w_lookup == k: return v(space, w_type, w_controller) - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "'%s' object could not be wrapped (YET)", w_type.getname(space)) From noreply at buildbot.pypy.org Fri Mar 22 02:13:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 02:13:53 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: (arigo, fijal) Proxies seems to be broken, otherwise fix the rest of errors Message-ID: <20130322011353.7728B1C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62632:b71c07d9680f Date: 2013-03-21 18:13 -0700 http://bitbucket.org/pypy/pypy/changeset/b71c07d9680f/ Log: (arigo, fijal) Proxies seems to be broken, otherwise fix the rest of errors diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/module/test_lib_pypy/test_tputil.py b/pypy/module/test_lib_pypy/test_tputil.py --- a/pypy/module/test_lib_pypy/test_tputil.py +++ b/pypy/module/test_lib_pypy/test_tputil.py @@ -2,55 +2,85 @@ spaceconfig = {"objspace.std.withtproxy": True} def test_errors(self): - from tputil import make_proxy + from tputil import make_proxy raises(TypeError, "make_proxy(None)") raises(TypeError, "make_proxy(None, None)") - def f(): pass + def f(): pass raises(TypeError, "make_proxy(f)") raises(TypeError, "make_proxy(f, None, None)") def test_repr(self): - from tputil import make_proxy + from tputil import make_proxy + + class A(object): + def append(self, item): + pass + l = [] - def func(operation): + def func(operation): l.append(repr(operation)) return operation.delegate() - tp = make_proxy(func, obj=[]) + tp = make_proxy(func, obj=A()) tp.append(3) for rep in l: assert isinstance(rep, str) - assert rep.find("list") != -1 + assert rep.find("append") != -1 def test_virtual_proxy(self): - from tputil import make_proxy + skip("XXX seems that proxies are more than a bit broken by now, but noone cares") + class A(object): + def __getitem__(self, item): + pass + + def __getslice__(self, start, stop): + xxx + + from tputil import make_proxy l = [] - tp = make_proxy(l.append, type=list) - x = tp[0:1] + + def f(*args): + print args + + tp = make_proxy(f, type=A) + #tp.__getslice__(0, 1) + tp[0:1] assert len(l) == 1 assert l[0].opname == '__getslice__' - + def test_simple(self): - from tputil import make_proxy + from tputil import make_proxy + + class A(object): + def append(self, item): + pass + record = [] def func(operation): record.append(operation) return operation.delegate() - l = make_proxy(func, obj=[]) + l = make_proxy(func, obj=A()) l.append(1) - assert len(record) == 2 - i1, i2 = record + assert len(record) == 1 + i1, = record assert i1.opname == '__getattribute__' - assert i2.opname == 'append' def test_missing_attr(self): from tputil import make_proxy + + class A(object): + pass + def func(operation): return operation.delegate() - l = make_proxy(func, obj=[]) + l = make_proxy(func, obj=A()) raises(AttributeError, "l.asdasd") - def test_proxy_double(self): + def test_proxy_double(self): from tputil import make_proxy + + class A(object): + def append(self, item): + pass r1 = [] r2 = [] def func1(operation): @@ -59,27 +89,32 @@ def func2(operation): r2.append(operation) return operation.delegate() - - l = make_proxy(func1, obj=[]) + + l = make_proxy(func1, obj=A()) l2 = make_proxy(func2, obj=l) assert not r1 and not r2 l2.append assert len(r2) == 1 assert r2[0].opname == '__getattribute__' - assert len(r1) == 2 + assert len(r1) == 2 assert r1[0].opname == '__getattribute__' assert r1[0].args[0] == '__getattribute__' assert r1[1].opname == '__getattribute__' - assert r1[1].args[0] == 'append' + assert r1[1].args[0] == 'append' def test_proxy_inplace_add(self): r = [] - from tputil import make_proxy + from tputil import make_proxy + + class A(object): + def __iadd__(self, other): + return self + def func1(operation): r.append(operation) return operation.delegate() - l2 = make_proxy(func1, obj=[]) + l2 = make_proxy(func1, obj=A()) l = l2 l += [3] assert l is l2 diff --git a/pypy/objspace/std/test/test_proxy.py b/pypy/objspace/std/test/test_proxy.py --- a/pypy/objspace/std/test/test_proxy.py +++ b/pypy/objspace/std/test/test_proxy.py @@ -2,15 +2,17 @@ """ test transparent proxy features """ +import py + class AppProxyBasic(object): spaceconfig = {"objspace.std.withtproxy": True} - + def setup_method(self, meth): self.w_Controller = self.space.appexec([], """(): class Controller(object): def __init__(self, obj): self.obj = obj - + def perform(self, name, *args, **kwargs): return getattr(self.obj, name)(*args, **kwargs) return Controller @@ -21,6 +23,9 @@ """) class AppTestListProxy(AppProxyBasic): + def setup_class(cls): + py.test.skip("removed support for lists") + def test_proxy(self): lst = self.proxy(list, lambda : None) assert type(lst) is list @@ -30,7 +35,7 @@ lst = [1,2,3] if name == '__repr__': return repr(lst) - + lst = self.proxy(list, controller) assert repr(lst) == repr([1,2,3]) @@ -79,13 +84,13 @@ pass else: fail("Accessing outside a list didn't raise") - + def test_list_inplace_add(self): c = self.Controller([1,2,3]) lst = self.proxy(list, c.perform) lst += [1,2,3] assert len(lst) == 6 - + def test_list_reverse_add(self): c = self.Controller([1,2,3]) lst = self.proxy(list, c.perform) @@ -93,6 +98,9 @@ assert l == [1,1,2,3] class AppTestDictProxy(AppProxyBasic): + def setup_class(cls): + py.test.skip("removed support for dicts") + def test_dict(self): c = self.Controller({"xx":1}) d = self.proxy(dict, c.perform) @@ -102,7 +110,7 @@ d.update(d2, x=4) assert sorted(d.keys()) == ['x', 'xx', 'yy'] assert sorted(d.values()) == [1, 3, 4] - + def test_dict_pop(self): c = self.Controller({'x':1}) d = self.proxy(dict, c.perform) diff --git a/pypy/objspace/std/test/test_proxy_object.py b/pypy/objspace/std/test/test_proxy_object.py --- a/pypy/objspace/std/test/test_proxy_object.py +++ b/pypy/objspace/std/test/test_proxy_object.py @@ -36,7 +36,6 @@ pass c = self.Controller(self.A()) - obj = self.proxy(self.A, c.perform) obj = self.proxy(AT, c.perform) assert type(obj) is AT @@ -97,24 +96,3 @@ c = self.Controller(a) obj = self.proxy(self.A, c.perform) assert repr(obj)[:6] == repr(a)[:6] - -class AppTestProxyObjectList(AppTestProxyObj): - def setup_method(self, meth): - super(AppTestProxyObj, self).setup_method(meth) - self.w_A = self.space.appexec([], """(): - class A(list): - pass - return A - """) - self.w_proxy = self.space.appexec([], """(): - from __pypy__ import tproxy - return tproxy - """) - - - def test_list_append(self): - a = self.A([1,2,3]) - c = self.Controller(a) - obj = self.proxy(self.A, c.perform) - assert len(obj) == 3 - assert obj[1] == 2 diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py --- a/pypy/objspace/std/test/test_stdobjspace.py +++ b/pypy/objspace/std/test/test_stdobjspace.py @@ -1,10 +1,12 @@ +import py +from py.test import raises from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import app2interp from pypy.tool.pytest.objspace import gettestobjspace class TestW_StdObjSpace: def test_wrap_wrap(self): + py.test.skip("maybe unskip in the future") raises(TypeError, self.space.wrap, self.space.wrap(0)) @@ -30,8 +32,8 @@ assert ('lt', False) in res assert ('setitem', False) in res assert ('mod', False) not in res - assert ('pop', True) in res - assert ('reverse', True) in res + assert ('pop', True) not in res + assert ('reverse', True) not in res assert ('popitem', True) not in res def test_sliceindices(self): diff --git a/pypy/objspace/std/transparent.py b/pypy/objspace/std/transparent.py --- a/pypy/objspace/std/transparent.py +++ b/pypy/objspace/std/transparent.py @@ -58,7 +58,7 @@ if w_lookup == k: return v(space, w_type, w_controller) raise operationerrfmt(space.w_TypeError, - "'%s' object could not be wrapped (YET)", + "'%s' object could not be wrapped", w_type.getname(space)) def register_proxyable(space, cls): From noreply at buildbot.pypy.org Fri Mar 22 02:30:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 02:30:35 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: fix translation Message-ID: <20130322013035.292291C0DC9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62633:96b7c2746125 Date: 2013-03-21 18:28 -0700 http://bitbucket.org/pypy/pypy/changeset/96b7c2746125/ Log: fix translation diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py --- a/pypy/objspace/std/proxyobject.py +++ b/pypy/objspace/std/proxyobject.py @@ -72,10 +72,10 @@ return W_Transparent W_Transparent = transparent_class('W_Transparent', baseobjspace.W_Root) -W_TransparentObject = transparent_class('W_TransparentObject', W_Object) +#W_TransparentObject = transparent_class('W_TransparentObject', W_Object) -from pypy.objspace.std.objecttype import object_typedef -W_TransparentObject.typedef = object_typedef +#from pypy.objspace.std.objecttype import object_typedef +#W_TransparentObject.typedef = object_typedef from pypy.interpreter.typedef import Function, GeneratorIterator, PyTraceback, \ PyFrame, PyCode From noreply at buildbot.pypy.org Fri Mar 22 05:35:04 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 05:35:04 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): remove some random nonsense Message-ID: <20130322043504.7E6071C04AB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62634:ecebd2bc6598 Date: 2013-03-21 21:34 -0700 http://bitbucket.org/pypy/pypy/changeset/ecebd2bc6598/ Log: (alex, fijal): remove some random nonsense diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,27 +1,30 @@ import sys +from rpython.rlib.cache import Cache +from rpython.tool.uid import HUGEVAL_BYTES +from rpython.rlib import jit, types +from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, + compute_unique_id) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import r_uint + from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, UserDelAction, FrameTraceAction) from pypy.interpreter.error import (OperationError, operationerrfmt, new_exception_class, typed_unwrap_error_msg) from pypy.interpreter.argument import Arguments from pypy.interpreter.miscutils import ThreadLocals -from rpython.rlib.cache import Cache -from rpython.tool.uid import HUGEVAL_BYTES -from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.objectmodel import we_are_translated, newlist_hint,\ - compute_unique_id -from rpython.rlib.rarithmetic import r_uint __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) -unpackiterable_driver = jit.JitDriver(name = 'unpackiterable', - greens = ['tp'], - reds = ['items', 'w_iterator']) +unpackiterable_driver = jit.JitDriver(name='unpackiterable', + greens=['tp'], + reds=['items', 'w_iterator']) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -698,6 +701,7 @@ raise return None + @signature(types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True diff --git a/pypy/tool/ann_override.py b/pypy/tool/ann_override.py --- a/pypy/tool/ann_override.py +++ b/pypy/tool/ann_override.py @@ -1,22 +1,17 @@ # overrides for annotation specific to PyPy codebase -from rpython.annotator.policy import AnnotatorPolicy, Sig +from rpython.annotator.policy import AnnotatorPolicy # for some reason, model must be imported first, # or we create a cycle. from rpython.flowspace.model import Constant -from rpython.annotator import model as annmodel -from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import specialize -from pypy.interpreter import baseobjspace + def isidentifier(s): - if not s: return False + if not s: + return False s = s.replace('_', 'x') return s[0].isalpha() and s.isalnum() -# patch - mostly for debugging, to enforce some signatures -baseobjspace.ObjSpace.newbool.im_func._annenforceargs_ = Sig(lambda s1,s2: s1, - bool) - class PyPyAnnotatorPolicy(AnnotatorPolicy): def __init__(pol, single_space=None): @@ -60,8 +55,8 @@ # for jit benefit if cached not in t._immutable_fields_: # accessed this way just # for convenience - t._immutable_fields_.append(cached) - + t._immutable_fields_.append(cached) + def attach_lookup(pol, t, attr): cached = "cached_%s" % attr if not t.is_heaptype() and not t.is_cpytype(): diff --git a/rpython/rlib/signature.py b/rpython/rlib/signature.py --- a/rpython/rlib/signature.py +++ b/rpython/rlib/signature.py @@ -1,5 +1,6 @@ from rpython.rlib import types + def signature(*paramtypes, **kwargs): """Decorate a function to specify its type signature. @@ -12,7 +13,7 @@ """ returntype = kwargs.pop('returns', None) if returntype is None: - raise TypeError, "signature: parameter 'returns' required" + raise TypeError("signature: parameter 'returns' required") def decorator(f): f._signature_ = (paramtypes, returntype) diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py --- a/rpython/rlib/types.py +++ b/rpython/rlib/types.py @@ -10,9 +10,11 @@ def float(): return model.SomeFloat() + def singlefloat(): return model.SomeSingleFloat() + def longfloat(): return model.SomeLongFloat() @@ -21,18 +23,26 @@ return model.SomeInteger() +def bool(): + return model.SomeBool() + + def unicode(): return model.SomeUnicodeString() + def unicode0(): return model.SomeUnicodeString(no_nul=True) + def str(): return model.SomeString() + def str0(): return model.SomeString(no_nul=True) + def char(): return model.SomeChar() @@ -46,21 +56,25 @@ listdef = ListDef(None, element, mutated=True, resized=True) return model.SomeList(listdef) + def array(element): listdef = ListDef(None, element, mutated=True, resized=False) return model.SomeList(listdef) + def dict(keytype, valuetype): dictdef = DictDef(None, keytype, valuetype) return model.SomeDict(dictdef) -def instance(class_): - return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(class_)) +def instance(cls): + return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(cls)) + class SelfTypeMarker(object): pass + def self(): return SelfTypeMarker() @@ -68,5 +82,6 @@ class AnyTypeMarker(object): pass + def any(): return AnyTypeMarker() From noreply at buildbot.pypy.org Fri Mar 22 05:40:58 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 05:40:58 +0100 (CET) Subject: [pypy-commit] pypy default: Replace annenforce args with signature() in rsandbox Message-ID: <20130322044058.9DEB41C04AB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62635:0b27e32c2000 Date: 2013-03-21 21:40 -0700 http://bitbucket.org/pypy/pypy/changeset/0b27e32c2000/ Log: Replace annenforce args with signature() in rsandbox diff --git a/rpython/translator/sandbox/rsandbox.py b/rpython/translator/sandbox/rsandbox.py --- a/rpython/translator/sandbox/rsandbox.py +++ b/rpython/translator/sandbox/rsandbox.py @@ -3,7 +3,10 @@ trampolines that marshal their input arguments, dump them to STDOUT, and wait for an answer on STDIN. Enable with 'translate.py --sandbox'. """ -from rpython.rlib import rmarshal +import py + +from rpython.rlib import rmarshal, types +from rpython.rlib.signature import signature # ____________________________________________________________ # @@ -12,12 +15,10 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.annotator import model as annmodel -from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import CDefinedIntSymbolic from rpython.tool.sourcetools import func_with_new_name from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator from rpython.tool.ansi_print import ansi_log -import py + log = py.log.Producer("sandbox") py.log.setconsumer("sandbox", ansi_log) @@ -27,13 +28,15 @@ ll_read_not_sandboxed = rffi.llexternal('read', [rffi.INT, rffi.CCHARP, rffi.SIZE_T], rffi.SIZE_T, - sandboxsafe = True) + sandboxsafe=True) ll_write_not_sandboxed = rffi.llexternal('write', [rffi.INT, rffi.CCHARP, rffi.SIZE_T], rffi.SIZE_T, - sandboxsafe = True) + sandboxsafe=True) + + at signature(types.int(), types.ptr(rffi.CCHARP.TO), types.int(), returns=types.none()) def writeall_not_sandboxed(fd, buf, length): while length > 0: size = rffi.cast(rffi.SIZE_T, length) @@ -43,22 +46,6 @@ length -= count buf = lltype.direct_ptradd(lltype.direct_arrayitems(buf), count) buf = rffi.cast(rffi.CCHARP, buf) -writeall_not_sandboxed._annenforceargs_ = [int, rffi.CCHARP, int] - -##def readall_not_sandboxed(fd, length): -## buf = lltype.malloc(rffi.CCHARP.TO, length, flavor='raw') -## p = buf -## got = 0 -## while got < length: -## size1 = rffi.cast(rffi.SIZE_T, length - got) -## count = rffi.cast(lltype.Signed, ll_read_not_sandboxed(fd, p, size1)) -## if count <= 0: -## raise IOError -## got += count -## p = lltype.direct_ptradd(lltype.direct_arrayitems(p), count) -## p = rffi.cast(rffi.CCHARP, p) -## return buf -##readall_not_sandboxed._annenforceargs_ = [int, int] class FdLoader(rmarshal.Loader): @@ -112,13 +99,14 @@ elif error == 8: raise IndexError else: raise RuntimeError + + at signature(types.str(), returns=types.none()) def not_implemented_stub(msg): STDERR = 2 buf = rffi.str2charp(msg + '\n') writeall_not_sandboxed(STDERR, buf, len(msg) + 1) rffi.free_charp(buf) raise RuntimeError(msg) # XXX in RPython, the msg is ignored at the moment -not_implemented_stub._annenforceargs_ = [str] dump_string = rmarshal.get_marshaller(str) load_int = rmarshal.get_loader(int) From noreply at buildbot.pypy.org Fri Mar 22 05:49:46 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 05:49:46 +0100 (CET) Subject: [pypy-commit] pypy extregistry-refactor: close to be merged branch Message-ID: <20130322044946.C66B31C0171@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extregistry-refactor Changeset: r62636:f208efb03da6 Date: 2013-03-21 21:49 -0700 http://bitbucket.org/pypy/pypy/changeset/f208efb03da6/ Log: close to be merged branch From noreply at buildbot.pypy.org Fri Mar 22 05:49:48 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 05:49:48 +0100 (CET) Subject: [pypy-commit] pypy default: (ronan) remove happy nonsense that meaning was abandonded eons ago Message-ID: <20130322044948.5E8291C0171@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62637:92a9a93262ed Date: 2013-03-21 21:49 -0700 http://bitbucket.org/pypy/pypy/changeset/92a9a93262ed/ Log: (ronan) remove happy nonsense that meaning was abandonded eons ago diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -11,14 +11,13 @@ from rpython.annotator.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue from rpython.annotator.model import SomeInstance, SomeBuiltin, SomeIterator from rpython.annotator.model import SomePBC, SomeFloat, s_None, SomeByteArray -from rpython.annotator.model import SomeExternalObject, SomeWeakRef +from rpython.annotator.model import SomeWeakRef from rpython.annotator.model import SomeAddress, SomeTypedAddressAccess from rpython.annotator.model import SomeSingleFloat, SomeLongFloat, SomeType from rpython.annotator.model import unionof, UnionError, missing_operation from rpython.annotator.model import TLS from rpython.annotator.model import read_can_only_throw from rpython.annotator.model import add_knowntypedata, merge_knowntypedata -from rpython.annotator.model import SomeGenericCallable from rpython.annotator.bookkeeper import getbookkeeper from rpython.flowspace.model import Variable, Constant from rpython.rlib import rarithmetic @@ -131,7 +130,7 @@ def is_((obj1, obj2)): r = SomeBool() if obj2.is_constant(): - if obj1.is_constant(): + if obj1.is_constant(): r.const = obj1.const is obj2.const if obj2.const is None and not obj1.can_be_none(): r.const = False @@ -149,7 +148,7 @@ def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): - add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, + add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, bk.valueoftype(src_obj.const)) assert annotator.binding(op.args[tgt_arg]) == tgt_obj @@ -175,7 +174,7 @@ getbookkeeper().count("coerce", obj1, obj2) return pair(obj1, obj2).union() # reasonable enough - # approximation of an annotation intersection, the result should be the annotation obj or + # approximation of an annotation intersection, the result should be the annotation obj or # the intersection of obj and improvement def improve((obj, improvement)): if not improvement.contains(obj) and obj.contains(improvement): @@ -322,7 +321,7 @@ return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') - + add_knowntypedata(knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): @@ -333,7 +332,7 @@ # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) - if (isinstance(op.args[1], Constant) and + if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: @@ -354,14 +353,14 @@ class __extend__(pairtype(SomeBool, SomeBool)): def union((boo1, boo2)): - s = SomeBool() - if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): - s.const = boo1.const + s = SomeBool() + if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): + s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) s.set_knowntypedata(ktd) - return s + return s def and_((boo1, boo2)): s = SomeBool() @@ -386,13 +385,13 @@ if boo2.const: s.const = True return s - + def xor((boo1, boo2)): s = SomeBool() if boo1.is_constant() and boo2.is_constant(): s.const = boo1.const ^ boo2.const return s - + class __extend__(pairtype(SomeString, SomeString)): def union((str1, str2)): @@ -495,7 +494,7 @@ return s_string.__class__() class __extend__(pairtype(SomeFloat, SomeFloat)): - + def union((flt1, flt2)): return SomeFloat() @@ -512,13 +511,13 @@ class __extend__(pairtype(SomeSingleFloat, SomeSingleFloat)): - + def union((flt1, flt2)): return SomeSingleFloat() class __extend__(pairtype(SomeLongFloat, SomeLongFloat)): - + def union((flt1, flt2)): return SomeLongFloat() @@ -610,7 +609,7 @@ class __extend__(pairtype(SomeTuple, SomeInteger)): - + def getitem((tup1, int2)): if int2.is_immutable_constant(): try: @@ -624,7 +623,7 @@ class __extend__(pairtype(SomeList, SomeInteger)): - + def mul((lst1, int2)): return lst1.listdef.offspring() @@ -643,27 +642,27 @@ getitem_idx_key = getitem_idx def setitem((lst1, int2), s_value): - getbookkeeper().count("list_setitem", int2) + getbookkeeper().count("list_setitem", int2) lst1.listdef.mutate() lst1.listdef.generalize(s_value) setitem.can_only_throw = [IndexError] def delitem((lst1, int2)): - getbookkeeper().count("list_delitem", int2) + getbookkeeper().count("list_delitem", int2) lst1.listdef.resize() delitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] @@ -675,14 +674,14 @@ class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem_idx.can_only_throw = [IndexError] @@ -694,7 +693,7 @@ class __extend__(pairtype(SomeInteger, SomeString), pairtype(SomeInteger, SomeUnicodeString)): - + def mul((int1, str2)): # xxx do we want to support this getbookkeeper().count("str_mul", str2, int1) return str2.basestringclass() @@ -714,7 +713,7 @@ return result class __extend__(pairtype(SomeInteger, SomeList)): - + def mul((int1, lst2)): return lst2.listdef.offspring() @@ -787,7 +786,7 @@ class __extend__(pairtype(SomePBC, SomePBC)): - def union((pbc1, pbc2)): + def union((pbc1, pbc2)): d = pbc1.descriptions.copy() d.update(pbc2.descriptions) return SomePBC(d, can_be_None = pbc1.can_be_None or pbc2.can_be_None) @@ -804,20 +803,6 @@ s.const = False # no common desc in the two sets return s -class __extend__(pairtype(SomeGenericCallable, SomePBC)): - def union((gencall, pbc)): - for desc in pbc.descriptions: - unique_key = desc - bk = desc.bookkeeper - s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unionof(s_result, gencall.s_result) - assert gencall.s_result.contains(s_result) - return gencall - -class __extend__(pairtype(SomePBC, SomeGenericCallable)): - def union((pbc, gencall)): - return pair(gencall, pbc).union() - class __extend__(pairtype(SomeImpossibleValue, SomeObject)): def union((imp1, obj2)): return obj2 @@ -854,7 +839,6 @@ _make_none_union('SomeUnicodeString', 'can_be_None=True') _make_none_union('SomeList', 'obj.listdef') _make_none_union('SomeDict', 'obj.dictdef') -_make_none_union('SomeExternalObject', 'obj.knowntype') _make_none_union('SomeWeakRef', 'obj.classdef') # getitem on SomePBCs, in particular None fails @@ -881,12 +865,6 @@ raise AnnotatorError('add on %r' % pbc) return s_ImpossibleValue -class __extend__(pairtype(SomeExternalObject, SomeExternalObject)): - def union((ext1, ext2)): - if ext1.knowntype == ext2.knowntype: - return SomeExternalObject(ext1.knowntype) - return SomeObject() - # ____________________________________________________________ # annotation of low-level types from rpython.annotator.model import SomePtr, SomeOOInstance, SomeOOClass diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -426,8 +426,8 @@ elif ishashable(x) and x in BUILTIN_ANALYZERS: _module = getattr(x,"__module__","unknown") result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__)) - elif extregistry.is_registered(x, self.policy): - entry = extregistry.lookup(x, self.policy) + elif extregistry.is_registered(x): + entry = extregistry.lookup(x) result = entry.compute_annotation_bk(self) elif isinstance(x, lltype._ptr): result = SomePtr(lltype.typeOf(x)) diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -83,7 +83,7 @@ def fmt_knowntype(self, t): return t.__name__ - + def contains(self, other): if self == other: return True @@ -452,16 +452,6 @@ else: return kt.__name__ -class SomeGenericCallable(SomeObject): - """ Stands for external callable with known signature - """ - def __init__(self, args, result): - self.args_s = args - self.s_result = result - - def can_be_None(self): - return True - class SomeBuiltin(SomeObject): "Stands for a built-in function or method with special-cased analysis." knowntype = BuiltinFunctionType # == BuiltinMethodType @@ -485,16 +475,6 @@ """ knowntype = MethodType -class SomeExternalObject(SomeObject): - """Stands for an object of 'external' type. External types have a Repr - controlled by rpython.rtyper.extregistry.""" - - def __init__(self, knowntype): - self.knowntype = knowntype - - def can_be_none(self): - return True - class SomeImpossibleValue(SomeObject): """The empty set. Instances are placeholders for objects that will never show up at run-time, e.g. elements of an empty list.""" @@ -571,7 +551,7 @@ immutable = True def __init__(self, ll_ptrtype, func): self.ll_ptrtype = ll_ptrtype - self.func = func + self.func = func def can_be_none(self): return False @@ -681,7 +661,7 @@ T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets) return SomeInteriorPtr(T) return lltype_to_annotation(lltype.typeOf(v)) - + # ____________________________________________________________ class UnionError(Exception): @@ -732,14 +712,14 @@ def commonbase(cls1, cls2): # XXX single inheritance only XXX hum l1 = inspect.getmro(cls1) - l2 = inspect.getmro(cls2) - if l1[-1] != object: - l1 = l1 + (object,) - if l2[-1] != object: - l2 = l2 + (object,) - for x in l1: - if x in l2: - return x + l2 = inspect.getmro(cls2) + if l1[-1] != object: + l1 = l1 + (object,) + if l2[-1] != object: + l2 = l2 + (object,) + for x in l1: + if x in l2: + return x assert 0, "couldn't get to commonbase of %r and %r" % (cls1, cls2) def missing_operation(cls, name): diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -82,8 +82,8 @@ return SomeUnicodeString() elif t is types.NoneType: return s_None - elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): - entry = extregistry.lookup_type(t, bookkeeper.policy) + elif bookkeeper and extregistry.is_registered_type(t): + entry = extregistry.lookup_type(t) return entry.compute_annotation_bk(bookkeeper) elif t is type: return SomeType() @@ -97,7 +97,7 @@ def __init__(self, *argtypes): self.argtypes = argtypes - + def __call__(self, funcdesc, inputcells): from rpython.rtyper.lltypesystem import lltype args_s = [] 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 @@ -3033,33 +3033,6 @@ s = a.build_types(fun, []) assert s.const == 0 - def test_some_generic_function_call(self): - def h(x): - return int(x) - - def c(x): - return int(x) - - def g(a, x): - if x == -1: - a = None - if x < 0: - if x == -1: - a = h - else: - a = c - x = x + .01 - return a(x) - - #def fun(x): - - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) - s = a.build_types(g, [annmodel.SomeGenericCallable( - args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), - annmodel.SomeFloat()]) - assert isinstance(s, annmodel.SomeInteger) - assert not hasattr(s, 'const') - def test_compare_int_bool(self): def fun(x): return 50 < x diff --git a/rpython/annotator/test/test_signature.py b/rpython/annotator/test/test_signature.py --- a/rpython/annotator/test/test_signature.py +++ b/rpython/annotator/test/test_signature.py @@ -6,10 +6,3 @@ assert _annotation_key({str:(str, [str])}) == ('dict', (str, (str, ('list', str)))) for i in ([[str]], [str], (int, int, {str: [str]})): assert hash(_annotation_key(i)) - -def test_genericcallable(): - py.test.skip("this two annotations should be equal - fix!") - from rpython.rtyper.extfunc import genericcallable - s1 = annotation([genericcallable([str], int)]) - s2 = annotation([genericcallable([str], int)]) - assert s1 == s2 diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -9,10 +9,10 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ + SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ - SomeGenericCallable, SomeWeakRef, SomeUnicodeString + SomeWeakRef, SomeUnicodeString from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import builtin from rpython.annotator.binaryop import _clone ## XXX where to put this? @@ -358,7 +358,7 @@ s_value = dct.dictdef.read_value() return (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)) - + def len(dct): if dct._is_empty(): return immutablevalue(0) @@ -751,34 +751,6 @@ else: return SomeObject() # len() on a pbc? no chance -class __extend__(SomeGenericCallable): - def call(self, args): - bookkeeper = getbookkeeper() - for arg, expected in zip(args.unpack()[0], self.args_s): - assert expected.contains(arg) - - return self.s_result - -class __extend__(SomeExternalObject): - def getattr(p, s_attr): - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - s_value = entry.get_field_annotation(p.knowntype, attr) - return s_value - else: - return SomeObject() - getattr.can_only_throw = [] - - def setattr(p, s_attr, s_value): - assert s_attr.is_constant() - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - entry.set_field_annotation(p.knowntype, attr, s_value) - - def is_true(p): - return s_Bool - # annotation of low-level types from rpython.annotator.model import SomePtr, SomeLLADTMeth from rpython.annotator.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth @@ -845,7 +817,7 @@ return SomeOOBoundMeth(r.ootype, s_attr.const) return ll_to_annotation(v) - def setattr(r, s_attr, s_value): + def setattr(r, s_attr, s_value): assert s_attr.is_constant(), "setattr on ref %r with non-constant field-name" % r.ootype v = annotation_to_lltype(s_value) example = r.ootype._example() diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py --- a/rpython/rtyper/extfunc.py +++ b/rpython/rtyper/extfunc.py @@ -125,23 +125,6 @@ def _freeze_(self): return True -class genericcallable(object): - """ A way to specify the callable annotation, but deferred until - we have bookkeeper - """ - def __init__(self, args, result=None): - self.args = args - self.result = result - -class _ext_callable(ExtRegistryEntry): - _type_ = genericcallable - # we defer a bit annotation here - - def compute_result_annotation(self): - return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper) - for i in self.instance.args], - annotation(self.instance.result, self.bookkeeper)) - class ExtFuncEntry(ExtRegistryEntry): safe_not_sandboxed = False @@ -249,7 +232,7 @@ llfakeimpl, oofakeimpl: optional; if provided, they are called by the llinterpreter sandboxsafe: use True if the function performs no I/O (safe for --sandbox) """ - + if export_name is None: export_name = function.__name__ diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -22,17 +22,9 @@ for k in key: selfcls._register(dict, k) else: - for basecls in selfcls.__mro__: - if '_condition_' in basecls.__dict__: - cond = basecls.__dict__['_condition_'] - break - else: - cond = None - try: - family = dict[key] - except KeyError: - family = dict[key] = ClassFamily() - family.add(selfcls, cond) + if key in dict: + raise ValueError("duplicate extregistry entry %r" % (selfcls,)) + dict[key] = selfcls def _register_value(selfcls, key): selfcls._register(EXT_REGISTRY_BY_VALUE, key) @@ -43,32 +35,6 @@ def _register_metatype(selfcls, key): selfcls._register(EXT_REGISTRY_BY_METATYPE, key) -class ClassFamily(object): - - def __init__(self): - self.default = None - self.conditionals = [] - - def add(self, cls, cond=None): - if cond is None: - assert self.default is None, ( - "duplicate extregistry entry %r" % (cls,)) - self.default = cls - else: - self.conditionals.append((cls, cond)) - - def match(self, config): - if config is not None: - matches = [cls for cls, cond in self.conditionals - if cond(config)] - if matches: - assert len(matches) == 1, ( - "multiple extregistry matches: %r" % (matches,)) - return matches[0] - if self.default: - return self.default - raise KeyError("no default extregistry entry") - class ExtRegistryEntry(object): __metaclass__ = AutoRegisteringType @@ -159,36 +125,36 @@ # ____________________________________________________________ # Public interface to access the registry -def _lookup_type_cls(tp, config): +def _lookup_type_cls(tp): try: - return EXT_REGISTRY_BY_TYPE[tp].match(config) + return EXT_REGISTRY_BY_TYPE[tp] except (KeyError, TypeError): - return EXT_REGISTRY_BY_METATYPE[type(tp)].match(config) + return EXT_REGISTRY_BY_METATYPE[type(tp)] -def lookup_type(tp, config=None): - Entry = _lookup_type_cls(tp, config) +def lookup_type(tp): + Entry = _lookup_type_cls(tp) return Entry(tp) -def is_registered_type(tp, config=None): +def is_registered_type(tp): try: - _lookup_type_cls(tp, config) + _lookup_type_cls(tp) except KeyError: return False return True -def _lookup_cls(instance, config): +def _lookup_cls(instance): try: - return EXT_REGISTRY_BY_VALUE[instance].match(config) + return EXT_REGISTRY_BY_VALUE[instance] except (KeyError, TypeError): - return _lookup_type_cls(type(instance), config) + return _lookup_type_cls(type(instance)) -def lookup(instance, config=None): - Entry = _lookup_cls(instance, config) +def lookup(instance): + Entry = _lookup_cls(instance) return Entry(type(instance), instance) -def is_registered(instance, config=None): +def is_registered(instance): try: - _lookup_cls(instance, config) + _lookup_cls(instance) except KeyError: return False return True diff --git a/rpython/rtyper/lltypesystem/rgeneric.py b/rpython/rtyper/lltypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/lltypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.lltypesystem.lltype import Ptr, FuncType - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return Ptr(FuncType(l_args, l_retval)) diff --git a/rpython/rtyper/ootypesystem/rgeneric.py b/rpython/rtyper/ootypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/ootypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.ootypesystem import ootype - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return ootype.StaticMethod(l_args, l_retval) diff --git a/rpython/rtyper/rexternalobj.py b/rpython/rtyper/rexternalobj.py deleted file mode 100644 --- a/rpython/rtyper/rexternalobj.py +++ /dev/null @@ -1,21 +0,0 @@ -from rpython.annotator import model as annmodel -from rpython.rtyper import extregistry -from rpython.rtyper.lltypesystem import lltype - -# ExternalObjects - - -class __extend__(annmodel.SomeExternalObject): - def rtyper_makerepr(self, rtyper): - # delegate to the get_repr() of the extregistrered Entry class - entry = extregistry.lookup_type(self.knowntype) - return entry.get_repr(rtyper, self) - - def rtyper_makekey(self): - # grab all attributes of the SomeExternalObject for the key - attrs = lltype.frozendict(self.__dict__) - if 'const' in attrs: - del attrs['const'] - if 'const_box' in attrs: - del attrs['const_box'] - return self.__class__, attrs diff --git a/rpython/rtyper/rgeneric.py b/rpython/rtyper/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/rgeneric.py +++ /dev/null @@ -1,56 +0,0 @@ -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.rmodel import Repr -from rpython.rtyper.rpbc import AbstractFunctionsPBCRepr -from rpython.tool.pairtype import pairtype - - -class AbstractGenericCallableRepr(Repr): - def __init__(self, rtyper, s_generic): - self.rtyper = rtyper - self.s_generic = s_generic - self.args_r = [self.rtyper.getrepr(arg) for arg in s_generic.args_s] - self.r_result = self.rtyper.getrepr(s_generic.s_result) - self.lowleveltype = self.create_low_leveltype() - - def rtype_simple_call(self, hop): - return self.call('simple_call', hop) - - def rtype_call_args(self, hop): - return self.call('call_args', hop) - - def call(self, opname, hop): - vlist = hop.inputargs(self, *self.args_r) + [hop.inputconst(lltype.Void, None)] - hop.exception_is_here() - v_result = hop.genop('indirect_call', vlist, resulttype=self.r_result) - return v_result - - def convert_const(self, value): - bookkeeper = self.rtyper.annotator.bookkeeper - if value is None: - return self.rtyper.type_system.null_callable(self.lowleveltype) - r_func = self.rtyper.getrepr(bookkeeper.immutablevalue(value)) - return r_func.get_unique_llfn().value - - def _setup_repr(self): - for r in self.args_r: - r.setup() - self.r_result.setup() - -class __extend__(annmodel.SomeGenericCallable): - def rtyper_makerepr(self, rtyper): - return rtyper.type_system.rgeneric.GenericCallableRepr(rtyper, self) - - def rtyper_makekey(self): - return self.__class__, tuple([i.rtyper_makekey() for i in self.args_s]),\ - self.s_result.rtyper_makekey() - -class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractGenericCallableRepr)): - def convert_from_to((pbcrepr, gencallrepr), v, llops): - if pbcrepr.lowleveltype is lltype.Void: - r = gencallrepr.convert_const(pbcrepr.s_pbc.const) - r.setup() - return r - if pbcrepr.lowleveltype == gencallrepr.lowleveltype: - return v - return NotImplemented diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -1012,9 +1012,7 @@ from rpython.rtyper import rrange from rpython.rtyper import rstr, rdict, rlist, rbytearray from rpython.rtyper import rclass, rbuiltin, rpbc -from rpython.rtyper import rexternalobj from rpython.rtyper import rptr -from rpython.rtyper import rgeneric from rpython.rtyper import rweakref from rpython.rtyper import raddress # memory addresses from rpython.rtyper.ootypesystem import rootype diff --git a/rpython/rtyper/test/test_extfunc.py b/rpython/rtyper/test/test_extfunc.py --- a/rpython/rtyper/test/test_extfunc.py +++ b/rpython/rtyper/test/test_extfunc.py @@ -58,32 +58,6 @@ res = interpret(f, []) assert res == 7 - def test_callback(self): - """ - Verify annotation when a callback function is in the arguments list. - """ - def d(y): - return eval("y()") - - class DTestFuncEntry(ExtFuncEntry): - _about_ = d - name = 'd' - signature_args = [annmodel.SomeGenericCallable(args=[], result= - annmodel.SomeFloat())] - signature_result = annmodel.SomeFloat() - - def callback(): - return 2.5 - - def f(): - return d(callback) - - policy = AnnotatorPolicy() - a = RPythonAnnotator(policy=policy) - s = a.build_types(f, []) - assert isinstance(s, annmodel.SomeFloat) - assert a.translator._graphof(callback) - def test_register_external_signature(self): """ Test the standard interface for external functions. @@ -198,5 +172,5 @@ return os_execve(l) py.test.raises(Exception, a.build_types, g, [[str]]) a.build_types(g, [[str0]]) # Does not raise - + diff --git a/rpython/rtyper/test/test_extregistry.py b/rpython/rtyper/test/test_extregistry.py --- a/rpython/rtyper/test/test_extregistry.py +++ b/rpython/rtyper/test/test_extregistry.py @@ -9,7 +9,7 @@ from rpython.rtyper.test.test_llinterp import interpret from rpython.rtyper.rmodel import Repr -def dummy(): +def dummy(): raiseNameError class Entry(ExtRegistryEntry): @@ -20,7 +20,7 @@ def func(): x = dummy() return x - + a = RPythonAnnotator() s = a.build_types(func, []) assert isinstance(s, annmodel.SomeInteger) @@ -38,20 +38,20 @@ def func(): x = dummy2() return x - + a = RPythonAnnotator() s = a.build_types(func, []) assert isinstance(s, annmodel.SomeInteger) - + def test_register_type_with_callable(): class DummyType(object): pass - + dummy_type = DummyType() - + def func(): return dummy_type - + class Entry(ExtRegistryEntry): _type_ = DummyType def compute_annotation(self): @@ -65,15 +65,15 @@ def test_register_metatype(): class MetaType(type): pass - + class RealClass(object): __metaclass__ = MetaType - + real_class = RealClass() - + def func(): return real_class - + class Entry(ExtRegistryEntry): _metatype_ = MetaType def compute_annotation(self): @@ -88,13 +88,13 @@ def test_register_metatype_2(): class MetaType(type): pass - + class RealClass(object): __metaclass__ = MetaType - + def func(real_class): return real_class - + class Entry(ExtRegistryEntry): _metatype_ = MetaType def compute_annotation(self): @@ -119,7 +119,7 @@ def func(): return dummy_func() - + res = interpret(func, []) assert res == 42 @@ -127,18 +127,18 @@ def test_register_type_with_get_repr(): class DummyClass(object): pass - + class SomeDummyObject(annmodel.SomeObject): def rtyper_makerepr(self, rtyper): entry = extregistry.lookup_type(self.knowntype) return entry.get_repr(rtyper, self) - + def rtyper_makekey( self ): return self.__class__, self.knowntype class DummyRepr(Repr): lowleveltype = lltype.Signed - + def convert_const(self, value): return 42 @@ -155,14 +155,14 @@ return DummyRepr() dummy_class = DummyClass() - + def func(): return dummy_class - + res = interpret(func, []) - + assert res == 42 - + def test_register_unhashable(): lst1 = [5, 6] lst2 = [5, 6] @@ -178,26 +178,3 @@ _about_ = n1 assert isinstance(extregistry.lookup(n1), Entry) assert isinstance(extregistry.lookup(n2), Entry) - -def test_condition(): - stuff = object() - class Entry(ExtRegistryEntry): - _about_ = stuff - _condition_ = lambda n: n == 'yes' - assert isinstance(extregistry.lookup(stuff, 'yes'), Entry) - py.test.raises(KeyError, "extregistry.lookup(stuff, 'no')") - py.test.raises(KeyError, "extregistry.lookup(stuff)") - - class Entry2(ExtRegistryEntry): - _about_ = stuff - assert isinstance(extregistry.lookup(stuff, 'yes'), Entry) - assert isinstance(extregistry.lookup(stuff, 'no'), Entry2) - assert isinstance(extregistry.lookup(stuff), Entry2) - - otherstuff = object() - class Entry3(Entry): - _about_ = otherstuff - # _condition_ is inherited from Entry - assert isinstance(extregistry.lookup(otherstuff, 'yes'), Entry3) - py.test.raises(KeyError, "extregistry.lookup(otherstuff, 'no')") - py.test.raises(KeyError, "extregistry.lookup(otherstuff)") diff --git a/rpython/rtyper/test/test_rgeneric.py b/rpython/rtyper/test/test_rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/test/test_rgeneric.py +++ /dev/null @@ -1,47 +0,0 @@ -from rpython.rtyper.rtyper import RPythonTyper -from rpython.annotator import model as annmodel -from rpython.annotator.annrpython import RPythonAnnotator -from rpython.annotator import policy -from rpython.rtyper.test.test_llinterp import interpret, interpret_raises - -import py -from rpython.rtyper.test.tool import LLRtypeMixin, OORtypeMixin - -class BaseRGenericTest: - def test_some_generic_function_call(self): - def h(x): - return int(x) - - def c(x): - return int(x) + 1 - - def default(x): - return int(x) + 3 - - def g(a, x): - if x == -1: - a = None - if x > 0: - if x == 1: - a = h - else: - a = c - x = x + 0.01 - return a(x) - - def f(x): - return g(default, x) - - g._annenforceargs_ = policy.Sig(annmodel.SomeGenericCallable( - args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), - float) - - assert interpret(f, [1.]) == 1 - assert interpret(f, [10.]) == 11 - assert interpret(f, [-3.]) == 0 - -class TestLLRgeneric(BaseRGenericTest, LLRtypeMixin): - pass - -class TestOORgeneric(BaseRGenericTest, OORtypeMixin): - pass diff --git a/rpython/rtyper/typesystem.py b/rpython/rtyper/typesystem.py --- a/rpython/rtyper/typesystem.py +++ b/rpython/rtyper/typesystem.py @@ -21,7 +21,7 @@ except ImportError: return None if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist', - 'rslice', 'rdict', 'rrange', 'rstr', 'rgeneric', + 'rslice', 'rdict', 'rrange', 'rstr', 'll_str', 'rbuilder', 'rvirtualizable2', 'rbytearray', 'exceptiondata'): mod = load(name) @@ -50,7 +50,7 @@ def getcallabletype(self, ARGS, RESTYPE): cls = self.callable_trait[0] return cls(ARGS, RESTYPE) - + def getcallable(self, graph, getconcretetype=None): """Return callable given a Python function.""" if getconcretetype is None: @@ -59,7 +59,7 @@ lloutput = getconcretetype(graph.getreturnvar()) typ, constr = self.callable_trait - + FT = typ(llinputs, lloutput) name = graph.name if hasattr(graph, 'func') and callable(graph.func): @@ -138,7 +138,7 @@ if robj1.lowleveltype != robj2.lowleveltype: raise TyperError('is of instances of different pointer types: %r, %r' % ( roriginal1, roriginal2)) - + v_list = hop.inputargs(robj1, robj2) return hop.genop('ptr_eq', v_list, resulttype=lltype.Bool) @@ -177,7 +177,7 @@ robj2.lowleveltype is not ootype.Class): raise TyperError('is of instances of the non-instances: %r, %r' % ( roriginal1, roriginal2)) - + v_list = hop.inputargs(robj1, robj2) return hop.genop('oois', v_list, resulttype=lltype.Bool) From noreply at buildbot.pypy.org Fri Mar 22 06:03:36 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 06:03:36 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: fixes and a new gateway interface Message-ID: <20130322050336.7A67C1C04AB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62638:eb3fc80f13e9 Date: 2013-03-21 22:03 -0700 http://bitbucket.org/pypy/pypy/changeset/eb3fc80f13e9/ Log: fixes and a new gateway interface diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -4,12 +4,15 @@ * BuiltinCode (call interp-level code from app-level) * app2interp (embed an app-level function into an interp-level callable) * interp2app (publish an interp-level object to be visible from app-level) +* interpindirect2app (publish an interp-level object to be visible from + app-level as an indirect call to implementation) """ import sys import os import types +import inspect import py @@ -794,6 +797,29 @@ w_result = space.w_None return w_result +def interpindirect2app(unbound_meth, unwrap_spec=None): + base_cls = unbound_meth.im_class + func = unbound_meth.im_func + args = inspect.getargs(func.func_code) + if args.varargs or args.keywords: + raise TypeError("Varargs and keywords not supported in unwrap_spec") + assert not func.func_defaults + argspec = ', '.join([arg for arg in args.args[1:]]) + func_code = py.code.Source(""" + def f(w_obj, %(args)s): + return w_obj.%(func_name)s(%(args)s) + """ % {'args': argspec, 'func_name': func.func_name}) + d = {} + exec func_code.compile() in d + f = d['f'] + f.func_name = func.func_name + if unwrap_spec is None: + unwrap_spec = {} + else: + assert isinstance(unwrap_spec, dict) + unwrap_spec = unwrap_spec.copy() + unwrap_spec['w_obj'] = base_cls + return interp2app(globals()['unwrap_spec'](**unwrap_spec)(f)) class interp2app(W_Root): """Build a gateway that calls 'f' at interp-level.""" 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 @@ -129,6 +129,36 @@ space.call_function(w_app_g3, w('foo'), w('bar')), w('foobar')) + def test_interpindirect2app(self): + space = self.space + class BaseA(W_Root): + def method(self, space, x): + pass + + class A(BaseA): + def method(self, space, x): + return space.wrap(x + 2) + + class B(BaseA): + def method(self, space, x): + return space.wrap(x + 1) + + class FakeTypeDef(object): + rawdict = {} + bases = {} + applevel_subclasses_base = None + name = 'foo' + hasdict = False + weakrefable = False + doc = 'xyz' + + meth = gateway.interpindirect2app(BaseA.method, {'x': int}) + w_c = space.wrap(meth) + w_a = A() + w_b = B() + assert space.int_w(space.call_function(w_c, w_a, space.wrap(1))) == 1 + 2 + assert space.int_w(space.call_function(w_c, w_b, space.wrap(-10))) == -10 + 1 + def test_interp2app_unwrap_spec(self): space = self.space w = space.wrap diff --git a/pypy/objspace/std/transparent.py b/pypy/objspace/std/transparent.py --- a/pypy/objspace/std/transparent.py +++ b/pypy/objspace/std/transparent.py @@ -73,8 +73,8 @@ None.""" if isinstance(w_object, W_Transparent): return w_object.w_controller - if isinstance(w_object, W_TransparentObject): - return w_object.w_controller + #if isinstance(w_object, W_TransparentObject): + # return w_object.w_controller return None app_proxy = gateway.interp2app(proxy) From noreply at buildbot.pypy.org Fri Mar 22 06:04:44 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 06:04:44 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): removed annenforce args from rlist, also contains fix to rtypes Message-ID: <20130322050444.55D6E1C04AB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62639:4b1033320d32 Date: 2013-03-21 22:04 -0700 http://bitbucket.org/pypy/pypy/changeset/4b1033320d32/ Log: (alex, fijal): removed annenforce args from rlist, also contains fix to rtypes diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -178,13 +178,11 @@ # a graph that has already been rtyped. Safety-check the new # annotations that are passed in, and don't annotate the old # graph -- it's already low-level operations! - for a, s_newarg in zip(graph.getargs(), cells): + for a, s_newarg in zip(block.inputargs, cells): s_oldarg = self.binding(a) assert annmodel.unionof(s_oldarg, s_newarg) == s_oldarg else: assert not self.frozen - for a in cells: - assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: self.bindinputargs(graph, block, cells) else: diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -598,7 +598,7 @@ return result return decorate - + def clone(self): assert self.inline_jit_merge_point, 'JitDriver.clone works only after @inline' @@ -844,7 +844,7 @@ assert s_name.is_constant() if s_name.const == 'enable_opts': assert annmodel.SomeString(can_be_None=True).contains(s_value) - else: + else: assert (s_value == annmodel.s_None or annmodel.SomeInteger().contains(s_value)) return annmodel.s_None @@ -876,7 +876,7 @@ class AsmInfo(object): """ An addition to JitDebugInfo concerning assembler. Attributes: - + ops_offset - dict of offsets of operations or None asmaddr - (int) raw address of assembler block asmlen - assembler block length @@ -986,7 +986,7 @@ def specialize_call(self, hop): from rpython.rtyper.lltypesystem import rclass, lltype - + classrepr = rclass.get_type_repr(hop.rtyper) hop.exception_cannot_occur() diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py --- a/rpython/rtyper/rlist.py +++ b/rpython/rtyper/rlist.py @@ -1,16 +1,18 @@ -from rpython.tool.pairtype import pairtype, pair +from rpython.annotator import model as annmodel from rpython.flowspace.model import Constant -from rpython.annotator import model as annmodel +from rpython.rlib import rgc, jit, types +from rpython.rlib.debug import ll_assert +from rpython.rlib.objectmodel import malloc_zero_filled +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import ovfcheck, widen, r_uint, intmask +from rpython.rtyper.annlowlevel import ADTInterface from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import typeOf, Ptr, Void, Signed, Bool +from rpython.rtyper.lltypesystem.lltype import nullptr, Char, UniChar, Number from rpython.rtyper.rmodel import Repr, IteratorRepr, IntegerRepr from rpython.rtyper.rstr import AbstractStringRepr, AbstractCharRepr -from rpython.rtyper.lltypesystem.lltype import typeOf, Ptr, Void, Signed, Bool -from rpython.rtyper.lltypesystem.lltype import nullptr, Char, UniChar, Number -from rpython.rlib.objectmodel import malloc_zero_filled -from rpython.rlib.debug import ll_assert -from rpython.rlib.rarithmetic import ovfcheck, widen, r_uint, intmask -from rpython.rtyper.annlowlevel import ADTInterface -from rpython.rlib import rgc, jit +from rpython.tool.pairtype import pairtype, pair + ADTIFixedList = ADTInterface(None, { 'll_newlist': (['SELF', Signed ], 'self'), @@ -521,6 +523,7 @@ return LIST.ITEM + at signature(types.any(), types.any(), types.int(), types.int(), types.int(), returns=types.none()) def ll_arraycopy(source, dest, source_start, dest_start, length): SRCTYPE = typeOf(source) if isinstance(SRCTYPE, Ptr): @@ -534,8 +537,7 @@ item = source.ll_getitem_fast(source_start + i) dest.ll_setitem_fast(dest_start + i, item) i += 1 -ll_arraycopy._annenforceargs_ = [None, None, int, int, int] -# no oopspec -- the function is inlined by the JIT + def ll_copy(RESLIST, l): length = l.ll_length() @@ -873,8 +875,9 @@ while j < newlength: lst.ll_setitem_fast(j, char) j += 1 -# not inlined by the JIT -- contains a loop + + at signature(types.any(), types.any(), types.int(), returns=types.any()) def ll_listslice_startonly(RESLIST, l1, start): len1 = l1.ll_length() ll_assert(start >= 0, "unexpectedly negative list slice start") @@ -883,8 +886,7 @@ l = RESLIST.ll_newlist(newlength) ll_arraycopy(l1, l, start, 0, newlength) return l -ll_listslice_startonly._annenforceargs_ = (None, None, int) -# no oopspec -- the function is inlined by the JIT + def ll_listslice_startstop(RESLIST, l1, start, stop): length = l1.ll_length() diff --git a/rpython/tool/sourcetools.py b/rpython/tool/sourcetools.py --- a/rpython/tool/sourcetools.py +++ b/rpython/tool/sourcetools.py @@ -272,7 +272,7 @@ def rpython_wrapper(f, template, templateargs=None, **globaldict): - """ + """ We cannot simply wrap the function using *args, **kwds, because it's not RPython. Instead, we generate a function from ``template`` with exactly the same argument list. @@ -280,8 +280,8 @@ if templateargs is None: templateargs = {} srcargs, srcvarargs, srckeywords, defaults = inspect.getargspec(f) - assert not srcvarargs, '*args not supported by enforceargs' - assert not srckeywords, '**kwargs not supported by enforceargs' + assert not srcvarargs, '*args not supported by rpython_wrapper' + assert not srckeywords, '**kwargs not supported by rpython_wrapper' # arglist = ', '.join(srcargs) templateargs.update(name=f.func_name, From noreply at buildbot.pypy.org Fri Mar 22 06:09:29 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 06:09:29 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal) removed usage of annenforceargs from ootype.py Message-ID: <20130322050929.B0BED1C0171@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62640:f04b6c364ed0 Date: 2013-03-21 22:09 -0700 http://bitbucket.org/pypy/pypy/changeset/f04b6c364ed0/ Log: (alex, fijal) removed usage of annenforceargs from ootype.py diff --git a/rpython/rtyper/ootypesystem/ootype.py b/rpython/rtyper/ootypesystem/ootype.py --- a/rpython/rtyper/ootypesystem/ootype.py +++ b/rpython/rtyper/ootypesystem/ootype.py @@ -1,12 +1,12 @@ import py -from py.builtin import set -from rpython.rtyper.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char -from rpython.rtyper.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \ - Primitive, isCompatibleType, enforce, saferecursive, SignedLongLong, UnsignedLongLong -from rpython.rtyper.lltypesystem.lltype import frozendict -from rpython.rtyper.lltypesystem.lltype import identityhash + +from rpython.rlib import objectmodel, types +from rpython.rlib.signature import signature from rpython.rlib.rarithmetic import intmask -from rpython.rlib import objectmodel +from rpython.rtyper.lltypesystem.lltype import (LowLevelType, Signed, Unsigned, + Float, Char, Bool, Void, UniChar, typeOf, Primitive, isCompatibleType, + enforce, saferecursive, SignedLongLong, UnsignedLongLong, frozendict, + identityhash) from rpython.tool.uid import uid @@ -75,7 +75,7 @@ def _example(self): return _class(ROOT) - + Class = Class() class Instance(OOType): @@ -111,7 +111,7 @@ def __hash__(self): return object.__hash__(self) - + def _defl(self): return self._null @@ -153,7 +153,7 @@ _, meth = self._lookup(name) if meth is not None: raise TypeError("Cannot add field %r: method already exists" % name) - + if self._superclass is not None: if self._superclass._has_field(name): raise TypeError("Field %r exists in superclass" % name) @@ -161,7 +161,7 @@ if type(defn) is not tuple: if isinstance(defn, Meth): raise TypeError("Attempting to store method in field") - + fields[name] = (defn, defn._defl()) else: ootype, default = defn @@ -198,7 +198,7 @@ def _init_instance(self, instance): if self._superclass is not None: self._superclass._init_instance(instance) - + for name, (ootype, default) in self._fields.iteritems(): instance.__dict__[name] = enforce(ootype, default) @@ -587,10 +587,10 @@ # this is the equivalent of the lltypesystem ll_newlist that is # marked as typeMethod. + @signature(types.any(), types.int(), returns=types.any()) def ll_newlist(self, length): from rpython.rtyper.ootypesystem import rlist return rlist.ll_newlist(self, length) - ll_newlist._annenforceargs_ = (None, int) # NB: We are expecting Lists of the same ITEMTYPE to compare/hash # equal. We don't redefine __eq__/__hash__ since the implementations @@ -613,7 +613,7 @@ def __hash__(self): if self.ITEM is None: raise TypeError("Can't hash uninitialized List type.") - return BuiltinADTType.__hash__(self) + return BuiltinADTType.__hash__(self) def __str__(self): return '%s(%s)' % (self.__class__.__name__, @@ -625,7 +625,7 @@ def _specialize(self, generic_types): ITEMTYPE = self._specialize_type(self.ITEM, generic_types) return self.__class__(ITEMTYPE) - + def _defl(self): return self._null @@ -644,7 +644,7 @@ # placeholders for types # make sure that each derived class has his own SELFTYPE_T # placeholder, because we want backends to distinguish that. - + SELFTYPE_T = object() ITEMTYPE_T = object() oopspec_name = 'list' @@ -694,7 +694,7 @@ def __hash__(self): if self.ITEM is None: raise TypeError("Can't hash uninitialized List type.") - return BuiltinADTType.__hash__(self) + return BuiltinADTType.__hash__(self) def __str__(self): return '%s(%s)' % (self.__class__.__name__, @@ -717,14 +717,15 @@ self.ITEM = ITEMTYPE self._init_methods() + @signature(types.any(), types.int(), returns=types.any()) def ll_newlist(self, length): from rpython.rtyper.ootypesystem import rlist return rlist.ll_newarray(self, length) - ll_newlist._annenforceargs_ = (None, int) def ll_convert_from_array(self, array): return array + class Dict(BuiltinADTType): # placeholders for types SELFTYPE_T = object() @@ -790,7 +791,7 @@ return False if not self._is_initialized() or not other._is_initialized(): return False # behave like a ForwardReference, i.e. compare by identity - return BuiltinADTType.__eq__(self, other) + return BuiltinADTType.__eq__(self, other) def __ne__(self, other): return not (self == other) @@ -812,7 +813,7 @@ self._KEYTYPE = KEYTYPE self._VALUETYPE = VALUETYPE self._init_methods() - + class CustomDict(Dict): def __init__(self, KEYTYPE=None, VALUETYPE=None): @@ -871,7 +872,7 @@ KEYTYPE = self._specialize_type(self._KEYTYPE, generic_types) VALUETYPE = self._specialize_type(self._VALUETYPE, generic_types) return self.__class__(KEYTYPE, VALUETYPE) - + # ____________________________________________________________ class _object(object): @@ -943,7 +944,7 @@ Class._null = nullruntimeclass class _instance(object): - + def __init__(self, INSTANCE): self.__dict__["_TYPE"] = INSTANCE INSTANCE._init_instance(self) @@ -958,7 +959,7 @@ DEFINST, meth = self._TYPE._lookup(name) if meth is not None: return meth._bound(DEFINST, self) - + self._TYPE._check_field(name) return self.__dict__[name] @@ -998,7 +999,7 @@ return self _enforce = _upcast - + def _downcast(self, INSTANCE): assert instanceof(self, INSTANCE) return self @@ -1023,7 +1024,7 @@ def __getattribute__(self, name): if name.startswith("_"): return object.__getattribute__(self, name) - + raise RuntimeError("Access to field in null object") def __setattr__(self, name, value): @@ -1189,7 +1190,7 @@ def __ne__(self, other): return not (self == other) - + def __hash__(self): return hash(frozendict(self.__dict__)) @@ -1227,7 +1228,7 @@ def __eq__(self, other): return self is other - + def __hash__(self): return id(self) @@ -1251,7 +1252,7 @@ class _meth(_callable): _bound_class = _bound_meth - + def __init__(self, METHOD, **attrs): assert isinstance(METHOD, Meth) _callable.__init__(self, METHOD, **attrs) @@ -1339,7 +1340,7 @@ return True else: return False - + def annotation_to_lltype(cls, ann): from rpython.annotator import model as annmodel return annmodel.annotation_to_lltype(ann) @@ -1605,7 +1606,7 @@ return len(self._list) def _ll_resize_ge(self, length): - # NOT_RPYTHON + # NOT_RPYTHON if len(self._list) < length: diff = length - len(self._list) self._list += [self._TYPE.ITEM._defl()] * diff @@ -1641,7 +1642,7 @@ class _null_list(_null_mixin(_list), _list): def __init__(self, LIST): - self.__dict__["_TYPE"] = LIST + self.__dict__["_TYPE"] = LIST class _array(_builtin_type): def __init__(self, ARRAY, length): @@ -1674,7 +1675,7 @@ class _null_array(_null_mixin(_array), _array): def __init__(self, ARRAY): - self.__dict__["_TYPE"] = ARRAY + self.__dict__["_TYPE"] = ARRAY class _dict(_builtin_type): def __init__(self, DICT): @@ -1772,7 +1773,7 @@ def ll_go_next(self): # NOT_RPYTHON self._check_stamp() - self._index += 1 + self._index += 1 if self._index >= len(self._items): return False else: @@ -1783,7 +1784,7 @@ self._check_stamp() assert 0 <= self._index < len(self._items) return self._items[self._index][0] - + def ll_current_value(self): # NOT_RPYTHON self._check_stamp() @@ -1843,7 +1844,7 @@ class _null_record(_null_mixin(_record), _record): def __init__(self, RECORD): - self.__dict__["_TYPE"] = RECORD + self.__dict__["_TYPE"] = RECORD def new(TYPE): @@ -1935,7 +1936,7 @@ def ooupcast(INSTANCE, instance): return instance._upcast(INSTANCE) - + def oodowncast(INSTANCE, instance): return instance._downcast(INSTANCE) @@ -1962,7 +1963,7 @@ def oostring(obj, base): """ Convert char, int, float, instances and str to str. - + Base is used only for formatting int: for other types is ignored and should be set to -1. For int only base 8, 10 and 16 are supported. From noreply at buildbot.pypy.org Fri Mar 22 06:15:46 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 06:15:46 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal) fix importing and remove more annenforceargs Message-ID: <20130322051546.5926A1C04AB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62641:af66d7a58e17 Date: 2013-03-21 22:15 -0700 http://bitbucket.org/pypy/pypy/changeset/af66d7a58e17/ Log: (alex, fijal) fix importing and remove more annenforceargs diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -530,7 +530,6 @@ # annotation of low-level types from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.ootypesystem import ootype class SomePtr(SomeObject): knowntype = lltype._ptr @@ -556,27 +555,35 @@ def can_be_none(self): return False + class SomeOOObject(SomeObject): def __init__(self): + from rpython.rtyper.ootypesystem import ootype self.ootype = ootype.Object + class SomeOOClass(SomeObject): def __init__(self, ootype): self.ootype = ootype + class SomeOOInstance(SomeObject): def __init__(self, ootype, can_be_None=False): self.ootype = ootype self.can_be_None = can_be_None + class SomeOOBoundMeth(SomeObject): immutable = True + def __init__(self, ootype, name): self.ootype = ootype self.name = name + class SomeOOStaticMeth(SomeObject): immutable = True + def __init__(self, method): self.method = method @@ -592,6 +599,8 @@ ] def annotation_to_lltype(s_val, info=None): + from rpython.rtyper.ootypesystem import ootype + if isinstance(s_val, SomeOOInstance): return s_val.ootype if isinstance(s_val, SomeOOStaticMeth): @@ -625,6 +634,8 @@ ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map]) def lltype_to_annotation(T): + from rpython.rtyper.ootypesystem import ootype + try: s = ll_to_annotation_map.get(T) except TypeError: @@ -730,7 +741,7 @@ flattened = args for arg in flattened: if arg.__class__ is SomeObject and arg.knowntype is not type: - return SomeObject() + return SomeObject() bookkeeper = rpython.annotator.bookkeeper.getbookkeeper() bookkeeper.warning("no precise annotation supplied for %s%r" % (name, args)) return s_ImpossibleValue diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -1,6 +1,6 @@ -from rpython.rlib import rgc, jit +from rpython.rlib import rgc, jit, types from rpython.rlib.debug import ll_assert -from rpython.rlib.objectmodel import enforceargs +from rpython.rlib.signature import signature from rpython.rtyper.lltypesystem import rstr from rpython.rtyper.lltypesystem.lltype import (GcForwardReference, Ptr, GcArray, GcStruct, Void, Signed, malloc, typeOf, nullptr, typeMethod) @@ -171,7 +171,7 @@ # adapted C code - at enforceargs(None, int, None) + at signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_hint_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements. Note that @@ -227,7 +227,8 @@ if allocated < newsize or newsize < (allocated >> 1) - 5: _ll_list_resize_hint_really(l, newsize, False) - at enforceargs(None, int, None) + + at signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements, and set From noreply at buildbot.pypy.org Fri Mar 22 06:19:32 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 06:19:32 +0100 (CET) Subject: [pypy-commit] pypy default: random whitespace/other cleanup Message-ID: <20130322051933.00B871C0171@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62642:d425c8bf2b7e Date: 2013-03-21 22:19 -0700 http://bitbucket.org/pypy/pypy/changeset/d425c8bf2b7e/ Log: random whitespace/other cleanup diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -29,13 +29,15 @@ from __future__ import absolute_import -from types import BuiltinFunctionType, MethodType, FunctionType +import inspect +import weakref +from types import BuiltinFunctionType, MethodType + import rpython from rpython.tool import descriptor from rpython.tool.pairtype import pair, extendabletype -from rpython.rlib.rarithmetic import r_uint, r_ulonglong, base_int -from rpython.rlib.rarithmetic import r_singlefloat, r_longfloat -import inspect, weakref +from rpython.rlib.rarithmetic import r_uint, base_int, r_singlefloat, r_longfloat + class State(object): # A global attribute :-( Patch it with 'True' to enable checking of @@ -56,8 +58,10 @@ def __eq__(self, other): return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + def __ne__(self, other): return not (self == other) + def __repr__(self): try: reprdict = TLS.reprdict @@ -75,7 +79,7 @@ m = getattr(self, 'fmt_' + k, repr) r = m(v) if r is not None: - args.append('%s=%s'%(k, r)) + args.append('%s=%s' % (k, r)) kwds = ', '.join(args) finally: del reprdict[self] @@ -130,6 +134,7 @@ def can_be_none(self): return False + class SomeFloat(SomeObject): "Stands for a float or an integer." knowntype = float # if we don't know if it's a float or an int, @@ -152,6 +157,7 @@ def can_be_none(self): return False + class SomeSingleFloat(SomeObject): "Stands for an r_singlefloat." # No operation supported, not even union with a regular float @@ -161,6 +167,7 @@ def can_be_none(self): return False + class SomeLongFloat(SomeObject): "Stands for an r_longfloat." # No operation supported, not even union with a regular float @@ -170,9 +177,11 @@ def can_be_none(self): return False + class SomeInteger(SomeFloat): "Stands for an object which is known to be an integer." knowntype = int + # size is in multiples of C's sizeof(long)! def __init__(self, nonneg=False, unsigned=None, knowntype=None): assert (knowntype is None or knowntype is int or @@ -189,25 +198,29 @@ self.nonneg = unsigned or nonneg self.unsigned = unsigned # rpython.rlib.rarithmetic.r_uint + class SomeBool(SomeInteger): "Stands for true or false." knowntype = bool nonneg = True unsigned = False + def __init__(self): pass + def set_knowntypedata(self, knowntypedata): assert not hasattr(self, 'knowntypedata') if knowntypedata: self.knowntypedata = knowntypedata + class SomeStringOrUnicode(SomeObject): """Base class for shared implementation of SomeString and SomeUnicodeString. Cannot be an annotation.""" immutable = True - can_be_None=False + can_be_None = False no_nul = False # No NUL character in the string. def __init__(self, can_be_None=False, no_nul=False): @@ -226,8 +239,10 @@ d1 = self.__dict__ d2 = other.__dict__ if not TLS.check_str_without_nul: - d1 = d1.copy(); d1['no_nul'] = 0 # ignored - d2 = d2.copy(); d2['no_nul'] = 0 # ignored + d1 = d1.copy() + d1['no_nul'] = 0 + d2 = d2.copy() + d2['no_nul'] = 0 return d1 == d2 def nonnoneify(self): @@ -236,27 +251,34 @@ def nonnulify(self): return self.__class__(can_be_None=self.can_be_None, no_nul=True) + class SomeString(SomeStringOrUnicode): "Stands for an object which is known to be a string." knowntype = str + class SomeUnicodeString(SomeStringOrUnicode): "Stands for an object which is known to be an unicode string" knowntype = unicode + class SomeByteArray(SomeStringOrUnicode): knowntype = bytearray + class SomeChar(SomeString): "Stands for an object known to be a string of length 1." can_be_None = False + def __init__(self, no_nul=False): # no 'can_be_None' argument here if no_nul: self.no_nul = True + class SomeUnicodeCodePoint(SomeUnicodeString): "Stands for an object known to be a unicode codepoint." can_be_None = False + def __init__(self, no_nul=False): # no 'can_be_None' argument here if no_nul: self.no_nul = True @@ -266,11 +288,14 @@ SomeUnicodeString.basestringclass = SomeUnicodeString SomeUnicodeString.basecharclass = SomeUnicodeCodePoint + class SomeList(SomeObject): "Stands for a homogenous list of any length." knowntype = list + def __init__(self, listdef): self.listdef = listdef + def __eq__(self, other): if self.__class__ is not other.__class__: return False @@ -285,10 +310,12 @@ def can_be_none(self): return True + class SomeTuple(SomeObject): "Stands for a tuple of known length." knowntype = tuple immutable = True + def __init__(self, items): self.items = tuple(items) # tuple of s_xxx elements for i in items: @@ -300,11 +327,14 @@ def can_be_none(self): return False + class SomeDict(SomeObject): "Stands for a dict." knowntype = dict + def __init__(self, dictdef): self.dictdef = dictdef + def __eq__(self, other): if self.__class__ is not other.__class__: return False @@ -323,12 +353,13 @@ if len(const) < 20: return repr(const) else: - return '{...%s...}'%(len(const),) + return '{...%s...}' % (len(const),) class SomeIterator(SomeObject): "Stands for an iterator returning objects from a given container." knowntype = type(iter([])) # arbitrarily chose seqiter as the type + def __init__(self, s_container, *variant): self.variant = variant self.s_container = s_container @@ -336,6 +367,7 @@ def can_be_none(self): return False + class SomeInstance(SomeObject): "Stands for an instance of a (user-defined) class." @@ -347,11 +379,13 @@ def fmt_knowntype(self, kt): return None + def fmt_classdef(self, cdef): if cdef is None: return 'object' else: return cdef.name + def fmt_flags(self, flags): if flags: return repr(flags) @@ -444,7 +478,7 @@ if hasattr(self, 'const'): return None else: - return '{...%s...}'%(len(pbis),) + return '{...%s...}' % (len(pbis),) def fmt_knowntype(self, kt): if self.is_constant(): @@ -452,6 +486,7 @@ else: return kt.__name__ + class SomeBuiltin(SomeObject): "Stands for a built-in function or method with special-cased analysis." knowntype = BuiltinFunctionType # == BuiltinMethodType @@ -470,16 +505,18 @@ def can_be_none(self): return False + class SomeBuiltinMethod(SomeBuiltin): """ Stands for a built-in method which has got special meaning """ knowntype = MethodType + class SomeImpossibleValue(SomeObject): """The empty set. Instances are placeholders for objects that will never show up at run-time, e.g. elements of an empty list.""" immutable = True - annotationcolor = (160,160,160) + annotationcolor = (160, 160, 160) def can_be_none(self): return False @@ -487,16 +524,18 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() -s_Int = SomeInteger() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) + # ____________________________________________________________ # weakrefs class SomeWeakRef(SomeObject): knowntype = weakref.ReferenceType immutable = True + def __init__(self, classdef): # 'classdef' is None for known-to-be-dead weakrefs. self.classdef = classdef @@ -506,6 +545,7 @@ from rpython.rtyper.lltypesystem import llmemory + class SomeAddress(SomeObject): immutable = True @@ -515,6 +555,7 @@ def is_null_address(self): return self.is_immutable_constant() and not self.const + # The following class is used to annotate the intermediate value that # appears in expressions of the form: # addr.signed[offset] and addr.signed[offset] = value @@ -531,9 +572,11 @@ from rpython.rtyper.lltypesystem import lltype + class SomePtr(SomeObject): knowntype = lltype._ptr immutable = True + def __init__(self, ll_ptrtype): assert isinstance(ll_ptrtype, lltype.Ptr) self.ll_ptrtype = ll_ptrtype @@ -541,13 +584,16 @@ def can_be_none(self): return False + class SomeInteriorPtr(SomePtr): def __init__(self, ll_ptrtype): assert isinstance(ll_ptrtype, lltype.InteriorPtr) self.ll_ptrtype = ll_ptrtype + class SomeLLADTMeth(SomeObject): immutable = True + def __init__(self, ll_ptrtype, func): self.ll_ptrtype = ll_ptrtype self.func = func @@ -598,6 +644,7 @@ (SomeAddress(), llmemory.Address), ] + def annotation_to_lltype(s_val, info=None): from rpython.rtyper.ootypesystem import ootype @@ -633,6 +680,7 @@ ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map]) + def lltype_to_annotation(T): from rpython.rtyper.ootypesystem import ootype @@ -660,6 +708,7 @@ else: return s + def ll_to_annotation(v): if v is None: # i think we can only get here in the case of void-returning @@ -673,12 +722,14 @@ return SomeInteriorPtr(T) return lltype_to_annotation(lltype.typeOf(v)) + # ____________________________________________________________ class UnionError(Exception): """Signals an suspicious attempt at taking the union of deeply incompatible SomeXxx instances.""" + def unionof(*somevalues): "The most precise SomeValue instance that contains all the values." try: @@ -694,12 +745,14 @@ s1 = pair(s1, s2).union() return s1 + # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): for v in vars: ktd[(truth, v)] = s_obj + def merge_knowntypedata(ktd1, ktd2): r = {} for truth_v in ktd1: @@ -707,6 +760,7 @@ r[truth_v] = unionof(ktd1[truth_v], ktd2[truth_v]) return r + def not_const(s_obj): if s_obj.is_constant() and not isinstance(s_obj, SomePBC): new_s_obj = SomeObject.__new__(s_obj.__class__) @@ -718,6 +772,7 @@ s_obj = new_s_obj return s_obj + # ____________________________________________________________ # internal @@ -733,6 +788,7 @@ return x assert 0, "couldn't get to commonbase of %r and %r" % (cls1, cls2) + def missing_operation(cls, name): def default_op(*args): if args and isinstance(args[0], tuple): @@ -747,6 +803,7 @@ return s_ImpossibleValue setattr(cls, name, default_op) + class HarmlesslyBlocked(Exception): """Raised by the unaryop/binaryop to signal a harmless kind of BlockedInference: the current block is blocked, but not in a way From noreply at buildbot.pypy.org Fri Mar 22 06:35:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 06:35:38 +0100 (CET) Subject: [pypy-commit] buildbot default: try on cpython just to see how it goes Message-ID: <20130322053538.C3B711C1497@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r754:14454bbd4ec3 Date: 2013-03-21 22:34 -0700 http://bitbucket.org/pypy/buildbot/changeset/14454bbd4ec3/ Log: try on cpython just to see how it goes diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -102,6 +102,7 @@ translationArgs=jit_translation_args, targetArgs=[], lib_python=True, + interpreter='/usr/bin/python', pypyjit=True, app_tests=True, platform='linux64', From noreply at buildbot.pypy.org Fri Mar 22 06:35:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 06:35:40 +0100 (CET) Subject: [pypy-commit] buildbot default: merge Message-ID: <20130322053540.1F7B81C1497@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r755:ccd87fb0895a Date: 2013-03-21 22:35 -0700 http://bitbucket.org/pypy/buildbot/changeset/ccd87fb0895a/ Log: merge diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -1,11 +1,10 @@ import os.path import datetime import itertools -import re import py import cgi import urllib -from twisted.web import resource +import sys from twisted.web.static import File, DirectoryLister class PyPyTarball(object): @@ -103,25 +102,45 @@ def display_in_italic(self): return self.vcs == 'latest' +class PyPyDirectory(object): + def __init__(self, filePath): + self.filename = filePath.basename() + self.filePath = filePath + self.parse_filename() + + def parse_filename(self): + if self.filename == 'trunk': + self.last_mod_time = sys.maxsize + return + self.last_mod_time = self.filePath.getmtime() + + def key(self): + return (self.last_mod_time) class PyPyList(File): - def listNames(self): - names = File.listNames(self) + def sortBuildNames(self, names): items = map(PyPyTarball, names) items.sort(key=PyPyTarball.key, reverse=True) return [item.filename for item in items] + def sortDirectoryNames(self, filePaths): + items = map(PyPyDirectory, filePaths) + items.sort(key=PyPyDirectory.key, reverse=True) + return [item.filename for item in items] + def directoryListing(self): def is_pypy_dir(names): for name in names: if name.startswith('pypy-c'): return True return False - names = self.listNames() + names = File.listNames(self) if is_pypy_dir(names): + names = self.sortBuildNames(names) Listener = PyPyDirectoryLister else: + names = self.sortDirectoryNames(File.listEntities(self)) Listener = DirectoryLister return Listener(self.path, names, diff --git a/bot2/pypybuildbot/test/test_pypylist.py b/bot2/pypybuildbot/test/test_pypylist.py --- a/bot2/pypybuildbot/test/test_pypylist.py +++ b/bot2/pypybuildbot/test/test_pypylist.py @@ -1,5 +1,5 @@ import py -from pypybuildbot.pypylist import PyPyTarball +from pypybuildbot.pypylist import PyPyTarball, PyPyList def test_pypytarball_svn(): t = PyPyTarball('pypy-c-jit-75654-linux.tar.bz2') @@ -12,6 +12,7 @@ assert t.platform == 'linux' assert t.vcs == 'svn' + def test_pypytarball_hg(): t = PyPyTarball('pypy-c-jit-75654-foo-linux.tar.bz2') assert t.filename == 'pypy-c-jit-75654-foo-linux.tar.bz2' @@ -23,6 +24,7 @@ assert t.platform == 'linux' assert t.vcs == 'hg' + def test_invalid_filename(): t = PyPyTarball('foo') assert t.vcs == None @@ -35,8 +37,8 @@ t2 = PyPyTarball('pypy-c-jit-75654-linux.tar.bz2') assert t.key() < t2.key() -def test_sort(): - files = map(PyPyTarball, [ +def test_sort(tmpdir): + files = [ 'pypy-c-jit-10000-linux.tar.bz2', 'pypy-c-jit-20000-linux.tar.bz2', 'pypy-c-nojit-10000-linux.tar.bz2', @@ -45,11 +47,11 @@ 'pypy-c-stackless-10000-linux.tar.bz2', 'pypy-c-jit-1000-e5b73981fc8d-linux.tar.bz2', # this is mercurial based 'pypy-c-jit-10000-linux-armel.tar.bz2', - ]) - - files.sort(key=PyPyTarball.key, reverse=True) - files = [f.filename for f in files] - assert files == [ + ] + [tmpdir.join(f).write(f) for f in files] + pypylist = PyPyList(tmpdir.strpath) + listener = pypylist.directoryListing() + assert listener.dirs == [ 'pypy-c-jit-1000-e5b73981fc8d-linux.tar.bz2', # mercurial first 'pypy-c-jit-20000-linux.tar.bz2', 'pypy-c-jit-10000-linux.tar.bz2', @@ -60,6 +62,26 @@ 'pypy-c-stackless-10000-linux.tar.bz2', ] +def test_pypy_list(tmpdir): + import os + pypylist = PyPyList(os.path.dirname(__file__)) + files = pypylist.listNames() + assert os.path.basename(__file__) in files + +def test_dir_render(tmpdir): + # Create a bunch of directories, including one named trunk, + # Make sure the time order is reversed collation order + trunk = tmpdir.mkdir('trunk') + oldtime = trunk.mtime() + for ascii in range(ord('a'), ord('m')): + newdir = tmpdir.mkdir(chr(ascii) * 4) + newdir.setmtime(oldtime + ascii * 10) + pypylist = PyPyList(tmpdir.strpath) + listener = pypylist.directoryListing() + assert listener.dirs == ['trunk', 'mmmm', 'llll', + 'kkkk','jjjj','iiii','hhhh','gggg','ffff','eeee', + 'dddd','cccc','bbbb','aaaa'] + def load_BuildmasterConfig(): import os from pypybuildbot import summary, builds @@ -70,7 +92,7 @@ return builds else: assert False - + this = py.path.local(__file__) master_py = this.dirpath().dirpath().join('master.py') glob = {'httpPortNumber': 80, @@ -91,13 +113,13 @@ assert app == expected_app assert own in builders or own in known_exceptions assert app in builders or app in known_exceptions - + t = PyPyTarball('pypy-c-jit-76867-linux.tar.bz2') check_builder_names(t, 'own-linux-x86-32', 'pypy-c-jit-linux-x86-32') t = PyPyTarball('pypy-c-nojit-76867-linux.tar.bz2') check_builder_names(t, 'own-linux-x86-32', 'pypy-c-app-level-linux-x86-32') - + t = PyPyTarball('pypy-c-jit-76867-osx.tar.bz2') check_builder_names(t, 'own-macosx-x86-32', 'pypy-c-jit-macosx-x86-32') From noreply at buildbot.pypy.org Fri Mar 22 09:32:25 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 22 Mar 2013 09:32:25 +0100 (CET) Subject: [pypy-commit] pypy default: add calling convention tests that fail on ARM hardfloat. Message-ID: <20130322083225.A1CB31C1497@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62643:c08ad20d4651 Date: 2013-03-22 10:00 +0200 http://bitbucket.org/pypy/pypy/changeset/c08ad20d4651/ Log: add calling convention tests that fail on ARM hardfloat. The tests pinpoint the current issue with float arguments passed on the stack using the hardfloat calling convention diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -7,6 +7,18 @@ from rpython.jit.backend.arm.codebuilder import ARMv7Builder from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests +from rpython.jit.backend.arm.test.test_runner import boxfloat, constfloat +from rpython.jit.metainterp.resoperation import ResOperation, rop +from rpython.jit.metainterp.history import (AbstractFailDescr, + AbstractDescr, + BasicFailDescr, + BasicFinalDescr, + BoxInt, Box, BoxPtr, + JitCellToken, TargetToken, + ConstInt, ConstPtr, + BoxObj, + ConstObj, BoxFloat, ConstFloat) + skip_unless_run_slow_tests() class TestARMCallingConvention(CallingConvTests): @@ -39,17 +51,6 @@ ops = """ [%s] i99 = call(ConstClass(func_ptr), 22, descr=calldescr) - force_spill(i0) - force_spill(i1) - force_spill(i2) - force_spill(i3) - force_spill(i4) - force_spill(i5) - force_spill(i6) - force_spill(i7) - force_spill(i8) - force_spill(i9) - force_spill(i10) guard_true(i0) [%s, i99] finish()""" % (args, args) loop = parse(ops, namespace=locals()) @@ -60,3 +61,82 @@ for x in range(11): assert self.cpu.get_int_value(deadframe, x) == x assert self.cpu.get_int_value(deadframe, 11) == 38 + + + def test_float_hf_call_mixed(self): + if not self.cpu.supports_floats: + py.test.skip("requires floats") + cpu = self.cpu + callargs = [] + def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9): + callargs.append(zip(range(12), + [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9])) + return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9 + F = lltype.Float + I = lltype.Signed + FUNC = self.FuncType([F] * 7 + [I] + [F] + [I] + [F]* 2, F) + FPTR = self.Ptr(FUNC) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + args = ([boxfloat(.1) for i in range(7)] + + [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3), + boxfloat(.4)]) + res = self.execute_operation(rop.CALL, + [funcbox] + args, + 'float', descr=calldescr) + for i,j in enumerate(callargs[0]): + box = args[i] + if box.type == 'f': + assert (i, args[i].getfloat()) == j + else: + assert (i, args[i].getint()) == j + assert abs(res.getfloat() - 4.6) < 0.0001 + + def test_float_hf_call_float(self): + if not self.cpu.supports_floats: + py.test.skip("requires floats") + cpu = self.cpu + callargs = [] + def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9): + callargs.append(zip(range(10), + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) + return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + F = lltype.Float + FUNC = self.FuncType([F] * 10, F) + FPTR = self.Ptr(FUNC) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + args = ([boxfloat(.1) for i in range(10)]) + res = self.execute_operation(rop.CALL, + [funcbox] + args, + 'float', descr=calldescr) + for i,j in enumerate(callargs[0]): + assert (i, 0.1) == j + assert abs(res.getfloat() - 1) < 0.0001 + + def test_float_hf_call_int(self): + cpu = self.cpu + callargs = [] + def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9): + callargs.append(zip(range(10), + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) + return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + + I = lltype.Signed + FUNC = self.FuncType([I] * 10, I) + FPTR = self.Ptr(FUNC) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + args = ([BoxInt(1) for i in range(10)]) + res = self.execute_operation(rop.CALL, + [funcbox] + args, + 'int', descr=calldescr) + for i,j in enumerate(callargs[0]): + assert (i, 1) == j + assert res.getint() == 10 From noreply at buildbot.pypy.org Fri Mar 22 09:32:26 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 22 Mar 2013 09:32:26 +0100 (CET) Subject: [pypy-commit] pypy default: avoid pushing a register when moving values around if we have a free register to use Message-ID: <20130322083226.F35521C1497@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62644:33776a88f16c Date: 2013-03-22 10:29 +0200 http://bitbucket.org/pypy/pypy/changeset/33776a88f16c/ Log: avoid pushing a register when moving values around if we have a free register to use diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1036,6 +1036,7 @@ assert 0, 'unsupported case' def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL): + helper = self._regalloc.get_free_reg() if loc.is_reg(): assert prev_loc.type != FLOAT, 'trying to load from an \ incompatible location into a core register' @@ -1044,24 +1045,24 @@ # unspill a core register offset = prev_loc.value is_imm = check_imm_arg(offset, size=0xFFF) - if not is_imm: - self.mc.PUSH([r.lr.value], cond=cond) - self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.lr) - if not is_imm: - self.mc.POP([r.lr.value], cond=cond) + helper = r.lr if helper is None else helper + save_helper = not is_imm and helper is r.lr elif loc.is_vfp_reg(): assert prev_loc.type == FLOAT, 'trying to load from an \ incompatible location into a float register' # load spilled value into vfp reg offset = prev_loc.value is_imm = check_imm_arg(offset) - if not is_imm: - self.mc.PUSH([r.ip.value], cond=cond) - self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.ip) - if not is_imm: - self.mc.POP([r.ip.value], cond=cond) + helper = r.ip if helper is None else helper + save_helper = not is_imm and helper is r.ip else: assert 0, 'unsupported case' + if save_helper: + self.mc.PUSH([helper.value], cond=cond) + self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=helper) + if save_helper: + self.mc.POP([helper.value], cond=cond) + def _mov_imm_float_to_loc(self, prev_loc, loc, cond=c.AL): if loc.is_vfp_reg(): diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -166,6 +166,13 @@ selected_reg=selected_reg) return reg + def get_free_reg(): + free_regs = self.free_regs + for i in range(len(free_regs), -1, -1): + if free_regs[i] in self.save_around_call_regs: + continue + return free_regs[i] + class Regalloc(BaseRegalloc): @@ -250,6 +257,8 @@ selected_reg) else: return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg) + def get_free_reg(self): + return self.rm.get_free_reg() def free_temp_vars(self): self.rm.free_temp_vars() diff --git a/rpython/jit/backend/arm/test/test_regalloc_mov.py b/rpython/jit/backend/arm/test/test_regalloc_mov.py --- a/rpython/jit/backend/arm/test/test_regalloc_mov.py +++ b/rpython/jit/backend/arm/test/test_regalloc_mov.py @@ -64,11 +64,15 @@ self.instrs.append(i) return i +class MockRegalloc(object): + def get_free_reg(self): + return r('helper') class BaseMovTest(object): def setup_method(self, method): self.builder = MockBuilder() self.asm = instantiate(AssemblerARM) + self.asm._regalloc = MockRegalloc() self.asm.mc = self.builder def validate(self, expected): @@ -170,10 +174,8 @@ s = stack(8191) r6 = r(6) expected = [ - mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, s.value, cond=AL), - mi('LDR_rr', r6.value, fp.value, lr.value, cond=AL), - mi('POP', [lr.value], cond=AL)] + mi('gen_load_int', 'helper', s.value, cond=AL), + mi('LDR_rr', r6.value, fp.value, 'helper', cond=AL)] self.mov(s, r6, expected) def test_mov_float_imm_to_vfp_reg(self): @@ -195,7 +197,7 @@ def test_mov_vfp_reg_to_stack(self): reg = vfp(7) s = stack_float(3) - expected = [mi('VSTR', reg.value, fp.value, imm=188, cond=AL)] + expected = [mi('VSTR', reg.value, fp.value, imm=192, cond=AL)] self.mov(reg, s, expected) def test_mov_vfp_reg_to_large_stackloc(self): @@ -211,7 +213,7 @@ def test_mov_stack_to_vfp_reg(self): reg = vfp(7) s = stack_float(3) - expected = [mi('VLDR', reg.value, fp.value, imm=188, cond=AL)] + expected = [mi('VLDR', reg.value, fp.value, imm=192, cond=AL)] self.mov(s, reg, expected) def test_mov_big_stackloc_to_vfp_reg(self): @@ -420,10 +422,8 @@ def test_push_big_stack(self): s = stack(1025) - e = [mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, s.value, cond=AL), - mi('LDR_rr', ip.value, fp.value, lr.value, cond=AL), - mi('POP', [lr.value], cond=AL), + e = [mi('gen_load_int', 'helper', s.value, cond=AL), + mi('LDR_rr', ip.value, fp.value, 'helper', cond=AL), mi('PUSH', [ip.value], cond=AL) ] self.push(s, e) @@ -436,7 +436,7 @@ def test_push_stack_float(self): sf = stack_float(4) e = [ - mi('VLDR', vfp_ip.value, fp.value, imm=192, cond=AL), + mi('VLDR', vfp_ip.value, fp.value, imm=196, cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL), ] self.push(sf, e) @@ -444,11 +444,9 @@ def test_push_large_stackfloat(self): sf = stack_float(100) e = [ - mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, sf.value, cond=AL), - mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL), - mi('VLDR', vfp_ip.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL), + mi('gen_load_int', 'helper', sf.value, cond=AL), + mi('ADD_rr', 'helper', fp.value, 'helper', cond=AL), + mi('VLDR', vfp_ip.value, 'helper', cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL), ] self.push(sf, e) From noreply at buildbot.pypy.org Fri Mar 22 09:32:28 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 22 Mar 2013 09:32:28 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130322083228.D1D1C1C1497@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62645:14906f16fcbe Date: 2013-03-22 10:31 +0200 http://bitbucket.org/pypy/pypy/changeset/14906f16fcbe/ Log: merge diff too long, truncating to 2000 out of 2589 lines diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,27 +1,30 @@ import sys +from rpython.rlib.cache import Cache +from rpython.tool.uid import HUGEVAL_BYTES +from rpython.rlib import jit, types +from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, + compute_unique_id) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import r_uint + from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, UserDelAction, FrameTraceAction) from pypy.interpreter.error import (OperationError, operationerrfmt, new_exception_class, typed_unwrap_error_msg) from pypy.interpreter.argument import Arguments from pypy.interpreter.miscutils import ThreadLocals -from rpython.rlib.cache import Cache -from rpython.tool.uid import HUGEVAL_BYTES -from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.objectmodel import we_are_translated, newlist_hint,\ - compute_unique_id -from rpython.rlib.rarithmetic import r_uint __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) -unpackiterable_driver = jit.JitDriver(name = 'unpackiterable', - greens = ['tp'], - reds = ['items', 'w_iterator']) +unpackiterable_driver = jit.JitDriver(name='unpackiterable', + greens=['tp'], + reds=['items', 'w_iterator']) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -698,6 +701,7 @@ raise return None + @signature(types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -20,31 +20,22 @@ assert space.unwrap(host) == socket.gethostname() def test_gethostbyname(): - host = "localhost" - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyname(host)") - assert space.unwrap(ip) == socket.gethostbyname(host) + for host in ["localhost", "127.0.0.1"]: + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyname(host)") + assert space.unwrap(ip) == socket.gethostbyname(host) def test_gethostbyname_ex(): - host = "localhost" - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyname_ex(host)") - assert isinstance(space.unwrap(ip), tuple) - assert space.unwrap(ip) == socket.gethostbyname_ex(host) + for host in ["localhost", "127.0.0.1"]: + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyname_ex(host)") + assert space.unwrap(ip) == socket.gethostbyname_ex(host) def test_gethostbyaddr(): - host = "localhost" - expected = socket.gethostbyaddr(host) - expecteds = (expected, expected[:2]+(['0.0.0.0'],)) - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) in expecteds - host = "127.0.0.1" - expected = socket.gethostbyaddr(host) - expecteds = (expected, expected[:2]+(['0.0.0.0'],)) - ip = space.appexec([w_socket, space.wrap(host)], - "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) in expecteds + for host in ["localhost", "127.0.0.1", "::1"]: + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + assert space.unwrap(ip) == socket.gethostbyaddr(host) def test_getservbyname(): name = "smtp" 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 @@ -175,6 +175,12 @@ class W_BoolBox(W_GenericBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("bool") + def descr_any(self, space): + return self + + def descr_all(self, space): + return self + class W_NumberBox(W_GenericBox): _attrs_ = () @@ -422,8 +428,9 @@ W_BoolBox.typedef = TypeDef("bool_", W_GenericBox.typedef, __module__ = "numpypy", __new__ = interp2app(W_BoolBox.descr__new__.im_func), - __index__ = interp2app(descr_index), + any = interp2app(W_BoolBox.descr_any), + all = interp2app(W_BoolBox.descr_all), ) W_NumberBox.typedef = TypeDef("number", W_GenericBox.typedef, 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 @@ -335,6 +335,15 @@ assert X(True) is numpy.True_ assert numpy.bool_("False") is numpy.True_ + def test_bool_any_all(self): + import numpypy as numpy + x = numpy.bool_(True) + assert x.any() + assert x.all() + x = numpy.bool_(False) + assert not x.any() + assert not x.all() + def test_int8(self): import numpypy as numpy diff --git a/pypy/tool/ann_override.py b/pypy/tool/ann_override.py --- a/pypy/tool/ann_override.py +++ b/pypy/tool/ann_override.py @@ -1,22 +1,17 @@ # overrides for annotation specific to PyPy codebase -from rpython.annotator.policy import AnnotatorPolicy, Sig +from rpython.annotator.policy import AnnotatorPolicy # for some reason, model must be imported first, # or we create a cycle. from rpython.flowspace.model import Constant -from rpython.annotator import model as annmodel -from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import specialize -from pypy.interpreter import baseobjspace + def isidentifier(s): - if not s: return False + if not s: + return False s = s.replace('_', 'x') return s[0].isalpha() and s.isalnum() -# patch - mostly for debugging, to enforce some signatures -baseobjspace.ObjSpace.newbool.im_func._annenforceargs_ = Sig(lambda s1,s2: s1, - bool) - class PyPyAnnotatorPolicy(AnnotatorPolicy): def __init__(pol, single_space=None): @@ -60,8 +55,8 @@ # for jit benefit if cached not in t._immutable_fields_: # accessed this way just # for convenience - t._immutable_fields_.append(cached) - + t._immutable_fields_.append(cached) + def attach_lookup(pol, t, attr): cached = "cached_%s" % attr if not t.is_heaptype() and not t.is_cpytype(): diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -178,13 +178,11 @@ # a graph that has already been rtyped. Safety-check the new # annotations that are passed in, and don't annotate the old # graph -- it's already low-level operations! - for a, s_newarg in zip(graph.getargs(), cells): + for a, s_newarg in zip(block.inputargs, cells): s_oldarg = self.binding(a) assert annmodel.unionof(s_oldarg, s_newarg) == s_oldarg else: assert not self.frozen - for a in cells: - assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: self.bindinputargs(graph, block, cells) else: diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -11,14 +11,13 @@ from rpython.annotator.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue from rpython.annotator.model import SomeInstance, SomeBuiltin, SomeIterator from rpython.annotator.model import SomePBC, SomeFloat, s_None, SomeByteArray -from rpython.annotator.model import SomeExternalObject, SomeWeakRef +from rpython.annotator.model import SomeWeakRef from rpython.annotator.model import SomeAddress, SomeTypedAddressAccess from rpython.annotator.model import SomeSingleFloat, SomeLongFloat, SomeType from rpython.annotator.model import unionof, UnionError, missing_operation from rpython.annotator.model import TLS from rpython.annotator.model import read_can_only_throw from rpython.annotator.model import add_knowntypedata, merge_knowntypedata -from rpython.annotator.model import SomeGenericCallable from rpython.annotator.bookkeeper import getbookkeeper from rpython.flowspace.model import Variable, Constant from rpython.rlib import rarithmetic @@ -131,7 +130,7 @@ def is_((obj1, obj2)): r = SomeBool() if obj2.is_constant(): - if obj1.is_constant(): + if obj1.is_constant(): r.const = obj1.const is obj2.const if obj2.const is None and not obj1.can_be_none(): r.const = False @@ -149,7 +148,7 @@ def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): - add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, + add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, bk.valueoftype(src_obj.const)) assert annotator.binding(op.args[tgt_arg]) == tgt_obj @@ -175,7 +174,7 @@ getbookkeeper().count("coerce", obj1, obj2) return pair(obj1, obj2).union() # reasonable enough - # approximation of an annotation intersection, the result should be the annotation obj or + # approximation of an annotation intersection, the result should be the annotation obj or # the intersection of obj and improvement def improve((obj, improvement)): if not improvement.contains(obj) and obj.contains(improvement): @@ -322,7 +321,7 @@ return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') - + add_knowntypedata(knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): @@ -333,7 +332,7 @@ # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) - if (isinstance(op.args[1], Constant) and + if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: @@ -354,14 +353,14 @@ class __extend__(pairtype(SomeBool, SomeBool)): def union((boo1, boo2)): - s = SomeBool() - if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): - s.const = boo1.const + s = SomeBool() + if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): + s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) s.set_knowntypedata(ktd) - return s + return s def and_((boo1, boo2)): s = SomeBool() @@ -386,13 +385,13 @@ if boo2.const: s.const = True return s - + def xor((boo1, boo2)): s = SomeBool() if boo1.is_constant() and boo2.is_constant(): s.const = boo1.const ^ boo2.const return s - + class __extend__(pairtype(SomeString, SomeString)): def union((str1, str2)): @@ -495,7 +494,7 @@ return s_string.__class__() class __extend__(pairtype(SomeFloat, SomeFloat)): - + def union((flt1, flt2)): return SomeFloat() @@ -512,13 +511,13 @@ class __extend__(pairtype(SomeSingleFloat, SomeSingleFloat)): - + def union((flt1, flt2)): return SomeSingleFloat() class __extend__(pairtype(SomeLongFloat, SomeLongFloat)): - + def union((flt1, flt2)): return SomeLongFloat() @@ -610,7 +609,7 @@ class __extend__(pairtype(SomeTuple, SomeInteger)): - + def getitem((tup1, int2)): if int2.is_immutable_constant(): try: @@ -624,7 +623,7 @@ class __extend__(pairtype(SomeList, SomeInteger)): - + def mul((lst1, int2)): return lst1.listdef.offspring() @@ -643,27 +642,27 @@ getitem_idx_key = getitem_idx def setitem((lst1, int2), s_value): - getbookkeeper().count("list_setitem", int2) + getbookkeeper().count("list_setitem", int2) lst1.listdef.mutate() lst1.listdef.generalize(s_value) setitem.can_only_throw = [IndexError] def delitem((lst1, int2)): - getbookkeeper().count("list_delitem", int2) + getbookkeeper().count("list_delitem", int2) lst1.listdef.resize() delitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] @@ -675,14 +674,14 @@ class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem_idx.can_only_throw = [IndexError] @@ -694,7 +693,7 @@ class __extend__(pairtype(SomeInteger, SomeString), pairtype(SomeInteger, SomeUnicodeString)): - + def mul((int1, str2)): # xxx do we want to support this getbookkeeper().count("str_mul", str2, int1) return str2.basestringclass() @@ -714,7 +713,7 @@ return result class __extend__(pairtype(SomeInteger, SomeList)): - + def mul((int1, lst2)): return lst2.listdef.offspring() @@ -787,7 +786,7 @@ class __extend__(pairtype(SomePBC, SomePBC)): - def union((pbc1, pbc2)): + def union((pbc1, pbc2)): d = pbc1.descriptions.copy() d.update(pbc2.descriptions) return SomePBC(d, can_be_None = pbc1.can_be_None or pbc2.can_be_None) @@ -804,20 +803,6 @@ s.const = False # no common desc in the two sets return s -class __extend__(pairtype(SomeGenericCallable, SomePBC)): - def union((gencall, pbc)): - for desc in pbc.descriptions: - unique_key = desc - bk = desc.bookkeeper - s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unionof(s_result, gencall.s_result) - assert gencall.s_result.contains(s_result) - return gencall - -class __extend__(pairtype(SomePBC, SomeGenericCallable)): - def union((pbc, gencall)): - return pair(gencall, pbc).union() - class __extend__(pairtype(SomeImpossibleValue, SomeObject)): def union((imp1, obj2)): return obj2 @@ -854,7 +839,6 @@ _make_none_union('SomeUnicodeString', 'can_be_None=True') _make_none_union('SomeList', 'obj.listdef') _make_none_union('SomeDict', 'obj.dictdef') -_make_none_union('SomeExternalObject', 'obj.knowntype') _make_none_union('SomeWeakRef', 'obj.classdef') # getitem on SomePBCs, in particular None fails @@ -881,12 +865,6 @@ raise AnnotatorError('add on %r' % pbc) return s_ImpossibleValue -class __extend__(pairtype(SomeExternalObject, SomeExternalObject)): - def union((ext1, ext2)): - if ext1.knowntype == ext2.knowntype: - return SomeExternalObject(ext1.knowntype) - return SomeObject() - # ____________________________________________________________ # annotation of low-level types from rpython.annotator.model import SomePtr, SomeOOInstance, SomeOOClass diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -426,8 +426,8 @@ elif ishashable(x) and x in BUILTIN_ANALYZERS: _module = getattr(x,"__module__","unknown") result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__)) - elif extregistry.is_registered(x, self.policy): - entry = extregistry.lookup(x, self.policy) + elif extregistry.is_registered(x): + entry = extregistry.lookup(x) result = entry.compute_annotation_bk(self) elif isinstance(x, lltype._ptr): result = SomePtr(lltype.typeOf(x)) diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -29,13 +29,15 @@ from __future__ import absolute_import -from types import BuiltinFunctionType, MethodType, FunctionType +import inspect +import weakref +from types import BuiltinFunctionType, MethodType + import rpython from rpython.tool import descriptor from rpython.tool.pairtype import pair, extendabletype -from rpython.rlib.rarithmetic import r_uint, r_ulonglong, base_int -from rpython.rlib.rarithmetic import r_singlefloat, r_longfloat -import inspect, weakref +from rpython.rlib.rarithmetic import r_uint, base_int, r_singlefloat, r_longfloat + class State(object): # A global attribute :-( Patch it with 'True' to enable checking of @@ -56,8 +58,10 @@ def __eq__(self, other): return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + def __ne__(self, other): return not (self == other) + def __repr__(self): try: reprdict = TLS.reprdict @@ -75,7 +79,7 @@ m = getattr(self, 'fmt_' + k, repr) r = m(v) if r is not None: - args.append('%s=%s'%(k, r)) + args.append('%s=%s' % (k, r)) kwds = ', '.join(args) finally: del reprdict[self] @@ -83,7 +87,7 @@ def fmt_knowntype(self, t): return t.__name__ - + def contains(self, other): if self == other: return True @@ -130,6 +134,7 @@ def can_be_none(self): return False + class SomeFloat(SomeObject): "Stands for a float or an integer." knowntype = float # if we don't know if it's a float or an int, @@ -152,6 +157,7 @@ def can_be_none(self): return False + class SomeSingleFloat(SomeObject): "Stands for an r_singlefloat." # No operation supported, not even union with a regular float @@ -161,6 +167,7 @@ def can_be_none(self): return False + class SomeLongFloat(SomeObject): "Stands for an r_longfloat." # No operation supported, not even union with a regular float @@ -170,9 +177,11 @@ def can_be_none(self): return False + class SomeInteger(SomeFloat): "Stands for an object which is known to be an integer." knowntype = int + # size is in multiples of C's sizeof(long)! def __init__(self, nonneg=False, unsigned=None, knowntype=None): assert (knowntype is None or knowntype is int or @@ -189,25 +198,29 @@ self.nonneg = unsigned or nonneg self.unsigned = unsigned # rpython.rlib.rarithmetic.r_uint + class SomeBool(SomeInteger): "Stands for true or false." knowntype = bool nonneg = True unsigned = False + def __init__(self): pass + def set_knowntypedata(self, knowntypedata): assert not hasattr(self, 'knowntypedata') if knowntypedata: self.knowntypedata = knowntypedata + class SomeStringOrUnicode(SomeObject): """Base class for shared implementation of SomeString and SomeUnicodeString. Cannot be an annotation.""" immutable = True - can_be_None=False + can_be_None = False no_nul = False # No NUL character in the string. def __init__(self, can_be_None=False, no_nul=False): @@ -226,8 +239,10 @@ d1 = self.__dict__ d2 = other.__dict__ if not TLS.check_str_without_nul: - d1 = d1.copy(); d1['no_nul'] = 0 # ignored - d2 = d2.copy(); d2['no_nul'] = 0 # ignored + d1 = d1.copy() + d1['no_nul'] = 0 + d2 = d2.copy() + d2['no_nul'] = 0 return d1 == d2 def nonnoneify(self): @@ -236,27 +251,34 @@ def nonnulify(self): return self.__class__(can_be_None=self.can_be_None, no_nul=True) + class SomeString(SomeStringOrUnicode): "Stands for an object which is known to be a string." knowntype = str + class SomeUnicodeString(SomeStringOrUnicode): "Stands for an object which is known to be an unicode string" knowntype = unicode + class SomeByteArray(SomeStringOrUnicode): knowntype = bytearray + class SomeChar(SomeString): "Stands for an object known to be a string of length 1." can_be_None = False + def __init__(self, no_nul=False): # no 'can_be_None' argument here if no_nul: self.no_nul = True + class SomeUnicodeCodePoint(SomeUnicodeString): "Stands for an object known to be a unicode codepoint." can_be_None = False + def __init__(self, no_nul=False): # no 'can_be_None' argument here if no_nul: self.no_nul = True @@ -266,11 +288,14 @@ SomeUnicodeString.basestringclass = SomeUnicodeString SomeUnicodeString.basecharclass = SomeUnicodeCodePoint + class SomeList(SomeObject): "Stands for a homogenous list of any length." knowntype = list + def __init__(self, listdef): self.listdef = listdef + def __eq__(self, other): if self.__class__ is not other.__class__: return False @@ -285,10 +310,12 @@ def can_be_none(self): return True + class SomeTuple(SomeObject): "Stands for a tuple of known length." knowntype = tuple immutable = True + def __init__(self, items): self.items = tuple(items) # tuple of s_xxx elements for i in items: @@ -300,11 +327,14 @@ def can_be_none(self): return False + class SomeDict(SomeObject): "Stands for a dict." knowntype = dict + def __init__(self, dictdef): self.dictdef = dictdef + def __eq__(self, other): if self.__class__ is not other.__class__: return False @@ -323,12 +353,13 @@ if len(const) < 20: return repr(const) else: - return '{...%s...}'%(len(const),) + return '{...%s...}' % (len(const),) class SomeIterator(SomeObject): "Stands for an iterator returning objects from a given container." knowntype = type(iter([])) # arbitrarily chose seqiter as the type + def __init__(self, s_container, *variant): self.variant = variant self.s_container = s_container @@ -336,6 +367,7 @@ def can_be_none(self): return False + class SomeInstance(SomeObject): "Stands for an instance of a (user-defined) class." @@ -347,11 +379,13 @@ def fmt_knowntype(self, kt): return None + def fmt_classdef(self, cdef): if cdef is None: return 'object' else: return cdef.name + def fmt_flags(self, flags): if flags: return repr(flags) @@ -444,7 +478,7 @@ if hasattr(self, 'const'): return None else: - return '{...%s...}'%(len(pbis),) + return '{...%s...}' % (len(pbis),) def fmt_knowntype(self, kt): if self.is_constant(): @@ -452,15 +486,6 @@ else: return kt.__name__ -class SomeGenericCallable(SomeObject): - """ Stands for external callable with known signature - """ - def __init__(self, args, result): - self.args_s = args - self.s_result = result - - def can_be_None(self): - return True class SomeBuiltin(SomeObject): "Stands for a built-in function or method with special-cased analysis." @@ -480,26 +505,18 @@ def can_be_none(self): return False + class SomeBuiltinMethod(SomeBuiltin): """ Stands for a built-in method which has got special meaning """ knowntype = MethodType -class SomeExternalObject(SomeObject): - """Stands for an object of 'external' type. External types have a Repr - controlled by rpython.rtyper.extregistry.""" - - def __init__(self, knowntype): - self.knowntype = knowntype - - def can_be_none(self): - return True class SomeImpossibleValue(SomeObject): """The empty set. Instances are placeholders for objects that will never show up at run-time, e.g. elements of an empty list.""" immutable = True - annotationcolor = (160,160,160) + annotationcolor = (160, 160, 160) def can_be_none(self): return False @@ -507,16 +524,18 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() -s_Int = SomeInteger() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) + # ____________________________________________________________ # weakrefs class SomeWeakRef(SomeObject): knowntype = weakref.ReferenceType immutable = True + def __init__(self, classdef): # 'classdef' is None for known-to-be-dead weakrefs. self.classdef = classdef @@ -526,6 +545,7 @@ from rpython.rtyper.lltypesystem import llmemory + class SomeAddress(SomeObject): immutable = True @@ -535,6 +555,7 @@ def is_null_address(self): return self.is_immutable_constant() and not self.const + # The following class is used to annotate the intermediate value that # appears in expressions of the form: # addr.signed[offset] and addr.signed[offset] = value @@ -550,11 +571,12 @@ # annotation of low-level types from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.ootypesystem import ootype + class SomePtr(SomeObject): knowntype = lltype._ptr immutable = True + def __init__(self, ll_ptrtype): assert isinstance(ll_ptrtype, lltype.Ptr) self.ll_ptrtype = ll_ptrtype @@ -562,41 +584,52 @@ def can_be_none(self): return False + class SomeInteriorPtr(SomePtr): def __init__(self, ll_ptrtype): assert isinstance(ll_ptrtype, lltype.InteriorPtr) self.ll_ptrtype = ll_ptrtype + class SomeLLADTMeth(SomeObject): immutable = True + def __init__(self, ll_ptrtype, func): self.ll_ptrtype = ll_ptrtype - self.func = func + self.func = func def can_be_none(self): return False + class SomeOOObject(SomeObject): def __init__(self): + from rpython.rtyper.ootypesystem import ootype self.ootype = ootype.Object + class SomeOOClass(SomeObject): def __init__(self, ootype): self.ootype = ootype + class SomeOOInstance(SomeObject): def __init__(self, ootype, can_be_None=False): self.ootype = ootype self.can_be_None = can_be_None + class SomeOOBoundMeth(SomeObject): immutable = True + def __init__(self, ootype, name): self.ootype = ootype self.name = name + class SomeOOStaticMeth(SomeObject): immutable = True + def __init__(self, method): self.method = method @@ -611,7 +644,10 @@ (SomeAddress(), llmemory.Address), ] + def annotation_to_lltype(s_val, info=None): + from rpython.rtyper.ootypesystem import ootype + if isinstance(s_val, SomeOOInstance): return s_val.ootype if isinstance(s_val, SomeOOStaticMeth): @@ -644,7 +680,10 @@ ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map]) + def lltype_to_annotation(T): + from rpython.rtyper.ootypesystem import ootype + try: s = ll_to_annotation_map.get(T) except TypeError: @@ -669,6 +708,7 @@ else: return s + def ll_to_annotation(v): if v is None: # i think we can only get here in the case of void-returning @@ -681,13 +721,15 @@ T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets) return SomeInteriorPtr(T) return lltype_to_annotation(lltype.typeOf(v)) - + + # ____________________________________________________________ class UnionError(Exception): """Signals an suspicious attempt at taking the union of deeply incompatible SomeXxx instances.""" + def unionof(*somevalues): "The most precise SomeValue instance that contains all the values." try: @@ -703,12 +745,14 @@ s1 = pair(s1, s2).union() return s1 + # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): for v in vars: ktd[(truth, v)] = s_obj + def merge_knowntypedata(ktd1, ktd2): r = {} for truth_v in ktd1: @@ -716,6 +760,7 @@ r[truth_v] = unionof(ktd1[truth_v], ktd2[truth_v]) return r + def not_const(s_obj): if s_obj.is_constant() and not isinstance(s_obj, SomePBC): new_s_obj = SomeObject.__new__(s_obj.__class__) @@ -727,21 +772,23 @@ s_obj = new_s_obj return s_obj + # ____________________________________________________________ # internal def commonbase(cls1, cls2): # XXX single inheritance only XXX hum l1 = inspect.getmro(cls1) - l2 = inspect.getmro(cls2) - if l1[-1] != object: - l1 = l1 + (object,) - if l2[-1] != object: - l2 = l2 + (object,) - for x in l1: - if x in l2: - return x + l2 = inspect.getmro(cls2) + if l1[-1] != object: + l1 = l1 + (object,) + if l2[-1] != object: + l2 = l2 + (object,) + for x in l1: + if x in l2: + return x assert 0, "couldn't get to commonbase of %r and %r" % (cls1, cls2) + def missing_operation(cls, name): def default_op(*args): if args and isinstance(args[0], tuple): @@ -750,12 +797,13 @@ flattened = args for arg in flattened: if arg.__class__ is SomeObject and arg.knowntype is not type: - return SomeObject() + return SomeObject() bookkeeper = rpython.annotator.bookkeeper.getbookkeeper() bookkeeper.warning("no precise annotation supplied for %s%r" % (name, args)) return s_ImpossibleValue setattr(cls, name, default_op) + class HarmlesslyBlocked(Exception): """Raised by the unaryop/binaryop to signal a harmless kind of BlockedInference: the current block is blocked, but not in a way diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -82,8 +82,8 @@ return SomeUnicodeString() elif t is types.NoneType: return s_None - elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): - entry = extregistry.lookup_type(t, bookkeeper.policy) + elif bookkeeper and extregistry.is_registered_type(t): + entry = extregistry.lookup_type(t) return entry.compute_annotation_bk(bookkeeper) elif t is type: return SomeType() @@ -97,7 +97,7 @@ def __init__(self, *argtypes): self.argtypes = argtypes - + def __call__(self, funcdesc, inputcells): from rpython.rtyper.lltypesystem import lltype args_s = [] 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 @@ -3033,33 +3033,6 @@ s = a.build_types(fun, []) assert s.const == 0 - def test_some_generic_function_call(self): - def h(x): - return int(x) - - def c(x): - return int(x) - - def g(a, x): - if x == -1: - a = None - if x < 0: - if x == -1: - a = h - else: - a = c - x = x + .01 - return a(x) - - #def fun(x): - - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) - s = a.build_types(g, [annmodel.SomeGenericCallable( - args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), - annmodel.SomeFloat()]) - assert isinstance(s, annmodel.SomeInteger) - assert not hasattr(s, 'const') - def test_compare_int_bool(self): def fun(x): return 50 < x diff --git a/rpython/annotator/test/test_signature.py b/rpython/annotator/test/test_signature.py --- a/rpython/annotator/test/test_signature.py +++ b/rpython/annotator/test/test_signature.py @@ -6,10 +6,3 @@ assert _annotation_key({str:(str, [str])}) == ('dict', (str, (str, ('list', str)))) for i in ([[str]], [str], (int, int, {str: [str]})): assert hash(_annotation_key(i)) - -def test_genericcallable(): - py.test.skip("this two annotations should be equal - fix!") - from rpython.rtyper.extfunc import genericcallable - s1 = annotation([genericcallable([str], int)]) - s2 = annotation([genericcallable([str], int)]) - assert s1 == s2 diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -9,10 +9,10 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ + SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ - SomeGenericCallable, SomeWeakRef, SomeUnicodeString + SomeWeakRef, SomeUnicodeString from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import builtin from rpython.annotator.binaryop import _clone ## XXX where to put this? @@ -358,7 +358,7 @@ s_value = dct.dictdef.read_value() return (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)) - + def len(dct): if dct._is_empty(): return immutablevalue(0) @@ -751,34 +751,6 @@ else: return SomeObject() # len() on a pbc? no chance -class __extend__(SomeGenericCallable): - def call(self, args): - bookkeeper = getbookkeeper() - for arg, expected in zip(args.unpack()[0], self.args_s): - assert expected.contains(arg) - - return self.s_result - -class __extend__(SomeExternalObject): - def getattr(p, s_attr): - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - s_value = entry.get_field_annotation(p.knowntype, attr) - return s_value - else: - return SomeObject() - getattr.can_only_throw = [] - - def setattr(p, s_attr, s_value): - assert s_attr.is_constant() - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - entry.set_field_annotation(p.knowntype, attr, s_value) - - def is_true(p): - return s_Bool - # annotation of low-level types from rpython.annotator.model import SomePtr, SomeLLADTMeth from rpython.annotator.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth @@ -845,7 +817,7 @@ return SomeOOBoundMeth(r.ootype, s_attr.const) return ll_to_annotation(v) - def setattr(r, s_attr, s_value): + def setattr(r, s_attr, s_value): assert s_attr.is_constant(), "setattr on ref %r with non-constant field-name" % r.ootype v = annotation_to_lltype(s_value) example = r.ootype._example() diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py --- a/rpython/rlib/_rsocket_rffi.py +++ b/rpython/rlib/_rsocket_rffi.py @@ -262,7 +262,7 @@ CConfig.in_addr = platform.Struct('struct in_addr', [('s_addr', rffi.UINT)]) CConfig.in6_addr = platform.Struct('struct in6_addr', - []) + [('s6_addr', rffi.CFixedArray(rffi.CHAR, 16))]) CConfig.sockaddr_in = platform.Struct('struct sockaddr_in', [('sin_family', rffi.INT), ('sin_port', rffi.USHORT), diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -598,7 +598,7 @@ return result return decorate - + def clone(self): assert self.inline_jit_merge_point, 'JitDriver.clone works only after @inline' @@ -844,7 +844,7 @@ assert s_name.is_constant() if s_name.const == 'enable_opts': assert annmodel.SomeString(can_be_None=True).contains(s_value) - else: + else: assert (s_value == annmodel.s_None or annmodel.SomeInteger().contains(s_value)) return annmodel.s_None @@ -876,7 +876,7 @@ class AsmInfo(object): """ An addition to JitDebugInfo concerning assembler. Attributes: - + ops_offset - dict of offsets of operations or None asmaddr - (int) raw address of assembler block asmlen - assembler block length @@ -986,7 +986,7 @@ def specialize_call(self, hop): from rpython.rtyper.lltypesystem import rclass, lltype - + classrepr = rclass.get_type_repr(hop.rtyper) hop.exception_cannot_occur() diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -15,21 +15,23 @@ # * the list of characters self.bigbuffer; # * each of the strings in self.strings. # + self.closed = False self.strings = None - self.bigbuffer = [] + self.bigbuffer = None self.pos = AT_END def close(self): + self.closed = True self.strings = None self.bigbuffer = None def is_closed(self): - return self.bigbuffer is None + return self.closed def getvalue(self): """If self.strings contains more than 1 string, join all the strings together. Return the final single string.""" - if len(self.bigbuffer): + if self.bigbuffer is not None: self.copy_into_bigbuffer() return ''.join(self.bigbuffer) if self.strings is not None: @@ -37,13 +39,17 @@ return '' def getsize(self): - result = len(self.bigbuffer) + result = 0 + if self.bigbuffer is not None: + result += len(self.bigbuffer) if self.strings is not None: result += self.strings.getlength() return result def copy_into_bigbuffer(self): """Copy all the data into the list of characters self.bigbuffer.""" + if self.bigbuffer is None: + self.bigbuffer = [] if self.strings is not None: self.bigbuffer += self.strings.build() self.strings = None @@ -56,7 +62,7 @@ if p != AT_END: # slow or semi-fast paths assert p >= 0 endp = p + len(buffer) - if len(self.bigbuffer) >= endp: + if self.bigbuffer is not None and len(self.bigbuffer) >= endp: # semi-fast path: the write is entirely inside self.bigbuffer for i in range(len(buffer)): self.bigbuffer[p + i] = buffer[i] @@ -114,7 +120,7 @@ if p == 0 and n < 0: self.pos = AT_END return self.getvalue() # reading everything - if p == AT_END: + if p == AT_END or n == 0: return '' assert p >= 0 self.copy_into_bigbuffer() @@ -132,12 +138,14 @@ return ''.join(self.bigbuffer[p:p+count]) def readline(self, size=-1): - p = self.tell() + p = self.pos + if p == AT_END or size == 0: + return '' + assert p >= 0 self.copy_into_bigbuffer() end = len(self.bigbuffer) if size >= 0 and size < end - p: end = p + size - assert p >= 0 i = p while i < end: finished = self.bigbuffer[i] == '\n' @@ -152,7 +160,7 @@ # than CPython: it never grows the buffer, and it sets the current # position to the end. assert size >= 0 - if size > len(self.bigbuffer): + if self.bigbuffer is None or size > len(self.bigbuffer): self.copy_into_bigbuffer() else: # we can drop all extra strings @@ -160,4 +168,6 @@ self.strings = None if size < len(self.bigbuffer): del self.bigbuffer[size:] + if len(self.bigbuffer) == 0: + self.bigbuffer = None self.pos = AT_END diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -339,7 +339,7 @@ # to avoid leaks if an exception occurs inbetween sin = lltype.malloc(_c.sockaddr_in6, flavor='raw', zero=True) result.setdata(sin, sizeof(_c.sockaddr_in6)) - rffi.setintfield(sin, 'c_sin6_family', AF_INET) + rffi.setintfield(sin, 'c_sin6_family', AF_INET6) rffi.structcopy(sin.c_sin6_addr, in6_addr) return result from_in6_addr = staticmethod(from_in6_addr) diff --git a/rpython/rlib/signature.py b/rpython/rlib/signature.py --- a/rpython/rlib/signature.py +++ b/rpython/rlib/signature.py @@ -1,5 +1,6 @@ from rpython.rlib import types + def signature(*paramtypes, **kwargs): """Decorate a function to specify its type signature. @@ -12,7 +13,7 @@ """ returntype = kwargs.pop('returns', None) if returntype is None: - raise TypeError, "signature: parameter 'returns' required" + raise TypeError("signature: parameter 'returns' required") def decorator(f): f._signature_ = (paramtypes, returntype) diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -40,55 +40,49 @@ a = NETLINKAddress(pid, group_mask) assert a.get_pid() == pid assert a.get_groups() == group_mask - + def test_gethostname(): s = gethostname() assert isinstance(s, str) def test_gethostbyname(): - a = gethostbyname('localhost') - assert isinstance(a, INETAddress) - assert a.get_host() == "127.0.0.1" + for host in ["localhost", "127.0.0.1"]: + a = gethostbyname(host) + assert isinstance(a, INETAddress) + assert a.get_host() == "127.0.0.1" def test_gethostbyname_ex(): - name, aliases, address_list = gethostbyname_ex('localhost') - allnames = [name] + aliases - for n in allnames: - assert isinstance(n, str) - if sys.platform != 'win32': - assert 'localhost' in allnames - for a in address_list: - if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": - break # ok - else: - py.test.fail("could not find the 127.0.0.1 IPv4 address in %r" - % (address_list,)) - -def test_gethostbyaddr(): - name, aliases, address_list = gethostbyaddr('127.0.0.1') - allnames = [name] + aliases - for n in allnames: - assert isinstance(n, str) - if sys.platform != 'win32': - assert 'localhost' in allnames - for a in address_list: - if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": - break # ok - else: - py.test.fail("could not find the 127.0.0.1 IPv4 address in %r" - % (address_list,)) - - name, aliases, address_list = gethostbyaddr('localhost') + for host in ["localhost", "127.0.0.1"]: + name, aliases, address_list = gethostbyname_ex(host) allnames = [name] + aliases for n in allnames: assert isinstance(n, str) if sys.platform != 'win32': - assert 'localhost' in allnames + assert host in allnames for a in address_list: - if isinstance(a, INET6Address) and a.get_host() == "::1": + if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": break # ok + # no IPV6, should always return IPV4 else: - py.test.fail("could not find the ::1 IPv6 address in %r" + py.test.fail("could not find the localhost address in %r" + % (address_list,)) + +def test_gethostbyaddr(): + for host in ["localhost", "127.0.0.1", "::1"]: + name, aliases, address_list = gethostbyaddr(host) + allnames = [name] + aliases + for n in allnames: + assert isinstance(n, str) + if sys.platform != 'win32': + assert 'localhost' in allnames or 'ip6-localhost' in allnames + for a in address_list: + if isinstance(a, INETAddress) and a.get_host() == "127.0.0.1": + break # ok + if host != '127.0.0.1': # name lookup might return IPV6 + if isinstance(a, INET6Address) and a.get_host() == "::1": + break # ok + else: + py.test.fail("could not find the localhost address in %r" % (address_list,)) def test_getservbyname(): @@ -124,7 +118,7 @@ def as_str(self): return self.x - + if sys.platform == "win32": py.test.skip('No socketpair on Windows') s1, s2 = socketpair() diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py --- a/rpython/rlib/types.py +++ b/rpython/rlib/types.py @@ -10,9 +10,11 @@ def float(): return model.SomeFloat() + def singlefloat(): return model.SomeSingleFloat() + def longfloat(): return model.SomeLongFloat() @@ -21,18 +23,26 @@ return model.SomeInteger() +def bool(): + return model.SomeBool() + + def unicode(): return model.SomeUnicodeString() + def unicode0(): return model.SomeUnicodeString(no_nul=True) + def str(): return model.SomeString() + def str0(): return model.SomeString(no_nul=True) + def char(): return model.SomeChar() @@ -46,21 +56,25 @@ listdef = ListDef(None, element, mutated=True, resized=True) return model.SomeList(listdef) + def array(element): listdef = ListDef(None, element, mutated=True, resized=False) return model.SomeList(listdef) + def dict(keytype, valuetype): dictdef = DictDef(None, keytype, valuetype) return model.SomeDict(dictdef) -def instance(class_): - return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(class_)) +def instance(cls): + return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(cls)) + class SelfTypeMarker(object): pass + def self(): return SelfTypeMarker() @@ -68,5 +82,6 @@ class AnyTypeMarker(object): pass + def any(): return AnyTypeMarker() diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py --- a/rpython/rtyper/extfunc.py +++ b/rpython/rtyper/extfunc.py @@ -125,23 +125,6 @@ def _freeze_(self): return True -class genericcallable(object): - """ A way to specify the callable annotation, but deferred until - we have bookkeeper - """ - def __init__(self, args, result=None): - self.args = args - self.result = result - -class _ext_callable(ExtRegistryEntry): - _type_ = genericcallable - # we defer a bit annotation here - - def compute_result_annotation(self): - return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper) - for i in self.instance.args], - annotation(self.instance.result, self.bookkeeper)) - class ExtFuncEntry(ExtRegistryEntry): safe_not_sandboxed = False @@ -249,7 +232,7 @@ llfakeimpl, oofakeimpl: optional; if provided, they are called by the llinterpreter sandboxsafe: use True if the function performs no I/O (safe for --sandbox) """ - + if export_name is None: export_name = function.__name__ diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -22,17 +22,9 @@ for k in key: selfcls._register(dict, k) else: - for basecls in selfcls.__mro__: - if '_condition_' in basecls.__dict__: - cond = basecls.__dict__['_condition_'] - break - else: - cond = None - try: - family = dict[key] - except KeyError: - family = dict[key] = ClassFamily() - family.add(selfcls, cond) + if key in dict: + raise ValueError("duplicate extregistry entry %r" % (selfcls,)) + dict[key] = selfcls def _register_value(selfcls, key): selfcls._register(EXT_REGISTRY_BY_VALUE, key) @@ -43,32 +35,6 @@ def _register_metatype(selfcls, key): selfcls._register(EXT_REGISTRY_BY_METATYPE, key) -class ClassFamily(object): - - def __init__(self): - self.default = None - self.conditionals = [] - - def add(self, cls, cond=None): - if cond is None: - assert self.default is None, ( - "duplicate extregistry entry %r" % (cls,)) - self.default = cls - else: - self.conditionals.append((cls, cond)) - - def match(self, config): - if config is not None: - matches = [cls for cls, cond in self.conditionals - if cond(config)] - if matches: - assert len(matches) == 1, ( - "multiple extregistry matches: %r" % (matches,)) - return matches[0] - if self.default: - return self.default - raise KeyError("no default extregistry entry") - class ExtRegistryEntry(object): __metaclass__ = AutoRegisteringType @@ -159,36 +125,36 @@ # ____________________________________________________________ # Public interface to access the registry -def _lookup_type_cls(tp, config): +def _lookup_type_cls(tp): try: - return EXT_REGISTRY_BY_TYPE[tp].match(config) + return EXT_REGISTRY_BY_TYPE[tp] except (KeyError, TypeError): - return EXT_REGISTRY_BY_METATYPE[type(tp)].match(config) + return EXT_REGISTRY_BY_METATYPE[type(tp)] -def lookup_type(tp, config=None): - Entry = _lookup_type_cls(tp, config) +def lookup_type(tp): + Entry = _lookup_type_cls(tp) return Entry(tp) -def is_registered_type(tp, config=None): +def is_registered_type(tp): try: - _lookup_type_cls(tp, config) + _lookup_type_cls(tp) except KeyError: return False return True -def _lookup_cls(instance, config): +def _lookup_cls(instance): try: - return EXT_REGISTRY_BY_VALUE[instance].match(config) + return EXT_REGISTRY_BY_VALUE[instance] except (KeyError, TypeError): - return _lookup_type_cls(type(instance), config) + return _lookup_type_cls(type(instance)) -def lookup(instance, config=None): - Entry = _lookup_cls(instance, config) +def lookup(instance): + Entry = _lookup_cls(instance) return Entry(type(instance), instance) -def is_registered(instance, config=None): +def is_registered(instance): try: - _lookup_cls(instance, config) + _lookup_cls(instance) except KeyError: return False return True diff --git a/rpython/rtyper/lltypesystem/rgeneric.py b/rpython/rtyper/lltypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/lltypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.lltypesystem.lltype import Ptr, FuncType - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return Ptr(FuncType(l_args, l_retval)) diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -1,6 +1,6 @@ -from rpython.rlib import rgc, jit +from rpython.rlib import rgc, jit, types from rpython.rlib.debug import ll_assert -from rpython.rlib.objectmodel import enforceargs +from rpython.rlib.signature import signature from rpython.rtyper.lltypesystem import rstr from rpython.rtyper.lltypesystem.lltype import (GcForwardReference, Ptr, GcArray, GcStruct, Void, Signed, malloc, typeOf, nullptr, typeMethod) @@ -171,7 +171,7 @@ # adapted C code - at enforceargs(None, int, None) + at signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_hint_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements. Note that @@ -227,7 +227,8 @@ if allocated < newsize or newsize < (allocated >> 1) - 5: _ll_list_resize_hint_really(l, newsize, False) - at enforceargs(None, int, None) + + at signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements, and set diff --git a/rpython/rtyper/ootypesystem/ootype.py b/rpython/rtyper/ootypesystem/ootype.py --- a/rpython/rtyper/ootypesystem/ootype.py +++ b/rpython/rtyper/ootypesystem/ootype.py @@ -1,12 +1,12 @@ import py -from py.builtin import set -from rpython.rtyper.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char -from rpython.rtyper.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \ - Primitive, isCompatibleType, enforce, saferecursive, SignedLongLong, UnsignedLongLong -from rpython.rtyper.lltypesystem.lltype import frozendict -from rpython.rtyper.lltypesystem.lltype import identityhash + +from rpython.rlib import objectmodel, types +from rpython.rlib.signature import signature from rpython.rlib.rarithmetic import intmask -from rpython.rlib import objectmodel +from rpython.rtyper.lltypesystem.lltype import (LowLevelType, Signed, Unsigned, + Float, Char, Bool, Void, UniChar, typeOf, Primitive, isCompatibleType, + enforce, saferecursive, SignedLongLong, UnsignedLongLong, frozendict, + identityhash) from rpython.tool.uid import uid @@ -75,7 +75,7 @@ def _example(self): return _class(ROOT) - + Class = Class() class Instance(OOType): @@ -111,7 +111,7 @@ def __hash__(self): return object.__hash__(self) - + def _defl(self): return self._null @@ -153,7 +153,7 @@ _, meth = self._lookup(name) if meth is not None: raise TypeError("Cannot add field %r: method already exists" % name) - + if self._superclass is not None: if self._superclass._has_field(name): raise TypeError("Field %r exists in superclass" % name) @@ -161,7 +161,7 @@ if type(defn) is not tuple: if isinstance(defn, Meth): raise TypeError("Attempting to store method in field") - + fields[name] = (defn, defn._defl()) else: ootype, default = defn @@ -198,7 +198,7 @@ def _init_instance(self, instance): if self._superclass is not None: self._superclass._init_instance(instance) - + for name, (ootype, default) in self._fields.iteritems(): instance.__dict__[name] = enforce(ootype, default) @@ -587,10 +587,10 @@ # this is the equivalent of the lltypesystem ll_newlist that is # marked as typeMethod. + @signature(types.any(), types.int(), returns=types.any()) def ll_newlist(self, length): from rpython.rtyper.ootypesystem import rlist return rlist.ll_newlist(self, length) - ll_newlist._annenforceargs_ = (None, int) # NB: We are expecting Lists of the same ITEMTYPE to compare/hash # equal. We don't redefine __eq__/__hash__ since the implementations @@ -613,7 +613,7 @@ def __hash__(self): if self.ITEM is None: raise TypeError("Can't hash uninitialized List type.") - return BuiltinADTType.__hash__(self) + return BuiltinADTType.__hash__(self) def __str__(self): return '%s(%s)' % (self.__class__.__name__, @@ -625,7 +625,7 @@ def _specialize(self, generic_types): ITEMTYPE = self._specialize_type(self.ITEM, generic_types) return self.__class__(ITEMTYPE) - + def _defl(self): return self._null @@ -644,7 +644,7 @@ # placeholders for types # make sure that each derived class has his own SELFTYPE_T # placeholder, because we want backends to distinguish that. - + SELFTYPE_T = object() ITEMTYPE_T = object() oopspec_name = 'list' @@ -694,7 +694,7 @@ def __hash__(self): if self.ITEM is None: raise TypeError("Can't hash uninitialized List type.") - return BuiltinADTType.__hash__(self) + return BuiltinADTType.__hash__(self) def __str__(self): return '%s(%s)' % (self.__class__.__name__, @@ -717,14 +717,15 @@ self.ITEM = ITEMTYPE self._init_methods() + @signature(types.any(), types.int(), returns=types.any()) def ll_newlist(self, length): from rpython.rtyper.ootypesystem import rlist return rlist.ll_newarray(self, length) - ll_newlist._annenforceargs_ = (None, int) def ll_convert_from_array(self, array): return array + class Dict(BuiltinADTType): # placeholders for types SELFTYPE_T = object() @@ -790,7 +791,7 @@ return False if not self._is_initialized() or not other._is_initialized(): return False # behave like a ForwardReference, i.e. compare by identity - return BuiltinADTType.__eq__(self, other) + return BuiltinADTType.__eq__(self, other) def __ne__(self, other): return not (self == other) @@ -812,7 +813,7 @@ self._KEYTYPE = KEYTYPE self._VALUETYPE = VALUETYPE self._init_methods() - + class CustomDict(Dict): def __init__(self, KEYTYPE=None, VALUETYPE=None): @@ -871,7 +872,7 @@ KEYTYPE = self._specialize_type(self._KEYTYPE, generic_types) VALUETYPE = self._specialize_type(self._VALUETYPE, generic_types) return self.__class__(KEYTYPE, VALUETYPE) - + # ____________________________________________________________ class _object(object): @@ -943,7 +944,7 @@ Class._null = nullruntimeclass class _instance(object): - + def __init__(self, INSTANCE): self.__dict__["_TYPE"] = INSTANCE INSTANCE._init_instance(self) @@ -958,7 +959,7 @@ DEFINST, meth = self._TYPE._lookup(name) if meth is not None: return meth._bound(DEFINST, self) - + self._TYPE._check_field(name) return self.__dict__[name] @@ -998,7 +999,7 @@ return self _enforce = _upcast - + def _downcast(self, INSTANCE): assert instanceof(self, INSTANCE) return self @@ -1023,7 +1024,7 @@ def __getattribute__(self, name): if name.startswith("_"): return object.__getattribute__(self, name) - + raise RuntimeError("Access to field in null object") def __setattr__(self, name, value): @@ -1189,7 +1190,7 @@ def __ne__(self, other): return not (self == other) - + def __hash__(self): return hash(frozendict(self.__dict__)) @@ -1227,7 +1228,7 @@ def __eq__(self, other): return self is other - + def __hash__(self): return id(self) @@ -1251,7 +1252,7 @@ class _meth(_callable): _bound_class = _bound_meth - + def __init__(self, METHOD, **attrs): assert isinstance(METHOD, Meth) _callable.__init__(self, METHOD, **attrs) @@ -1339,7 +1340,7 @@ return True else: return False - + def annotation_to_lltype(cls, ann): from rpython.annotator import model as annmodel return annmodel.annotation_to_lltype(ann) @@ -1605,7 +1606,7 @@ return len(self._list) def _ll_resize_ge(self, length): - # NOT_RPYTHON + # NOT_RPYTHON if len(self._list) < length: diff = length - len(self._list) self._list += [self._TYPE.ITEM._defl()] * diff @@ -1641,7 +1642,7 @@ class _null_list(_null_mixin(_list), _list): def __init__(self, LIST): - self.__dict__["_TYPE"] = LIST + self.__dict__["_TYPE"] = LIST class _array(_builtin_type): def __init__(self, ARRAY, length): @@ -1674,7 +1675,7 @@ class _null_array(_null_mixin(_array), _array): def __init__(self, ARRAY): - self.__dict__["_TYPE"] = ARRAY + self.__dict__["_TYPE"] = ARRAY class _dict(_builtin_type): def __init__(self, DICT): @@ -1772,7 +1773,7 @@ def ll_go_next(self): # NOT_RPYTHON self._check_stamp() - self._index += 1 + self._index += 1 if self._index >= len(self._items): return False else: @@ -1783,7 +1784,7 @@ self._check_stamp() assert 0 <= self._index < len(self._items) return self._items[self._index][0] - + def ll_current_value(self): # NOT_RPYTHON self._check_stamp() @@ -1843,7 +1844,7 @@ class _null_record(_null_mixin(_record), _record): def __init__(self, RECORD): - self.__dict__["_TYPE"] = RECORD + self.__dict__["_TYPE"] = RECORD def new(TYPE): @@ -1935,7 +1936,7 @@ def ooupcast(INSTANCE, instance): return instance._upcast(INSTANCE) - + def oodowncast(INSTANCE, instance): return instance._downcast(INSTANCE) @@ -1962,7 +1963,7 @@ def oostring(obj, base): """ Convert char, int, float, instances and str to str. - + Base is used only for formatting int: for other types is ignored and should be set to -1. For int only base 8, 10 and 16 are supported. diff --git a/rpython/rtyper/ootypesystem/rgeneric.py b/rpython/rtyper/ootypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/ootypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.ootypesystem import ootype From noreply at buildbot.pypy.org Fri Mar 22 11:00:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:18 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups in pypy.module Message-ID: <20130322100018.D32951C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62646:2299a8227a15 Date: 2013-03-22 04:29 -0400 http://bitbucket.org/pypy/pypy/changeset/2299a8227a15/ Log: cleanups in pypy.module diff --git a/pypy/module/_collections/__init__.py b/pypy/module/_collections/__init__.py --- a/pypy/module/_collections/__init__.py +++ b/pypy/module/_collections/__init__.py @@ -1,5 +1,3 @@ -import py - from pypy.interpreter.mixedmodule import MixedModule class Module(MixedModule): diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -221,7 +221,6 @@ self = global_state.origin self.h = h global_state.clear() - space = self.space try: frame = self.bottomframe w_result = frame.execute_frame() diff --git a/pypy/module/_demo/demo.py b/pypy/module/_demo/demo.py --- a/pypy/module/_demo/demo.py +++ b/pypy/module/_demo/demo.py @@ -5,7 +5,7 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rtyper.tool import rffi_platform from rpython.translator.tool.cbuild import ExternalCompilationInfo -import sys, math +import math time_t = rffi_platform.getsimpletype('time_t', '#include ', rffi.LONG) diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py --- a/pypy/module/_ffi/interp_funcptr.py +++ b/pypy/module/_ffi/interp_funcptr.py @@ -11,7 +11,7 @@ from rpython.rlib import libffi from rpython.rlib.clibffi import get_libc_name, StackCheckError, LibFFIError from rpython.rlib.rdynload import DLOpenError -from rpython.rlib.rarithmetic import intmask, r_uint +from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import we_are_translated from pypy.module._ffi.type_converter import FromAppLevelConverter, ToAppLevelConverter from pypy.module._rawffi.interp_rawffi import got_libffi_error diff --git a/pypy/module/_ffi/interp_struct.py b/pypy/module/_ffi/interp_struct.py --- a/pypy/module/_ffi/interp_struct.py +++ b/pypy/module/_ffi/interp_struct.py @@ -3,13 +3,12 @@ from rpython.rlib import libffi from rpython.rlib import jit from rpython.rlib.rgc import must_be_light_finalizer -from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_singlefloat, intmask +from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import operationerrfmt -from pypy.objspace.std.typetype import type_typedef -from pypy.module._ffi.interp_ffitype import W_FFIType, app_types +from pypy.module._ffi.interp_ffitype import W_FFIType from pypy.module._ffi.type_converter import FromAppLevelConverter, ToAppLevelConverter diff --git a/pypy/module/_ffi/type_converter.py b/pypy/module/_ffi/type_converter.py --- a/pypy/module/_ffi/type_converter.py +++ b/pypy/module/_ffi/type_converter.py @@ -1,7 +1,6 @@ from rpython.rlib import libffi from rpython.rlib import jit -from rpython.rlib.rarithmetic import intmask, r_uint -from rpython.rtyper.lltypesystem import rffi +from rpython.rlib.rarithmetic import r_uint from pypy.interpreter.error import operationerrfmt, OperationError from pypy.module._rawffi.structure import W_StructureInstance, W_Structure from pypy.module._ffi.interp_ffitype import app_types @@ -307,7 +306,7 @@ def get_unsigned_which_fits_into_a_signed(self, w_ffitype): """ Return type: lltype.Signed. - + We return Signed even if the input type is unsigned, because this way we get an app-level instead of a . """ diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -138,7 +138,6 @@ self.fdopenstream(stream, fd, mode) def direct_close(self): - space = self.space stream = self.stream if stream is not None: self.newlines = self.stream.getnewlines() diff --git a/pypy/module/_hashlib/interp_hashlib.py b/pypy/module/_hashlib/interp_hashlib.py --- a/pypy/module/_hashlib/interp_hashlib.py +++ b/pypy/module/_hashlib/interp_hashlib.py @@ -4,9 +4,8 @@ from pypy.interpreter.error import OperationError from rpython.tool.sourcetools import func_renamer from pypy.interpreter.baseobjspace import Wrappable -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib import rgc, ropenssl -from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rstring import StringBuilder from pypy.module.thread.os_lock import Lock diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py --- a/pypy/module/_io/__init__.py +++ b/pypy/module/_io/__init__.py @@ -1,10 +1,9 @@ from pypy.interpreter.mixedmodule import MixedModule -import sys class Module(MixedModule): appleveldefs = { - } + } interpleveldefs = { 'DEFAULT_BUFFER_SIZE': 'space.wrap(interp_iobase.DEFAULT_BUFFER_SIZE)', @@ -25,7 +24,7 @@ 'open': 'interp_io.open', 'IncrementalNewlineDecoder': 'interp_textio.W_IncrementalNewlineDecoder', - } + } def init(self, space): MixedModule.init(self, space) @@ -41,4 +40,3 @@ # at shutdown, flush all open streams. Ignore I/O errors. from pypy.module._io.interp_iobase import get_autoflushher get_autoflushher(space).flush_all(space) - diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -531,7 +531,7 @@ raise else: break - + if space.is_w(w_size, space.w_None): raise BlockingIOError() size = space.int_w(w_size) @@ -564,7 +564,6 @@ result_buffer = ['\0'] * n remaining = n written = 0 - data = None if current_size: for i in range(current_size): result_buffer[written + i] = self.buffer[self.pos + i] @@ -926,10 +925,6 @@ mode = GetSetProperty(W_BufferedWriter.mode_get_w), ) -def _forward_call(space, w_obj, method, __args__): - w_meth = self.getattr(w_obj, self.wrap(method)) - return self.call_args(w_meth, __args__) - def make_forwarding_method(method, writer=False, reader=False): @func_renamer(method + '_w') def method_w(self, space, __args__): diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -290,7 +290,7 @@ self._check_closed(space) if self.seekable < 0: try: - pos = os.lseek(self.fd, 0, os.SEEK_CUR) + os.lseek(self.fd, 0, os.SEEK_CUR) except OSError: self.seekable = 0 else: diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -149,8 +149,6 @@ # For backwards compatibility, a (slowish) readline(). limit = convert_size(space, w_limit) - old_size = -1 - has_peek = space.findattr(self, space.wrap("peek")) builder = StringBuilder() @@ -315,7 +313,6 @@ # ------------------------------------------------------------ class StreamHolder(object): - def __init__(self, w_iobase): self.w_iobase_ref = rweakref.ref(w_iobase) w_iobase.autoflusher = self @@ -325,7 +322,7 @@ if w_iobase is not None: try: space.call_method(w_iobase, 'flush') - except OperationError, e: + except OperationError: # Silencing all errors is bad, but getting randomly # interrupted here is equally as bad, and potentially # more frequent (because of shutdown issues). @@ -333,7 +330,6 @@ class AutoFlusher(object): - def __init__(self, space): self.streams = {} @@ -366,8 +362,5 @@ else: streamholder.autoflush(space) - def get_autoflushher(space): return space.fromcache(AutoFlusher) - - diff --git a/pypy/module/_minimal_curses/__init__.py b/pypy/module/_minimal_curses/__init__.py --- a/pypy/module/_minimal_curses/__init__.py +++ b/pypy/module/_minimal_curses/__init__.py @@ -8,9 +8,7 @@ py.test.skip("no _curses or _minimal_curses module") #no _curses at all from pypy.interpreter.mixedmodule import MixedModule -from pypy.module._minimal_curses import fficurses -from pypy.module._minimal_curses import interp_curses -from rpython.rlib.nonconst import NonConstant +from pypy.module._minimal_curses import fficurses # for side effects class Module(MixedModule): @@ -21,7 +19,7 @@ appleveldefs = { 'error' : 'app_curses.error', } - + interpleveldefs = { 'setupterm' : 'interp_curses.setupterm', 'tigetstr' : 'interp_curses.tigetstr', diff --git a/pypy/module/_random/__init__.py b/pypy/module/_random/__init__.py --- a/pypy/module/_random/__init__.py +++ b/pypy/module/_random/__init__.py @@ -1,11 +1,8 @@ -import py - from pypy.interpreter.mixedmodule import MixedModule class Module(MixedModule): appleveldefs = {} - + interpleveldefs = { 'Random' : 'interp_random.W_Random', - } - + } diff --git a/pypy/module/_rawffi/__init__.py b/pypy/module/_rawffi/__init__.py --- a/pypy/module/_rawffi/__init__.py +++ b/pypy/module/_rawffi/__init__.py @@ -1,15 +1,9 @@ - """ Low-level interface to clibffi """ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module._rawffi.interp_rawffi import W_CDLL -from rpython.rtyper.lltypesystem import lltype, rffi -from pypy.module._rawffi.tracker import Tracker -import sys class Module(MixedModule): - interpleveldefs = { 'CDLL' : 'interp_rawffi.W_CDLL', 'FuncPtr' : 'interp_rawffi.W_FuncPtr', @@ -52,6 +46,6 @@ ]: if hasattr(clibffi, name): Module.interpleveldefs[name] = "space.wrap(%r)" % getattr(clibffi, name) - + super(Module, cls).buildloaders() buildloaders = classmethod(buildloaders) diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py --- a/pypy/module/_socket/__init__.py +++ b/pypy/module/_socket/__init__.py @@ -1,6 +1,4 @@ -# Package initialisation from pypy.interpreter.mixedmodule import MixedModule -import sys class Module(MixedModule): @@ -31,11 +29,10 @@ getdefaulttimeout setdefaulttimeout """.split(): - if name in ('inet_pton', 'inet_ntop', - 'fromfd', 'socketpair', - ) and not hasattr(rsocket, name): + if name in ('inet_pton', 'inet_ntop', 'fromfd', 'socketpair') \ + and not hasattr(rsocket, name): continue - + Module.interpleveldefs[name] = 'interp_func.%s' % (name, ) for constant, value in rsocket.constants.iteritems(): diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -163,7 +163,7 @@ def bind_w(self, space, w_addr): """bind(address) - + Bind the socket to a local address. For IP sockets, the address is a pair (host, port); the host must refer to the local host. For raw packet sockets the address is a tuple (ifname, proto [,pkttype [,hatype]]) @@ -180,7 +180,7 @@ """ try: self.close() - except SocketError, e: + except SocketError: # cpython doesn't return any errors on close pass diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -190,7 +190,6 @@ return space.wrap("") filename = space.str_w(w_filename) - length = len(filename) if filename.endswith(".py"): n = len(filename) - 3 assert n >= 0 diff --git a/pypy/module/_winreg/__init__.py b/pypy/module/_winreg/__init__.py --- a/pypy/module/_winreg/__init__.py +++ b/pypy/module/_winreg/__init__.py @@ -1,5 +1,4 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module._winreg import interp_winreg from rpython.rlib.rwinreg import constants class Module(MixedModule): diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -188,7 +188,6 @@ The caller of this method must possess the SeBackupPrivilege security privilege. This function passes NULL for security_attributes to the API.""" hkey = hkey_w(w_hkey, space) - pSA = 0 ret = rwinreg.RegSaveKey(hkey, filename, None) if ret != 0: raiseWindowsError(space, ret, 'RegSaveKey') diff --git a/pypy/module/array/__init__.py b/pypy/module/array/__init__.py --- a/pypy/module/array/__init__.py +++ b/pypy/module/array/__init__.py @@ -1,5 +1,6 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.array.interp_array import types, W_ArrayBase + +from pypy.module.array.interp_array import types from pypy.objspace.std.model import registerimplementation for mytype in types.values(): @@ -7,7 +8,6 @@ class Module(MixedModule): - interpleveldefs = { 'array': 'interp_array.W_ArrayBase', 'ArrayType': 'interp_array.W_ArrayBase', diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -412,7 +412,6 @@ return space.wrap(cnt) def array_index__Array_ANY(space, self, w_val): - cnt = 0 for i in range(self.len): w_item = self.w_getitem(space, i) if space.is_true(space.eq(w_item, w_val)): diff --git a/pypy/module/clr/app_importer.py b/pypy/module/clr/app_importer.py --- a/pypy/module/clr/app_importer.py +++ b/pypy/module/clr/app_importer.py @@ -4,7 +4,6 @@ # Meta hooks can override the sys.path, frozen modules , built-in modules # To register a Meta Hook simply add importer object to sys.meta_path -import imp import sys import types @@ -69,8 +68,6 @@ mod.__name__ = fullname # add it to the modules dict sys.modules[fullname] = mod - else: - mod = sys.modules[fullname] # if it is a PACKAGE then we are to initialize the __path__ for the module # we won't deal with Packages here @@ -81,7 +78,7 @@ if not name.startswith("__"): try: iname = self.__name__ + '.' + name - mod = __import__(iname) + __import__(iname) except ImportError: pass return types.ModuleType.__getattribute__(self, name) diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py --- a/pypy/module/cpyext/__init__.py +++ b/pypy/module/cpyext/__init__.py @@ -1,8 +1,6 @@ from pypy.interpreter.mixedmodule import MixedModule -from rpython.rlib.objectmodel import we_are_translated from pypy.module.cpyext.state import State from pypy.module.cpyext import api -from rpython.rtyper.lltypesystem import rffi, lltype class Module(MixedModule): interpleveldefs = { 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 @@ -112,7 +112,7 @@ def try_getattr(space, w_obj, w_name): try: return space.getattr(w_obj, w_name) - except OperationError, e: + except OperationError: # ugh, but blame CPython :-/ this is supposed to emulate # hasattr, which eats all exceptions. return None @@ -164,8 +164,7 @@ # Try to import parent package try: - w_parent = absolute_import(space, ctxt_package, 0, - None, tentative=False) + absolute_import(space, ctxt_package, 0, None, tentative=False) except OperationError, e: if not e.match(space, space.w_ImportError): raise @@ -703,7 +702,6 @@ namepath = modulename.split('.') subname = namepath[-1] parent_name = '.'.join(namepath[:-1]) - parent = None if parent_name: w_parent = check_sys_modules_w(space, parent_name) if w_parent is None: @@ -1005,7 +1003,6 @@ Load a module from a compiled file, execute it, and return its module object. """ - w = space.wrap if magic != get_pyc_magic(space): raise operationerrfmt(space.w_ImportError, "Bad magic number in %s", cpathname) diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py --- a/pypy/module/marshal/interp_marshal.py +++ b/pypy/module/marshal/interp_marshal.py @@ -235,7 +235,6 @@ lng = len(lst_w) self.put_int(lng) idx = 0 - space = self.space while idx < lng: w_obj = lst_w[idx] self.space.marshal_w(w_obj, self) diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -1,7 +1,7 @@ import math import sys -from rpython.rlib import rfloat, unroll +from rpython.rlib import rfloat from pypy.interpreter.error import OperationError class State: 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 @@ -10,8 +10,7 @@ from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem, raw_storage_getitem) from rpython.rlib.objectmodel import specialize -from rpython.rlib.rarithmetic import (widen, byteswap, r_ulonglong, - most_neg_value_of) +from rpython.rlib.rarithmetic import widen, byteswap, r_ulonglong from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rstruct.runpack import runpack from rpython.rlib.rstruct.nativefmttable import native_is_bigendian diff --git a/pypy/module/mmap/__init__.py b/pypy/module/mmap/__init__.py --- a/pypy/module/mmap/__init__.py +++ b/pypy/module/mmap/__init__.py @@ -1,5 +1,4 @@ from pypy.interpreter.mixedmodule import MixedModule -from rpython.rlib import rmmap class Module(MixedModule): interpleveldefs = { @@ -14,13 +13,11 @@ appleveldefs = { } - + def buildloaders(cls): - from pypy.module.mmap import interp_mmap + from rpython.rlib import rmmap for constant, value in rmmap.constants.iteritems(): if isinstance(value, (int, long)): Module.interpleveldefs[constant] = "space.wrap(%r)" % value - super(Module, cls).buildloaders() buildloaders = classmethod(buildloaders) - diff --git a/pypy/module/operator/__init__.py b/pypy/module/operator/__init__.py --- a/pypy/module/operator/__init__.py +++ b/pypy/module/operator/__init__.py @@ -1,5 +1,4 @@ -from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule class Module(MixedModule): """Operator Builtin Module. """ @@ -10,19 +9,19 @@ def __init__(self, space, w_name): def create_lambda(name, alsoname): return lambda space : self.getdictvalue(space, alsoname) - + MixedModule.__init__(self, space, w_name) for name, alsoname in self.mapping.iteritems(): self.loaders[name] = create_lambda(name, alsoname) - appleveldefs = {} - + appleveldefs = {} + app_names = ['__delslice__', '__getslice__', '__repeat__', '__setslice__', 'countOf', 'delslice', 'getslice', 'indexOf', 'isMappingType', 'isNumberType', 'isSequenceType', 'repeat', 'setslice', 'attrgetter', 'itemgetter', 'methodcaller', - ] + ] for name in app_names: appleveldefs[name] = 'app_operator.%s' % name @@ -45,52 +44,52 @@ interpleveldefs[name] = 'interp_operator.%s' % name mapping = { - '__abs__' : 'abs', - '__add__' : 'add', - '__and__' : 'and_', - '__concat__' : 'concat', - '__contains__' : 'contains', - 'sequenceIncludes' : 'contains', - '__delitem__' : 'delitem', - '__div__' : 'div', - '__eq__' : 'eq', - '__floordiv__' : 'floordiv', - '__ge__' : 'ge', - '__getitem__' : 'getitem', - '__gt__' : 'gt', - '__inv__' : 'inv', - '__invert__' : 'invert', - '__le__' : 'le', - '__lshift__' : 'lshift', - '__lt__' : 'lt', - '__mod__' : 'mod', - '__mul__' : 'mul', - '__ne__' : 'ne', - '__neg__' : 'neg', - '__not__' : 'not_', - '__or__' : 'or_', - '__pos__' : 'pos', - '__pow__' : 'pow', - '__rshift__' : 'rshift', - '__setitem__' : 'setitem', - '__sub__' : 'sub', - '__truediv__' : 'truediv', - '__xor__' : 'xor', - # in-place - '__iadd__' : 'iadd', - '__iand__' : 'iand', - '__iconcat__' : 'iconcat', - '__idiv__' : 'idiv', - '__ifloordiv__' : 'ifloordiv', - '__ilshift__' : 'ilshift', - '__imod__' : 'imod', - '__imul__' : 'imul', - '__ior__' : 'ior', - '__ipow__' : 'ipow', - '__irepeat__' : 'irepeat', - '__irshift__' : 'irshift', - '__isub__' : 'isub', - '__itruediv__' : 'itruediv', - '__ixor__' : 'ixor', + '__abs__' : 'abs', + '__add__' : 'add', + '__and__' : 'and_', + '__concat__' : 'concat', + '__contains__' : 'contains', + 'sequenceIncludes' : 'contains', + '__delitem__' : 'delitem', + '__div__' : 'div', + '__eq__' : 'eq', + '__floordiv__' : 'floordiv', + '__ge__' : 'ge', + '__getitem__' : 'getitem', + '__gt__' : 'gt', + '__inv__' : 'inv', + '__invert__' : 'invert', + '__le__' : 'le', + '__lshift__' : 'lshift', + '__lt__' : 'lt', + '__mod__' : 'mod', + '__mul__' : 'mul', + '__ne__' : 'ne', + '__neg__' : 'neg', + '__not__' : 'not_', + '__or__' : 'or_', + '__pos__' : 'pos', + '__pow__' : 'pow', + '__rshift__' : 'rshift', + '__setitem__' : 'setitem', + '__sub__' : 'sub', + '__truediv__' : 'truediv', + '__xor__' : 'xor', + # in-place + '__iadd__' : 'iadd', + '__iand__' : 'iand', + '__iconcat__' : 'iconcat', + '__idiv__' : 'idiv', + '__ifloordiv__' : 'ifloordiv', + '__ilshift__' : 'ilshift', + '__imod__' : 'imod', + '__imul__' : 'imul', + '__ior__' : 'ior', + '__ipow__' : 'ipow', + '__irepeat__' : 'irepeat', + '__irshift__' : 'irshift', + '__isub__' : 'isub', + '__itruediv__' : 'itruediv', + '__ixor__' : 'ixor', } diff --git a/pypy/module/oracle/conftest.py b/pypy/module/oracle/conftest.py --- a/pypy/module/oracle/conftest.py +++ b/pypy/module/oracle/conftest.py @@ -1,5 +1,3 @@ -from rpython.rtyper.tool.rffi_platform import CompilationError -import py import os def pytest_addoption(parser): diff --git a/pypy/module/oracle/transform.py b/pypy/module/oracle/transform.py --- a/pypy/module/oracle/transform.py +++ b/pypy/module/oracle/transform.py @@ -1,5 +1,5 @@ from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.module.oracle import roci, config +from pypy.module.oracle import roci def OracleNumberToPythonFloat(environment, valueptr): "Return a Python float object given an oracle number" diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -1,8 +1,7 @@ -# Package initialisation from pypy.interpreter.mixedmodule import MixedModule from rpython.rtyper.module.ll_os import RegisterOs -import os, sys +import os exec 'import %s as posix' % os.name # this is the list of function which is *not* present in the posix module of diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -4,20 +4,17 @@ from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 -from pypy.interpreter.error import operationerrfmt from rpython.rtyper.module.ll_os import RegisterOs from rpython.rtyper.module import ll_os_stat -from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rtyper.tool import rffi_platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo from pypy.module.sys.interp_encoding import getfilesystemencoding -import os, sys +import os +import sys _WIN32 = sys.platform == 'win32' if _WIN32: from rpython.rlib.rwin32 import _MAX_ENV - + c_int = "c_int" # CPython 2.7 semantics are too messy to follow exactly, @@ -854,17 +851,6 @@ raise raise OperationError(space.w_TypeError, space.wrap(msg)) -def setsid(space): - """setsid() -> pid - - Creates a new session with this process as the leader. - """ - try: - result = os.setsid() - except OSError, e: - raise wrap_oserror(space, e) - return space.wrap(result) - def uname(space): """ uname() -> (sysname, nodename, release, version, machine) @@ -1161,7 +1147,7 @@ def getloadavg(space): try: load = os.getloadavg() - except OSError, e: + except OSError: raise OperationError(space.w_OSError, space.wrap("Load averages are unobtainable")) return space.newtuple([space.wrap(load[0]), diff --git a/pypy/module/pwd/interp_pwd.py b/pypy/module/pwd/interp_pwd.py --- a/pypy/module/pwd/interp_pwd.py +++ b/pypy/module/pwd/interp_pwd.py @@ -1,8 +1,8 @@ from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rtyper.tool import rffi_platform from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.error import operationerrfmt from rpython.rlib.rarithmetic import intmask eci = ExternalCompilationInfo( diff --git a/pypy/module/pyexpat/__init__.py b/pypy/module/pyexpat/__init__.py --- a/pypy/module/pyexpat/__init__.py +++ b/pypy/module/pyexpat/__init__.py @@ -1,5 +1,3 @@ -import py - from pypy.interpreter.mixedmodule import MixedModule class ErrorsModule(MixedModule): diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py --- a/pypy/module/signal/__init__.py +++ b/pypy/module/signal/__init__.py @@ -1,7 +1,6 @@ +from pypy.interpreter.mixedmodule import MixedModule -from pypy.interpreter.mixedmodule import MixedModule import os -import signal as cpy_signal class Module(MixedModule): interpleveldefs = { diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py --- a/pypy/module/sys/__init__.py +++ b/pypy/module/sys/__init__.py @@ -91,18 +91,18 @@ if sys.platform == 'win32': interpleveldefs['winver'] = 'version.get_winver(space)' interpleveldefs['getwindowsversion'] = 'vm.getwindowsversion' - + appleveldefs = { - 'excepthook' : 'app.excepthook', - '__excepthook__' : 'app.excepthook', - 'exit' : 'app.exit', + 'excepthook' : 'app.excepthook', + '__excepthook__' : 'app.excepthook', + 'exit' : 'app.exit', 'exitfunc' : 'app.exitfunc', 'callstats' : 'app.callstats', 'copyright' : 'app.copyright_str', 'flags' : 'app.null_sysflags', } - def setbuiltinmodule(self, w_module, name): + def setbuiltinmodule(self, w_module, name): w_name = self.space.wrap(name) w_modules = self.get('modules') self.space.setitem(w_modules, w_name, w_module) @@ -120,8 +120,8 @@ def getmodule(self, name): space = self.space - w_modules = self.get('modules') - try: + w_modules = self.get('modules') + try: return space.getitem(w_modules, space.wrap(name)) except OperationError, e: if not e.match(space, space.w_KeyError): diff --git a/pypy/module/sys/currentframes.py b/pypy/module/sys/currentframes.py --- a/pypy/module/sys/currentframes.py +++ b/pypy/module/sys/currentframes.py @@ -48,7 +48,6 @@ This function should be used for specialized purposes only.""" w_result = space.newdict() w_fake_frame = app.wget(space, "fake_frame") - w_fake_code = app.wget(space, "fake_code") ecs = space.threadlocals.getallvalues() for thread_ident, ec in ecs.items(): vref = ec.topframeref @@ -61,7 +60,7 @@ vref = f.f_backref else: frames.append(None) - # + w_topframe = space.wrap(None) w_prevframe = None for f in frames: @@ -71,7 +70,7 @@ else: space.setattr(w_prevframe, space.wrap('f_back'), w_nextframe) w_prevframe = w_nextframe - # + space.setitem(w_result, space.wrap(thread_ident), w_topframe) diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -1,8 +1,6 @@ """ Implementation of interpreter-level 'sys' routines. """ -import sys - from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import unwrap_spec, WrappedDefault @@ -11,15 +9,6 @@ # ____________________________________________________________ -def setbuiltinmodule(w_module, name): - """ put a module into the modules builtin_modules dicts """ - if builtin_modules[name] is None: - builtin_modules[name] = space.unwrap(w_module) - else: - assert builtin_modules[name] is space.unwrap(w_module), ( - "trying to change the builtin-in module %r" % (name,)) - space.setitem(w_modules, space.wrap(name), w_module) - @unwrap_spec(w_depth = WrappedDefault(0)) def _getframe(space, w_depth): """Return a frame object from the call stack. If optional integer depth is diff --git a/pypy/module/termios/__init__.py b/pypy/module/termios/__init__.py --- a/pypy/module/termios/__init__.py +++ b/pypy/module/termios/__init__.py @@ -1,7 +1,4 @@ - from pypy.interpreter.mixedmodule import MixedModule -import termios -from rpython.rlib.nonconst import NonConstant class Module(MixedModule): "This module provides an interface to the Posix calls for tty I/O control.\n\ @@ -15,7 +12,7 @@ appleveldefs = { } - + interpleveldefs = { 'tcdrain' : 'interp_termios.tcdrain', 'tcflow' : 'interp_termios.tcflow', @@ -26,13 +23,10 @@ 'error' : 'space.fromcache(interp_termios.Cache).w_error', } -import termios -from pypy.module.termios import interp_termios - # XXX this is extremaly not-portable, but how to prevent this? +import termios for i in dir(termios): val = getattr(termios, i) if i.isupper() and type(val) is int: Module.interpleveldefs[i] = "space.wrap(%s)" % val - diff --git a/pypy/module/termios/interp_termios.py b/pypy/module/termios/interp_termios.py --- a/pypy/module/termios/interp_termios.py +++ b/pypy/module/termios/interp_termios.py @@ -4,10 +4,7 @@ """ from pypy.interpreter.gateway import unwrap_spec -from pypy.interpreter.error import OperationError, wrap_oserror -from rpython.rtyper.module import ll_termios -from rpython.rlib.objectmodel import we_are_translated -import os +from pypy.interpreter.error import wrap_oserror from rpython.rlib import rtermios import termios diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py --- a/pypy/module/thread/os_local.py +++ b/pypy/module/thread/os_local.py @@ -1,6 +1,6 @@ import weakref from rpython.rlib import jit -from pypy.interpreter.baseobjspace import Wrappable, W_Root +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.typedef import (TypeDef, interp2app, GetSetProperty, descr_get_dict) diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py --- a/pypy/module/thread/os_thread.py +++ b/pypy/module/thread/os_thread.py @@ -183,7 +183,7 @@ try: rthread.gc_thread_prepare() # (this has no effect any more) ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) - except Exception, e: + except Exception: bootstrapper.release() # normally called by the new thread raise except rthread.error: diff --git a/pypy/module/time/__init__.py b/pypy/module/time/__init__.py --- a/pypy/module/time/__init__.py +++ b/pypy/module/time/__init__.py @@ -1,17 +1,13 @@ -# Package initialisation from pypy.interpreter.mixedmodule import MixedModule -import time - class Module(MixedModule): """time module""" appleveldefs = { } - + interpleveldefs = { - 'clock' : 'interp_time.clock', - 'time' : 'interp_time.time_', - 'sleep' : 'interp_time.sleep', + 'clock' : 'interp_time.clock', + 'time' : 'interp_time.time_', + 'sleep' : 'interp_time.sleep', } - diff --git a/pypy/module/unicodedata/__init__.py b/pypy/module/unicodedata/__init__.py --- a/pypy/module/unicodedata/__init__.py +++ b/pypy/module/unicodedata/__init__.py @@ -1,4 +1,5 @@ from pypy.interpreter.mixedmodule import MixedModule + # This is the default unicodedb used in various places: # - the unicode type # - the regular expression engine diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -52,10 +52,8 @@ raise OperationError(space.w_KeyError, space.wrap(name)) assert isinstance(w_zipimporter, W_ZipImporter) w = space.wrap - values = {} w_d = space.newdict() for key, info in w_zipimporter.zip_file.NameToInfo.iteritems(): - w_values = space.newdict() space.setitem(w_d, w(key), space.newtuple([ w(info.filename), w(info.compress_type), w(info.compress_size), w(info.file_size), w(info.file_offset), w(info.dostime), @@ -350,7 +348,6 @@ @unwrap_spec(name='str0') def descr_new_zipimporter(space, w_type, name): - w = space.wrap ok = False parts_ends = [i for i in range(0, len(name)) if name[i] == os.path.sep or name[i] == ZIPSEP] From noreply at buildbot.pypy.org Fri Mar 22 11:00:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:20 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups in pypy.interpreter Message-ID: <20130322100020.321981C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62647:cd694cb03816 Date: 2013-03-22 05:46 -0400 http://bitbucket.org/pypy/pypy/changeset/cd694cb03816/ Log: cleanups in pypy.interpreter diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -629,7 +629,6 @@ # start a prompt if requested if inspect_requested(): - inteactive = False try: from _pypy_interact import interactive_console success = run_toplevel(interactive_console, mainmodule) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -336,7 +336,6 @@ if e.match(self, self.w_KeyError): continue raise - modname = self.str_w(w_modname) mod = self.interpclass_w(w_mod) if isinstance(mod, Module) and not mod.startup_called: mod.init(self) @@ -429,7 +428,6 @@ def get_builtinmodule_to_install(self): """NOT_RPYTHON""" - from pypy.tool.lib_pypy import LIB_PYPY try: return self._builtinmodule_list except AttributeError: diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -1,6 +1,5 @@ import sys from pypy.interpreter.error import OperationError -from rpython.rlib.rarithmetic import LONG_BIT from rpython.rlib.unroll import unrolling_iterable from rpython.rlib import jit diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -12,7 +12,6 @@ from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized funccallunrolling = unrolling_iterable(range(4)) @@ -309,7 +308,6 @@ return nt([new_inst, nt(tup_base), nt(tup_state)]) def descr_function__setstate__(self, space, w_args): - from pypy.interpreter.pycode import PyCode args_w = space.unpackiterable(w_args) try: (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs, @@ -576,7 +574,6 @@ w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('method_new') - w = space.wrap w_instance = self.w_instance or space.w_None function = space.interpclass_w(self.w_function) if isinstance(function, Function) and isinstance(function.code, BuiltinCode): diff --git a/pypy/interpreter/interactive.py b/pypy/interpreter/interactive.py --- a/pypy/interpreter/interactive.py +++ b/pypy/interpreter/interactive.py @@ -1,5 +1,4 @@ -from pypy.interpreter import error -from pypy.interpreter import baseobjspace, module, main +from pypy.interpreter import main, error import sys import code import time @@ -126,7 +125,6 @@ #banner = "Python %s in pypy\n%s / %s" % ( # sys.version, self.__class__.__name__, # self.space.__class__.__name__) - w_sys = self.space.sys major, minor, micro, tag, rev = self.space.unwrap(self.space.sys.get('pypy_version_info')) elapsed = time.time() - self.space._starttime version = "%d.%d.%d" % (major, minor, micro) diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -5,8 +5,6 @@ from pypy.interpreter.baseobjspace import W_Root import os, sys -import inspect - class MixedModule(Module): applevel_name = None expose__file__attribute = True diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -15,9 +15,8 @@ CO_GENERATOR, CO_CONTAINSGLOBALS) from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT from rpython.rlib.rarithmetic import intmask -from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import compute_hash from rpython.rlib import jit -from rpython.rlib.objectmodel import compute_hash class BytecodeCorruption(Exception): diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -2,7 +2,7 @@ """ from rpython.tool.pairtype import extendabletype -from pypy.interpreter import eval, baseobjspace, pycode +from pypy.interpreter import eval, pycode from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.executioncontext import ExecutionContext From noreply at buildbot.pypy.org Fri Mar 22 11:00:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:21 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups in rpython.rlib Message-ID: <20130322100021.9633A1C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62648:aedad688feca Date: 2013-03-22 02:29 -0400 http://bitbucket.org/pypy/pypy/changeset/aedad688feca/ Log: cleanups in rpython.rlib diff --git a/rpython/rlib/_jit_vref.py b/rpython/rlib/_jit_vref.py --- a/rpython/rlib/_jit_vref.py +++ b/rpython/rlib/_jit_vref.py @@ -1,9 +1,7 @@ from rpython.annotator import model as annmodel from rpython.tool.pairtype import pairtype -from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.rclass import getinstancerepr from rpython.rtyper.rmodel import Repr -from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.lltypesystem.rclass import OBJECTPTR from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.error import TyperError diff --git a/rpython/rlib/_rffi_stacklet.py b/rpython/rlib/_rffi_stacklet.py --- a/rpython/rlib/_rffi_stacklet.py +++ b/rpython/rlib/_rffi_stacklet.py @@ -4,7 +4,6 @@ from rpython.rtyper.tool import rffi_platform from rpython.rlib.rarithmetic import is_emulated_long from rpython.conftest import cdir -import sys cdir = py.path.local(cdir) diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py --- a/rpython/rlib/_rsocket_rffi.py +++ b/rpython/rlib/_rsocket_rffi.py @@ -3,7 +3,6 @@ from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.tool import rffi_platform as platform from rpython.rtyper.lltypesystem.rffi import CCHARP -from rpython.rlib.rposix import get_errno as geterrno from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.translator.platform import platform as target_platform @@ -635,6 +634,8 @@ def gai_strerror_str(errno): return rwin32.FormatError(errno) else: + from rpython.rlib.rposix import get_errno as geterrno + socket_strerror_str = os.strerror def gai_strerror_str(errno): return rffi.charp2str(gai_strerror(errno)) diff --git a/rpython/rlib/_rweakkeydict.py b/rpython/rlib/_rweakkeydict.py --- a/rpython/rlib/_rweakkeydict.py +++ b/rpython/rlib/_rweakkeydict.py @@ -1,13 +1,11 @@ from rpython.flowspace.model import Constant from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rdict from rpython.rtyper.lltypesystem.llmemory import weakref_create, weakref_deref -from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.rclass import getinstancerepr from rpython.rtyper.rmodel import Repr from rpython.rlib.rweakref import RWeakKeyDictionary from rpython.rlib import jit from rpython.rlib.objectmodel import compute_identity_hash -from rpython.rlib.objectmodel import we_are_translated # Warning: this implementation of RWeakKeyDictionary is not exactly diff --git a/rpython/rlib/_rweakvaldict.py b/rpython/rlib/_rweakvaldict.py --- a/rpython/rlib/_rweakvaldict.py +++ b/rpython/rlib/_rweakvaldict.py @@ -1,9 +1,7 @@ from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rclass, rdict +from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rdict from rpython.rtyper.lltypesystem.llmemory import weakref_create, weakref_deref -from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.rclass import getinstancerepr -from rpython.rtyper.rint import signed_repr from rpython.rtyper.rmodel import Repr from rpython.rlib.rweakref import RWeakValueDictionary from rpython.rlib import jit diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py --- a/rpython/rlib/clibffi.py +++ b/rpython/rlib/clibffi.py @@ -5,7 +5,7 @@ from rpython.rtyper.tool import rffi_platform from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.rarithmetic import intmask, r_uint, is_emulated_long +from rpython.rlib.rarithmetic import intmask, is_emulated_long from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rmmap import alloc from rpython.rlib.rdynload import dlopen, dlclose, dlsym, dlsym_byordinal diff --git a/rpython/rlib/debug.py b/rpython/rlib/debug.py --- a/rpython/rlib/debug.py +++ b/rpython/rlib/debug.py @@ -296,7 +296,7 @@ _about_ = mark_dict_non_null def compute_result_annotation(self, s_dict): - from rpython.annotator.model import SomeDict, s_None + from rpython.annotator.model import SomeDict assert isinstance(s_dict, SomeDict) s_dict.dictdef.force_non_null = True diff --git a/rpython/rlib/jit_hooks.py b/rpython/rlib/jit_hooks.py --- a/rpython/rlib/jit_hooks.py +++ b/rpython/rlib/jit_hooks.py @@ -4,7 +4,7 @@ from rpython.rtyper.lltypesystem import llmemory, lltype from rpython.rtyper.lltypesystem import rclass from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr,\ - cast_base_ptr_to_instance, llstr, hlstr + cast_base_ptr_to_instance, llstr from rpython.rlib.objectmodel import specialize def register_helper(s_result): diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -5,7 +5,6 @@ from __future__ import absolute_import -import py import sys import types import math diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -1,5 +1,5 @@ -from rpython.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong -from rpython.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int +from rpython.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong +from rpython.rlib.rarithmetic import ovfcheck, r_longlong, widen from rpython.rlib.rarithmetic import most_neg_value_of_same_type from rpython.rlib.rfloat import isinf, isnan from rpython.rlib.rstring import StringBuilder diff --git a/rpython/rlib/rcomplex.py b/rpython/rlib/rcomplex.py --- a/rpython/rlib/rcomplex.py +++ b/rpython/rlib/rcomplex.py @@ -1,5 +1,5 @@ import math -from math import fabs, pi, e +from math import fabs from rpython.rlib.rfloat import copysign, asinh, log1p, isfinite, isinf, isnan from rpython.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN from rpython.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -119,7 +119,7 @@ # Never called raise KeyError(index) -if _WIN32: +else: # _WIN32 DLLHANDLE = rwin32.HMODULE RTLD_GLOBAL = None @@ -153,5 +153,5 @@ raise KeyError(index) # XXX rffi.cast here... return res - + LoadLibrary = rwin32.LoadLibrary diff --git a/rpython/rlib/rerased.py b/rpython/rlib/rerased.py --- a/rpython/rlib/rerased.py +++ b/rpython/rlib/rerased.py @@ -18,13 +18,11 @@ from rpython.annotator import model as annmodel from rpython.tool.pairtype import pairtype from rpython.rtyper.extregistry import ExtRegistryEntry -from rpython.rtyper.rclass import getinstancerepr from rpython.rtyper.rmodel import Repr +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.lltypesystem.rclass import OBJECTPTR -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.error import TyperError from rpython.rlib.rarithmetic import is_valid_int +from rpython.rlib.debug import ll_assert def erase_int(x): @@ -161,8 +159,6 @@ return hop.args_r[0].rtype_unerase_int(hop, v) def ll_unerase_int(gcref): - from rpython.rtyper.lltypesystem.lloperation import llop - from rpython.rlib.debug import ll_assert x = llop.cast_ptr_to_int(lltype.Signed, gcref) ll_assert((x&1) != 0, "unerased_int(): not an integer") return x >> 1 diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -5,7 +5,6 @@ from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated, enforceargs, specialize -from rpython.rlib.nonconst import NonConstant from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory @@ -100,7 +99,6 @@ return annmodel.SomePtr(lltype.Ptr(ARRAY_TYPEID_MAP)) def specialize_call(self, hop): - from rpython.memory.gc.base import ARRAY_TYPEID_MAP hop.exception_is_here() return hop.genop('gc_heap_stats', [], resulttype=hop.r_result) diff --git a/rpython/rlib/rmd5.py b/rpython/rlib/rmd5.py --- a/rpython/rlib/rmd5.py +++ b/rpython/rlib/rmd5.py @@ -25,7 +25,7 @@ Converted to RPython by arigo. """ -from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask +from rpython.rlib.rarithmetic import r_uint, r_ulonglong if r_uint.BITS == 32: diff --git a/rpython/rlib/rope.py b/rpython/rlib/rope.py --- a/rpython/rlib/rope.py +++ b/rpython/rlib/rope.py @@ -1,9 +1,9 @@ import py import sys +import math + from rpython.rlib.rarithmetic import intmask, ovfcheck from rpython.rlib.rarithmetic import r_uint, LONG_BIT -from rpython.rlib.objectmodel import we_are_translated -import math LOG2 = math.log(2) NBITS = int(math.log(sys.maxint) / LOG2) + 2 @@ -696,7 +696,6 @@ if i != start: nodelist.append(LiteralUnicodeNode(uni[start:i])) start = i - strchunk = [] while i < length: c = ord(uni[i]) if c >= 256: @@ -973,28 +972,24 @@ def nextchar(self): node = self.getnode() - index = self.index result = node.getchar(self.index) self.advance_index() return result def nextunichar(self): node = self.getnode() - index = self.index result = node.getunichar(self.index) self.advance_index() return result def nextrope(self): node = self.getnode() - index = self.index result = node.getrope(self.index) self.advance_index() return result def nextint(self): node = self.getnode() - index = self.index result = node.getint(self.index) self.advance_index() return result @@ -1064,7 +1059,6 @@ assert 0 <= items < node.length() while isinstance(node, BinaryConcatNode): self.stack.append(node) - right = node.right left = node.left if items >= left.length(): items -= left.length() @@ -1085,7 +1079,7 @@ if self.index == -1: self.seekback(0) return self.node - + nextchar = make_seekable_method("getchar") nextunichar = make_seekable_method("getunichar") nextint = make_seekable_method("getint") diff --git a/rpython/rlib/rpoll.py b/rpython/rlib/rpoll.py --- a/rpython/rlib/rpoll.py +++ b/rpython/rlib/rpoll.py @@ -5,11 +5,9 @@ function that directly takes a dictionary as argument. """ -import os from rpython.rlib import _rsocket_rffi as _c +from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import intmask, r_uint -import math # ____________________________________________________________ # events diff --git a/rpython/rlib/rsha.py b/rpython/rlib/rsha.py --- a/rpython/rlib/rsha.py +++ b/rpython/rlib/rsha.py @@ -13,7 +13,7 @@ converted to RPython by arigo. """ -from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask +from rpython.rlib.rarithmetic import r_uint, r_ulonglong from rpython.rlib.unroll import unrolling_iterable # We reuse helpers from rmd5 too diff --git a/rpython/rlib/rstack.py b/rpython/rlib/rstack.py --- a/rpython/rlib/rstack.py +++ b/rpython/rlib/rstack.py @@ -3,17 +3,13 @@ RPython-compliant way, intended mostly for use by the Stackless PyPy. """ -import inspect - import py from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import r_uint from rpython.rlib import rgc -from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.controllerentry import Controller, SomeControlledInstance from rpython.conftest import cdir from rpython.translator.tool.cbuild import ExternalCompilationInfo diff --git a/rpython/rlib/rtimer.py b/rpython/rlib/rtimer.py --- a/rpython/rlib/rtimer.py +++ b/rpython/rlib/rtimer.py @@ -1,6 +1,6 @@ import time -from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint +from rpython.rlib.rarithmetic import r_longlong, r_uint from rpython.rlib.rarithmetic import intmask, longlongmask from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, rffi diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -876,7 +876,6 @@ else: # begin base64-encoded section inShift = 1 shiftOutStartPos = pos - 1 - bitsleft = 0 elif _utf7_DECODE_DIRECT(oc): # character decodes at itself result.append(unichr(oc)) @@ -894,7 +893,6 @@ if (surrogate or base64bits >= 6 or (base64bits > 0 and base64buffer != 0)): - endinpos = size msg = "unterminated shift sequence" res, pos = errorhandler(errors, 'utf-7', msg, s, shiftOutStartPos, pos) result.append(res) @@ -1118,7 +1116,6 @@ def hexescape(builder, s, pos, digits, encoding, errorhandler, message, errors): - import sys chr = 0 if pos + digits > len(s): message = "end of string in escape sequence" diff --git a/rpython/rlib/rweakref.py b/rpython/rlib/rweakref.py --- a/rpython/rlib/rweakref.py +++ b/rpython/rlib/rweakref.py @@ -68,7 +68,6 @@ from rpython.rtyper import extregistry from rpython.annotator import model as annmodel -from rpython.annotator.bookkeeper import getbookkeeper from rpython.tool.pairtype import pairtype class Entry(extregistry.ExtRegistryEntry): diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -2,6 +2,9 @@ Common types, functions from core win32 libraries, such as kernel32 """ +import os +import errno + from rpython.rtyper.tool import rffi_platform from rpython.tool.udir import udir from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -9,7 +12,6 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rarithmetic import intmask from rpython.rlib import jit -import os, sys, errno # This module can be imported on any platform, # but most symbols are not usable... From noreply at buildbot.pypy.org Fri Mar 22 11:00:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:23 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups in rpython.annotator Message-ID: <20130322100023.00ED91C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62649:c154acb97f6a Date: 2013-03-22 05:18 -0400 http://bitbucket.org/pypy/pypy/changeset/c154acb97f6a/ Log: cleanups in rpython.annotator diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -1,6 +1,7 @@ from __future__ import absolute_import import types + from rpython.tool.ansi_print import ansi_log from rpython.tool.pairtype import pair from rpython.tool.error import (format_blocked_annotation_error, @@ -10,12 +11,13 @@ from rpython.translator import simplify, transform from rpython.annotator import model as annmodel, signature, unaryop, binaryop from rpython.annotator.bookkeeper import Bookkeeper + import py log = py.log.Producer("annrpython") py.log.setconsumer("annrpython", ansi_log) +FAIL = object() -FAIL = object() class RPythonAnnotator(object): """Block annotator for RPython. diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -15,7 +15,6 @@ from rpython.annotator.model import SomeAddress, SomeTypedAddressAccess from rpython.annotator.model import SomeSingleFloat, SomeLongFloat, SomeType from rpython.annotator.model import unionof, UnionError, missing_operation -from rpython.annotator.model import TLS from rpython.annotator.model import read_can_only_throw from rpython.annotator.model import add_knowntypedata, merge_knowntypedata from rpython.annotator.model import SomeGenericCallable diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -12,7 +12,7 @@ SomeInteger, SomeOOInstance, SomeOOObject, TLS, SomeAddress, \ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ - SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ + SomeUnicodeString, SomeList, HarmlesslyBlocked, \ SomeWeakRef, lltype_to_annotation, SomeType, SomeByteArray from rpython.annotator.classdef import InstanceSource, ClassDef from rpython.annotator.listdef import ListDef, ListItem @@ -25,7 +25,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.ootypesystem import ootype from rpython.rtyper import extregistry -from rpython.tool.identity_dict import identity_dict + class Stats(object): @@ -758,9 +758,7 @@ except AttributeError: return None - def delayed_imports(): # import ordering hack global BUILTIN_ANALYZERS from rpython.annotator.builtin import BUILTIN_ANALYZERS - diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -1,10 +1,10 @@ """ Built-in functions. """ +import sys -import sys from rpython.annotator.model import SomeInteger, SomeObject, SomeChar, SomeBool -from rpython.annotator.model import SomeString, SomeTuple, s_Bool, SomeBuiltin +from rpython.annotator.model import SomeString, SomeTuple, s_Bool from rpython.annotator.model import SomeUnicodeCodePoint, SomeAddress from rpython.annotator.model import SomeFloat, unionof, SomeUnicodeString from rpython.annotator.model import SomePBC, SomeInstance, SomeDict, SomeList diff --git a/rpython/annotator/classdef.py b/rpython/annotator/classdef.py --- a/rpython/annotator/classdef.py +++ b/rpython/annotator/classdef.py @@ -212,7 +212,7 @@ def find_attribute(self, attr): return self.locate_attribute(attr).attrs[attr] - + def __repr__(self): return "" % (self.name,) @@ -223,7 +223,6 @@ return True def commonbase(self, other): - other1 = other while other is not None and not self.issubclass(other): other = other.basedef return other @@ -323,14 +322,11 @@ d = [] uplookup = None updesc = None - meth = False - check_for_missing_attrs = False for desc in pbc.descriptions: # pick methods but ignore already-bound methods, which can come # from an instance attribute if (isinstance(desc, description.MethodDesc) - and desc.selfclassdef is None): - meth = True + and desc.selfclassdef is None): methclassdef = desc.originclassdef if methclassdef is not self and methclassdef.issubclass(self): pass # subclasses methods are always candidates @@ -349,7 +345,7 @@ # more precise subclass that it's coming from. desc = desc.bind_self(methclassdef, flags) d.append(desc) - if uplookup is not None: + if uplookup is not None: d.append(updesc.bind_self(self, flags)) if d or pbc.can_be_None: diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -282,7 +282,7 @@ raise Exception("%r: signature and enforceargs cannot both be used" % (self,)) if enforceargs: if not callable(enforceargs): - from rpython.annotator.policy import Sig + from rpython.annotator.signature import Sig enforceargs = Sig(*enforceargs) self.pyobj._annenforceargs_ = enforceargs enforceargs(self, inputcells) # can modify inputcells in-place @@ -867,7 +867,6 @@ def consider_call_site(bookkeeper, family, descs, args, s_result, op): shape = rawshape(args, nextra=1) # account for the extra 'self' - funcdescs = [methoddesc.funcdesc for methoddesc in descs] row = FunctionDesc.row_to_consider(descs, args, op) family.calltable_add_row(shape, row) consider_call_site = staticmethod(consider_call_site) @@ -1028,7 +1027,6 @@ def consider_call_site(bookkeeper, family, descs, args, s_result, op): shape = rawshape(args, nextra=1) # account for the extra 'self' - funcdescs = [mofdesc.funcdesc for mofdesc in descs] row = FunctionDesc.row_to_consider(descs, args, op) family.calltable_add_row(shape, row) consider_call_site = staticmethod(consider_call_site) diff --git a/rpython/annotator/dictdef.py b/rpython/annotator/dictdef.py --- a/rpython/annotator/dictdef.py +++ b/rpython/annotator/dictdef.py @@ -1,6 +1,5 @@ -from rpython.annotator.model import SomeObject, s_ImpossibleValue +from rpython.annotator.model import s_ImpossibleValue from rpython.annotator.model import SomeInteger, s_Bool, unionof -from rpython.annotator.model import SomeInstance from rpython.annotator.listdef import ListItem from rpython.rlib.objectmodel import compute_hash diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py --- a/rpython/annotator/listdef.py +++ b/rpython/annotator/listdef.py @@ -1,4 +1,4 @@ -from rpython.annotator.model import SomeObject, s_ImpossibleValue +from rpython.annotator.model import s_ImpossibleValue from rpython.annotator.model import SomeList, SomeString from rpython.annotator.model import unionof, TLS, UnionError diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -29,11 +29,11 @@ from __future__ import absolute_import -from types import BuiltinFunctionType, MethodType, FunctionType +from types import BuiltinFunctionType, MethodType import rpython from rpython.tool import descriptor from rpython.tool.pairtype import pair, extendabletype -from rpython.rlib.rarithmetic import r_uint, r_ulonglong, base_int +from rpython.rlib.rarithmetic import r_uint, base_int from rpython.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref diff --git a/rpython/annotator/policy.py b/rpython/annotator/policy.py --- a/rpython/annotator/policy.py +++ b/rpython/annotator/policy.py @@ -2,11 +2,6 @@ from rpython.annotator.specialize import default_specialize as default from rpython.annotator.specialize import specialize_argvalue, specialize_argtype, specialize_arglistitemtype, specialize_arg_or_var from rpython.annotator.specialize import memo, specialize_call_location -# for some reason, model must be imported first, -# or we create a cycle. -from rpython.annotator import model as annmodel -from rpython.annotator.bookkeeper import getbookkeeper -from rpython.annotator.signature import Sig class BasicAnnotatorPolicy(object): diff --git a/rpython/annotator/specialize.py b/rpython/annotator/specialize.py --- a/rpython/annotator/specialize.py +++ b/rpython/annotator/specialize.py @@ -1,10 +1,10 @@ # specialization support import py -from rpython.tool.uid import uid + from rpython.tool.sourcetools import func_with_new_name from rpython.tool.algo.unionfind import UnionFind from rpython.flowspace.model import Block, Link, Variable, SpaceOperation -from rpython.flowspace.model import Constant, checkgraph +from rpython.flowspace.model import checkgraph from rpython.annotator import model as annmodel from rpython.flowspace.argument import Signature @@ -22,7 +22,7 @@ nb_extra_args = s_len.const flattened_s = list(args_s[:-1]) flattened_s.extend(s_tuple.items) - + def builder(translator, func): # build a hacked graph that doesn't take a *arg any more, but # individual extra arguments @@ -93,7 +93,6 @@ result.append(graph) assert len(result) == 1 return result[0] - # ____________________________________________________________________________ # specializations @@ -189,8 +188,6 @@ # is the arg a bool? elif nextargvalues == [False, True]: - fieldname0 = self.getuniquefieldname() - fieldname1 = self.getuniquefieldname() stmt = ['if %s:' % argnames[firstarg]] if hasattr(nextfns[True], 'constant_result'): # the True branch has a constant result diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -430,7 +430,7 @@ return dct.dictdef.read_value() def _can_only_throw(dic, *ignore): - if dic1.dictdef.dictkey.custom_eq_hash: + if dic.dictdef.dictkey.custom_eq_hash: return None # r_dict: can throw anything return [] # else: no possible exception @@ -753,10 +753,8 @@ class __extend__(SomeGenericCallable): def call(self, args): - bookkeeper = getbookkeeper() for arg, expected in zip(args.unpack()[0], self.args_s): assert expected.contains(arg) - return self.s_result class __extend__(SomeExternalObject): @@ -769,13 +767,13 @@ else: return SomeObject() getattr.can_only_throw = [] - + def setattr(p, s_attr, s_value): assert s_attr.is_constant() attr = s_attr.const entry = extregistry.lookup_type(p.knowntype) entry.set_field_annotation(p.knowntype, attr, s_value) - + def is_true(p): return s_Bool From noreply at buildbot.pypy.org Fri Mar 22 11:00:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:24 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups in rpython.translator Message-ID: <20130322100024.493AF1C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62650:5f4b6b693539 Date: 2013-03-22 04:03 -0400 http://bitbucket.org/pypy/pypy/changeset/5f4b6b693539/ Log: cleanups in rpython.translator diff --git a/rpython/translator/backendopt/escape.py b/rpython/translator/backendopt/escape.py --- a/rpython/translator/backendopt/escape.py +++ b/rpython/translator/backendopt/escape.py @@ -226,9 +226,6 @@ return NotImplemented return VarState(self.get_creationpoint(op.result, "malloc_varsize", op)) - def op_keepalive(self, op, state): - return None - def op_cast_pointer(self, op, state): return state diff --git a/rpython/translator/backendopt/mallocprediction.py b/rpython/translator/backendopt/mallocprediction.py --- a/rpython/translator/backendopt/mallocprediction.py +++ b/rpython/translator/backendopt/mallocprediction.py @@ -26,7 +26,7 @@ STRUCT)._obj.destructor_funcptr if destr_ptr: continue - except (ValueError, AttributeError), e: + except (ValueError, AttributeError): pass varstate = adi.getstate(op.result) assert len(varstate.creation_points) == 1 diff --git a/rpython/translator/backendopt/mallocv.py b/rpython/translator/backendopt/mallocv.py --- a/rpython/translator/backendopt/mallocv.py +++ b/rpython/translator/backendopt/mallocv.py @@ -1,5 +1,5 @@ from rpython.flowspace.model import Variable, Constant, Block, Link -from rpython.flowspace.model import SpaceOperation, FunctionGraph, copygraph +from rpython.flowspace.model import SpaceOperation, copygraph from rpython.flowspace.model import checkgraph from rpython.flowspace.model import c_last_exception from rpython.translator.backendopt.support import log diff --git a/rpython/translator/backendopt/tailrecursion.py b/rpython/translator/backendopt/tailrecursion.py --- a/rpython/translator/backendopt/tailrecursion.py +++ b/rpython/translator/backendopt/tailrecursion.py @@ -1,4 +1,3 @@ -from rpython.translator.simplify import get_graph from rpython.flowspace.model import mkentrymap, checkgraph # this transformation is very academical -- I had too much time diff --git a/rpython/translator/c/extfunc.py b/rpython/translator/c/extfunc.py --- a/rpython/translator/c/extfunc.py +++ b/rpython/translator/c/extfunc.py @@ -48,9 +48,6 @@ def _RPyListOfString_New(length=lltype.Signed): return LIST_OF_STR.ll_newlist(length) - def _RPyListOfString_New(length=lltype.Signed): - return LIST_OF_STR.ll_newlist(length) - def _RPyListOfString_SetItem(l=p, index=lltype.Signed, newstring=lltype.Ptr(STR)): diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -264,7 +264,6 @@ for op in self.gen_link(link): yield '\t' + op # 'break;' not needed, as gen_link ends in a 'goto' - # Emit default case yield 'default:' if defaultlink is None: @@ -371,7 +370,7 @@ # the C preprocessor cannot handle operations taking a variable number # of arguments, so here are Python methods that do it - + def OP_NEWLIST(self, op): args = [self.expr(v) for v in op.args] r = self.expr(op.result) 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 @@ -1,6 +1,6 @@ from rpython.rtyper.lltypesystem.lltype import (Struct, Array, FixedSizeArray, FuncType, typeOf, GcStruct, GcArray, RttiStruct, ContainerType, parentlink, - Ptr, Void, OpaqueType, Float, RuntimeTypeInfo, getRuntimeTypeInfo, Char, + Void, OpaqueType, Float, RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray) from rpython.rtyper.lltypesystem import llmemory, llgroup from rpython.translator.c.funcgen import FunctionCodeGenerator @@ -11,10 +11,7 @@ from rpython.translator.c.primitive import PrimitiveType, name_signed from rpython.rlib import exports from rpython.rlib.rfloat import isfinite, isinf -from rpython.rlib.rstackovf import _StackOverflow from rpython.translator.c import extfunc -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from py.builtin import BaseException def needs_gcheader(T): if not isinstance(T, ContainerType): @@ -259,7 +256,6 @@ return 'RPyItem(%s, %s)' % (baseexpr, indexexpr) def definition(self): - gcpolicy = self.db.gcpolicy yield 'struct %s {' % self.name for fname, typename in self.gcfields: yield '\t' + cdecl(typename, fname) + ';' @@ -701,7 +697,6 @@ def initializationexpr(self, decoration=''): T = self.getTYPE() - defnode = self.db.gettypedefnode(T) yield '{' if needs_gcheader(T): gc_init = self.db.gcpolicy.array_gcheader_initdata(self) @@ -772,7 +767,6 @@ def initializationexpr(self, decoration=''): T = self.getTYPE() assert self.typename == self.implementationtypename # not var-sized - is_empty = True yield '{' # _names == ['item0', 'item1', ...] for j, name in enumerate(T._names): diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -315,7 +315,7 @@ for func, inputtypes in self.secondary_entrypoints: if inputtypes == Ellipsis: continue - rettype = annotator.build_types(func, inputtypes, False) + annotator.build_types(func, inputtypes, False) if self.entry_point: s = annotator.build_types(self.entry_point, self.inputtypes) diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py --- a/rpython/translator/exceptiontransform.py +++ b/rpython/translator/exceptiontransform.py @@ -1,14 +1,13 @@ from rpython.translator.simplify import join_blocks, cleanup_graph from rpython.translator.unsimplify import copyvar, varoftype from rpython.translator.unsimplify import insert_empty_block, split_block -from rpython.translator.backendopt import canraise, inline, support, removenoops +from rpython.translator.backendopt import canraise, inline from rpython.flowspace.model import Block, Constant, Variable, Link, \ - c_last_exception, SpaceOperation, checkgraph, FunctionGraph, mkentrymap + c_last_exception, SpaceOperation, FunctionGraph, mkentrymap from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.ootypesystem import ootype from rpython.rtyper.lltypesystem import lloperation from rpython.rtyper import rtyper -from rpython.rtyper import rclass from rpython.rtyper.rmodel import inputconst from rpython.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from rpython.rlib.rarithmetic import r_singlefloat @@ -106,7 +105,7 @@ evalue = rpyexc_fetch_value() rpyexc_clear() return evalue - + def rpyexc_restore_exception(evalue): if evalue: exc_data.exc_type = rclass.ll_inst_type(evalue) @@ -408,14 +407,13 @@ # XXX: does alloc_shortcut make sense also for ootype? if alloc_shortcut: - T = spaceop.result.concretetype var_no_exc = self.gen_nonnull(spaceop.result, llops) else: v_exc_type = self.gen_getfield('exc_type', llops) var_no_exc = self.gen_isnull(v_exc_type, llops) block.operations.extend(llops) - + block.exitswitch = var_no_exc #exception occurred case b = Block([]) diff --git a/rpython/translator/gensupp.py b/rpython/translator/gensupp.py --- a/rpython/translator/gensupp.py +++ b/rpython/translator/gensupp.py @@ -3,8 +3,6 @@ Another name could be genEric, but well... """ -import sys - def uniquemodulename(name, SEEN={}): # never reuse the same module name within a Python session! i = 0 diff --git a/rpython/translator/goal/_test_thread.py b/rpython/translator/goal/_test_thread.py --- a/rpython/translator/goal/_test_thread.py +++ b/rpython/translator/goal/_test_thread.py @@ -1,4 +1,4 @@ -import thread, time +import thread class MonitorList(list): def append(self, obj): diff --git a/rpython/translator/goal/bpnn.py b/rpython/translator/goal/bpnn.py --- a/rpython/translator/goal/bpnn.py +++ b/rpython/translator/goal/bpnn.py @@ -187,8 +187,6 @@ # __________ Entry point for stand-alone builds __________ -import time - def entry_point(argv): if len(argv) > 1: N = int(argv[1]) diff --git a/rpython/translator/goal/gcbench.py b/rpython/translator/goal/gcbench.py --- a/rpython/translator/goal/gcbench.py +++ b/rpython/translator/goal/gcbench.py @@ -43,7 +43,7 @@ # - No attempt to measure variation with object size # - Results are sensitive to locking cost, but we dont # check for proper locking -import os, time +import time USAGE = """gcbench [num_repetitions] [--depths=N,N,N..] [--threads=N]""" ENABLE_THREADS = True diff --git a/rpython/translator/goal/query.py b/rpython/translator/goal/query.py --- a/rpython/translator/goal/query.py +++ b/rpython/translator/goal/query.py @@ -1,6 +1,5 @@ # functions to query information out of the translator and annotator from the debug prompt of translate import types -import re import rpython.annotator.model as annmodel import rpython.flowspace.model as flowmodel @@ -23,7 +22,7 @@ return "%s -> %s" % ( ', '.join(map(hbinding, g.getargs())), hbinding(g.getreturnvar())) - + class Found(Exception): pass diff --git a/rpython/translator/goal/targetgcbench.py b/rpython/translator/goal/targetgcbench.py --- a/rpython/translator/goal/targetgcbench.py +++ b/rpython/translator/goal/targetgcbench.py @@ -1,4 +1,3 @@ -import os, sys from rpython.translator.goal import gcbench # _____ Define and setup target ___ diff --git a/rpython/translator/goal/targetpushpop.py b/rpython/translator/goal/targetpushpop.py --- a/rpython/translator/goal/targetpushpop.py +++ b/rpython/translator/goal/targetpushpop.py @@ -7,8 +7,6 @@ actually implementing argv of the executable. """ -import os, sys - # __________ Entry point __________ class A(object): diff --git a/rpython/translator/goal/targetvarsized.py b/rpython/translator/goal/targetvarsized.py --- a/rpython/translator/goal/targetvarsized.py +++ b/rpython/translator/goal/targetvarsized.py @@ -1,4 +1,4 @@ -import os, sys +import os #from rpython.translator.goal import richards modfilename = os.path.join(os.path.dirname(__file__), 'richards.py') diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -2,7 +2,6 @@ import py, os, sys -from rpython.tool.ansi_print import ansi_log from rpython.tool.runsubprocess import run_subprocess as _run_subprocess from rpython.tool.udir import udir diff --git a/rpython/translator/platform/arm.py b/rpython/translator/platform/arm.py --- a/rpython/translator/platform/arm.py +++ b/rpython/translator/platform/arm.py @@ -1,8 +1,6 @@ -import py, os from rpython.translator.platform.linux import Linux from rpython.translator.platform.posix import _run_subprocess, GnuMakefile from rpython.translator.platform import ExecutionResult, log -from rpython.tool.udir import udir from os import getenv SB2 = getenv('SB2') diff --git a/rpython/translator/platform/darwin.py b/rpython/translator/platform/darwin.py --- a/rpython/translator/platform/darwin.py +++ b/rpython/translator/platform/darwin.py @@ -1,7 +1,5 @@ """Support for OS X.""" -import os - from rpython.translator.platform import posix class Darwin(posix.BasePosix): @@ -21,7 +19,7 @@ return (list(self.shared_only) + ['-dynamiclib', '-undefined', 'dynamic_lookup'] + args) - + def _include_dirs_for_libffi(self): return ['/usr/include/ffi'] diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -6,10 +6,10 @@ """ import py + from rpython.flowspace import operation -from rpython.flowspace.model import (SpaceOperation, Variable, Constant, Block, - Link, c_last_exception, checkgraph, - mkentrymap) +from rpython.flowspace.model import (SpaceOperation, Variable, Constant, + c_last_exception, checkgraph, mkentrymap) from rpython.rlib import rarithmetic from rpython.translator import unsimplify from rpython.translator.backendopt import ssa @@ -21,7 +21,7 @@ Return an object which is supposed to have attributes such as graph and _callable """ - if hasattr(func, '_obj'): + if hasattr(func, '_obj'): return func._obj # lltypesystem else: return func # ootypesystem @@ -489,7 +489,7 @@ pending.append(prevvar) flow_read_var_backward(read_vars) - + for block in blocks: # look for removable operations whose result is never used @@ -501,7 +501,7 @@ elif op.opname == 'simple_call': # XXX we want to have a more effective and safe # way to check if this operation has side effects - # ... + # ... if op.args and isinstance(op.args[0], Constant): func = op.args[0].value try: @@ -956,7 +956,6 @@ break else: raise AssertionError("lost 'iter' operation") - vlength = Variable('maxlength') vlist2 = Variable(vlist) chint = Constant({'maxlength': True}) iterblock.operations += [ @@ -1018,5 +1017,4 @@ eliminate_empty_blocks(graph) join_blocks(graph) remove_identical_vars(graph) - checkgraph(graph) - + checkgraph(graph) diff --git a/rpython/translator/tool/graphpage.py b/rpython/translator/tool/graphpage.py --- a/rpython/translator/tool/graphpage.py +++ b/rpython/translator/tool/graphpage.py @@ -1,7 +1,6 @@ -import inspect, types from rpython.flowspace.model import Block, Link, FunctionGraph from rpython.flowspace.model import safe_iterblocks, safe_iterlinks -from rpython.translator.tool.make_dot import DotGen, make_dot, make_dot_graphs +from rpython.translator.tool.make_dot import DotGen, make_dot_graphs from rpython.annotator.model import SomePBC from rpython.annotator.description import MethodDesc from rpython.annotator.classdef import ClassDef @@ -27,7 +26,7 @@ label += "\\n" + self.createlink(info.origin, 'Originated at') if caused_by is not None: label += '\\n' + self.createlink(caused_by) - + dotgen.emit_node('0', shape="box", color="red", label=label) for n, (data, caused_by) in zip(range(len(history)), history): label = nottoowide(data) @@ -387,8 +386,6 @@ return 'class_hierarchy' def do_compute(self, dotgen): - translator = self.translator - # show the class hierarchy self.compute_class_hieararchy(dotgen) diff --git a/rpython/translator/tool/lltracker.py b/rpython/translator/tool/lltracker.py --- a/rpython/translator/tool/lltracker.py +++ b/rpython/translator/tool/lltracker.py @@ -3,7 +3,6 @@ """ import sys, os -import gc from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.memory.gcheader import header2obj from rpython.translator.tool.reftracker import BaseRefTrackerPage, MARKER @@ -12,7 +11,6 @@ class LLRefTrackerPage(BaseRefTrackerPage): - def compute(self, objectlist, size_gc_header): self.size_gc_header = size_gc_header return BaseRefTrackerPage.compute(self, objectlist) @@ -74,7 +72,6 @@ with_header=False): yield fmt % (name,), value if gcobjptr: - GCT = lltype.typeOf(gcobjptr) if self.size_gc_header is not None: for sub in self.enum_content(gcobjptr._obj, with_header=False): diff --git a/rpython/translator/transform.py b/rpython/translator/transform.py --- a/rpython/translator/transform.py +++ b/rpython/translator/transform.py @@ -5,12 +5,10 @@ completed. """ -import types from rpython.flowspace.model import SpaceOperation from rpython.flowspace.model import Variable, Constant, Link from rpython.flowspace.model import c_last_exception, checkgraph from rpython.annotator import model as annmodel -from rpython.rlib.rstack import stack_check from rpython.rtyper.lltypesystem import lltype def checkgraphs(self, blocks): diff --git a/rpython/translator/translator.py b/rpython/translator/translator.py --- a/rpython/translator/translator.py +++ b/rpython/translator/translator.py @@ -4,15 +4,16 @@ translation-related code. It can be used for interactive testing of the translator; see pypy/bin/translatorshell.py. """ -import os, sys, types, copy +import sys +import types from rpython.translator import simplify from rpython.flowspace.model import FunctionGraph, checkgraph, Block from rpython.flowspace.objspace import build_flow from rpython.tool.ansi_print import ansi_log from rpython.tool.sourcetools import nice_repr_for_func -from rpython.config.translationoption import get_combined_translation_config from rpython.config.translationoption import get_platform + import py log = py.log.Producer("flowgraph") py.log.setconsumer("flowgraph", ansi_log) From noreply at buildbot.pypy.org Fri Mar 22 11:00:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:25 +0100 (CET) Subject: [pypy-commit] pypy default: random other cleanups Message-ID: <20130322100025.877751C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62651:f4837cb97fc2 Date: 2013-03-22 05:51 -0400 http://bitbucket.org/pypy/pypy/changeset/f4837cb97fc2/ Log: random other cleanups diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -33,7 +33,7 @@ modname = os.path.basename(modname) try: checkmodule(modname) - except Exception, e: + except Exception: import traceback, pdb traceback.print_exc() pdb.post_mortem(sys.exc_info()[2]) diff --git a/pypy/bin/dotviewer.py b/pypy/bin/dotviewer.py --- a/pypy/bin/dotviewer.py +++ b/pypy/bin/dotviewer.py @@ -4,6 +4,7 @@ Run with no arguments for help. """ +import os import sys sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))) from dotviewer.dotviewer import main diff --git a/pypy/bin/pyinteractive.py b/pypy/bin/pyinteractive.py --- a/pypy/bin/pyinteractive.py +++ b/pypy/bin/pyinteractive.py @@ -6,14 +6,13 @@ """ -import os, sys +import os +import sys import time sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) -import pypy from pypy.tool import option -from optparse import make_option from pypy.interpreter import main, interactive, error, gateway from rpython.config.config import OptionDescription, BoolOption, StrOption from rpython.config.config import Config, to_optparse diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -61,7 +61,6 @@ def main(): - import sys try: kwds = parse_options(sys.argv[1:]) except AssertionError: diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.tool.ann_override import PyPyAnnotatorPolicy -from rpython.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE +from rpython.config.config import to_optparse, make_dict, SUPPRESS_USAGE from rpython.config.config import ConflictConfigError from pypy.tool.option import make_objspace from pypy.conftest import pypydir diff --git a/pypy/tool/alarm.py b/pypy/tool/alarm.py --- a/pypy/tool/alarm.py +++ b/pypy/tool/alarm.py @@ -7,8 +7,6 @@ sending KeyboardInterrupts. """ -import traceback - def _main_with_alarm(finished): import sys, os import time diff --git a/pypy/tool/ann_override.py b/pypy/tool/ann_override.py --- a/pypy/tool/ann_override.py +++ b/pypy/tool/ann_override.py @@ -1,10 +1,7 @@ # overrides for annotation specific to PyPy codebase -from rpython.annotator.policy import AnnotatorPolicy, Sig -# for some reason, model must be imported first, -# or we create a cycle. +from rpython.annotator.policy import AnnotatorPolicy +from rpython.annotator.signature import Sig from rpython.flowspace.model import Constant -from rpython.annotator import model as annmodel -from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import specialize from pypy.interpreter import baseobjspace @@ -60,8 +57,8 @@ # for jit benefit if cached not in t._immutable_fields_: # accessed this way just # for convenience - t._immutable_fields_.append(cached) - + t._immutable_fields_.append(cached) + def attach_lookup(pol, t, attr): cached = "cached_%s" % attr if not t.is_heaptype() and not t.is_cpytype(): diff --git a/pypy/tool/import_graph.py b/pypy/tool/import_graph.py --- a/pypy/tool/import_graph.py +++ b/pypy/tool/import_graph.py @@ -1,7 +1,6 @@ from __future__ import division import py -import math import random exclude_files = ["__init__.py", "conftest.py"] @@ -72,7 +71,6 @@ return points[0] def color(t): - points = [0, 0, 1, 0, 0] casteljeau([0, 0, 1, 0, 0], t) / 0.375 class ModuleGraph(object): diff --git a/pypy/tool/option.py b/pypy/tool/option.py --- a/pypy/tool/option.py +++ b/pypy/tool/option.py @@ -1,8 +1,7 @@ # This is where the options for py.py are defined. -import os from pypy.config.pypyoption import get_pypy_config -from rpython.config.config import Config, OptionDescription, to_optparse +from rpython.config.config import to_optparse import optparse extra_useage = """For detailed descriptions of all the options see diff --git a/pypy/tool/pydis.py b/pypy/tool/pydis.py --- a/pypy/tool/pydis.py +++ b/pypy/tool/pydis.py @@ -147,7 +147,6 @@ n = len(code) i = 0 extended_arg = 0 - free = None while i < n: c = code[i] op = ord(c) @@ -171,7 +170,7 @@ i = i+2 if op == EXTENDED_ARG: extended_arg = oparg*65536L - + disresult.append(current_bytecodeindex, oparg, lineno) assert disresult is not None return disresult diff --git a/pypy/tool/traceconfig.py b/pypy/tool/traceconfig.py --- a/pypy/tool/traceconfig.py +++ b/pypy/tool/traceconfig.py @@ -29,7 +29,7 @@ # Many operations call back into the object space "recursive_operations" : False, - + # Show the bytecode or just the operations "show_bytecode" : True, @@ -45,6 +45,4 @@ "result_printer_clz" : ResultPrinter, "operations" : get_operations_all() - } - diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -24,7 +24,8 @@ Try dir(snippet) for list of current snippets. """ -import os, sys +import os +import sys sys.path.insert(0, os.path.dirname(os.path.dirname( os.path.dirname(os.path.realpath(__file__))))) @@ -32,8 +33,6 @@ from rpython.rtyper.rtyper import * from rpython.rlib.rarithmetic import * -import py - def get_c_function(lib, f): from ctypes import CDLL diff --git a/rpython/config/config.py b/rpython/config/config.py --- a/rpython/config/config.py +++ b/rpython/config/config.py @@ -1,4 +1,3 @@ -import py import optparse from rpython.tool.pairtype import extendabletype @@ -18,7 +17,7 @@ class Config(object): _cfgimpl_frozen = False - + def __init__(self, descr, parent=None, **overrides): self._cfgimpl_descr = descr self._cfgimpl_value_owners = {} @@ -239,15 +238,15 @@ def add_optparse_option(self, argnames, parser, config): callback = ConfigUpdate(config, self) - option = parser.add_option(help=self.doc+" %default", - action='callback', type=self.opt_type, - callback=callback, metavar=self._name.upper(), - *argnames) + parser.add_option(help=self.doc+" %default", + action='callback', type=self.opt_type, + callback=callback, metavar=self._name.upper(), + *argnames) - + class ChoiceOption(Option): opt_type = 'string' - + def __init__(self, name, doc, values, default=None, requires=None, suggests=None, cmdline=DEFAULT_OPTION_NAME): super(ChoiceOption, self).__init__(name, doc, cmdline) @@ -328,9 +327,9 @@ def add_optparse_option(self, argnames, parser, config): callback = BoolConfigUpdate(config, self, True) - option = parser.add_option(help=self.doc+" %default", - action='callback', - callback=callback, *argnames) + parser.add_option(help=self.doc+" %default", + action='callback', + callback=callback, *argnames) if not self.negation: return no_argnames = ["--" + _getnegation(argname.lstrip("-")) @@ -340,14 +339,14 @@ no_argnames = ["--" + _getnegation(argname.lstrip("-")) for argname in argnames] callback = BoolConfigUpdate(config, self, False) - option = parser.add_option(help="unset option set by %s %%default" % (argname, ), - action='callback', - callback=callback, *no_argnames) + parser.add_option(help="unset option set by %s %%default" % (argname, ), + action='callback', + callback=callback, *no_argnames) - + class IntOption(Option): opt_type = 'int' - + def __init__(self, name, doc, default=None, cmdline=DEFAULT_OPTION_NAME): super(IntOption, self).__init__(name, doc, cmdline) self.default = default diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -1,6 +1,6 @@ -import py, os, sys +import sys from rpython.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption -from rpython.config.config import ChoiceOption, StrOption, to_optparse, Config +from rpython.config.config import ChoiceOption, StrOption, Config from rpython.config.config import ConfigError from rpython.config.support import detect_number_of_processors @@ -349,11 +349,6 @@ """Apply optimization suggestions on the 'config'. The optimizations depend on the selected level and possibly on the backend. """ - # warning: during some tests, the type_system and the backend may be - # unspecified and we get None. It shouldn't occur in translate.py though. - type_system = config.translation.type_system - backend = config.translation.backend - try: opts = OPT_TABLE[level] except KeyError: diff --git a/rpython/jit/conftest.py b/rpython/jit/conftest.py --- a/rpython/jit/conftest.py +++ b/rpython/jit/conftest.py @@ -1,8 +1,5 @@ -import py - def pytest_addoption(parser): group = parser.getgroup("JIT options") group.addoption('--slow', action="store_true", default=False, dest="run_slow_tests", help="run all the compiled tests (instead of just a few)") - diff --git a/rpython/memory/support.py b/rpython/memory/support.py --- a/rpython/memory/support.py +++ b/rpython/memory/support.py @@ -1,6 +1,5 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rlib.objectmodel import free_non_gc_object, we_are_translated -from rpython.rlib.rarithmetic import r_uint, LONG_BIT from rpython.rlib.debug import ll_assert from rpython.tool.identity_dict import identity_dict diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py --- a/rpython/rtyper/annlowlevel.py +++ b/rpython/rtyper/annlowlevel.py @@ -4,7 +4,8 @@ from rpython.tool.sourcetools import valid_identifier from rpython.annotator import model as annmodel -from rpython.annotator.policy import AnnotatorPolicy, Sig +from rpython.annotator.policy import AnnotatorPolicy +from rpython.annotator.signature import Sig from rpython.annotator.specialize import flatten_star_args from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.flowspace.model import Constant diff --git a/rpython/tool/gcc_cache.py b/rpython/tool/gcc_cache.py --- a/rpython/tool/gcc_cache.py +++ b/rpython/tool/gcc_cache.py @@ -1,5 +1,4 @@ from rpython.translator.platform import CompilationError -from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.conftest import cache_dir from hashlib import md5 import py diff --git a/rpython/tool/runsubprocess.py b/rpython/tool/runsubprocess.py --- a/rpython/tool/runsubprocess.py +++ b/rpython/tool/runsubprocess.py @@ -3,7 +3,8 @@ if the current process already grew very large. """ -import sys, gc +import sys +import gc import os from subprocess import PIPE, Popen @@ -21,18 +22,18 @@ else: args = [str(executable)] + args shell = False + # Just before spawning the subprocess, do a gc.collect(). This # should help if we are running on top of PyPy, if the subprocess # is going to need a lot of RAM and we are using a lot too. gc.collect() - # + pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env, cwd=cwd) stdout, stderr = pipe.communicate() return pipe.returncode, stdout, stderr if __name__ == '__main__': - import gc while True: gc.collect() operation = sys.stdin.readline() diff --git a/rpython/tool/udir.py b/rpython/tool/udir.py --- a/rpython/tool/udir.py +++ b/rpython/tool/udir.py @@ -17,8 +17,8 @@ # of the current Mercurial branch. # -import os, sys -import py +import os +import sys from rpython.tool.version import get_repo_version_info from py.path import local From noreply at buildbot.pypy.org Fri Mar 22 11:00:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:00:26 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130322100026.EDADC1C1532@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62652:6c566f6935d5 Date: 2013-03-22 05:59 -0400 http://bitbucket.org/pypy/pypy/changeset/6c566f6935d5/ Log: merge heads diff too long, truncating to 2000 out of 2542 lines diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,27 +1,30 @@ import sys +from rpython.rlib.cache import Cache +from rpython.tool.uid import HUGEVAL_BYTES +from rpython.rlib import jit, types +from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, + compute_unique_id) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import r_uint + from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, UserDelAction, FrameTraceAction) from pypy.interpreter.error import (OperationError, operationerrfmt, new_exception_class, typed_unwrap_error_msg) from pypy.interpreter.argument import Arguments from pypy.interpreter.miscutils import ThreadLocals -from rpython.rlib.cache import Cache -from rpython.tool.uid import HUGEVAL_BYTES -from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.objectmodel import we_are_translated, newlist_hint,\ - compute_unique_id -from rpython.rlib.rarithmetic import r_uint __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) -unpackiterable_driver = jit.JitDriver(name = 'unpackiterable', - greens = ['tp'], - reds = ['items', 'w_iterator']) +unpackiterable_driver = jit.JitDriver(name='unpackiterable', + greens=['tp'], + reds=['items', 'w_iterator']) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -696,6 +699,7 @@ raise return None + @signature(types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True diff --git a/pypy/tool/ann_override.py b/pypy/tool/ann_override.py --- a/pypy/tool/ann_override.py +++ b/pypy/tool/ann_override.py @@ -1,19 +1,15 @@ # overrides for annotation specific to PyPy codebase from rpython.annotator.policy import AnnotatorPolicy -from rpython.annotator.signature import Sig from rpython.flowspace.model import Constant from rpython.annotator import specialize -from pypy.interpreter import baseobjspace + def isidentifier(s): - if not s: return False + if not s: + return False s = s.replace('_', 'x') return s[0].isalpha() and s.isalnum() -# patch - mostly for debugging, to enforce some signatures -baseobjspace.ObjSpace.newbool.im_func._annenforceargs_ = Sig(lambda s1,s2: s1, - bool) - class PyPyAnnotatorPolicy(AnnotatorPolicy): def __init__(pol, single_space=None): diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -180,13 +180,11 @@ # a graph that has already been rtyped. Safety-check the new # annotations that are passed in, and don't annotate the old # graph -- it's already low-level operations! - for a, s_newarg in zip(graph.getargs(), cells): + for a, s_newarg in zip(block.inputargs, cells): s_oldarg = self.binding(a) assert annmodel.unionof(s_oldarg, s_newarg) == s_oldarg else: assert not self.frozen - for a in cells: - assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: self.bindinputargs(graph, block, cells) else: diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -11,13 +11,12 @@ from rpython.annotator.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue from rpython.annotator.model import SomeInstance, SomeBuiltin, SomeIterator from rpython.annotator.model import SomePBC, SomeFloat, s_None, SomeByteArray -from rpython.annotator.model import SomeExternalObject, SomeWeakRef +from rpython.annotator.model import SomeWeakRef from rpython.annotator.model import SomeAddress, SomeTypedAddressAccess from rpython.annotator.model import SomeSingleFloat, SomeLongFloat, SomeType from rpython.annotator.model import unionof, UnionError, missing_operation from rpython.annotator.model import read_can_only_throw from rpython.annotator.model import add_knowntypedata, merge_knowntypedata -from rpython.annotator.model import SomeGenericCallable from rpython.annotator.bookkeeper import getbookkeeper from rpython.flowspace.model import Variable, Constant from rpython.rlib import rarithmetic @@ -130,7 +129,7 @@ def is_((obj1, obj2)): r = SomeBool() if obj2.is_constant(): - if obj1.is_constant(): + if obj1.is_constant(): r.const = obj1.const is obj2.const if obj2.const is None and not obj1.can_be_none(): r.const = False @@ -148,7 +147,7 @@ def bind(src_obj, tgt_obj, tgt_arg): if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant(): - add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, + add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, bk.valueoftype(src_obj.const)) assert annotator.binding(op.args[tgt_arg]) == tgt_obj @@ -174,7 +173,7 @@ getbookkeeper().count("coerce", obj1, obj2) return pair(obj1, obj2).union() # reasonable enough - # approximation of an annotation intersection, the result should be the annotation obj or + # approximation of an annotation intersection, the result should be the annotation obj or # the intersection of obj and improvement def improve((obj, improvement)): if not improvement.contains(obj) and obj.contains(improvement): @@ -321,7 +320,7 @@ return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') - + add_knowntypedata(knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): @@ -332,7 +331,7 @@ # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) - if (isinstance(op.args[1], Constant) and + if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: @@ -353,14 +352,14 @@ class __extend__(pairtype(SomeBool, SomeBool)): def union((boo1, boo2)): - s = SomeBool() - if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): - s.const = boo1.const + s = SomeBool() + if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): + s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) s.set_knowntypedata(ktd) - return s + return s def and_((boo1, boo2)): s = SomeBool() @@ -385,13 +384,13 @@ if boo2.const: s.const = True return s - + def xor((boo1, boo2)): s = SomeBool() if boo1.is_constant() and boo2.is_constant(): s.const = boo1.const ^ boo2.const return s - + class __extend__(pairtype(SomeString, SomeString)): def union((str1, str2)): @@ -494,7 +493,7 @@ return s_string.__class__() class __extend__(pairtype(SomeFloat, SomeFloat)): - + def union((flt1, flt2)): return SomeFloat() @@ -511,13 +510,13 @@ class __extend__(pairtype(SomeSingleFloat, SomeSingleFloat)): - + def union((flt1, flt2)): return SomeSingleFloat() class __extend__(pairtype(SomeLongFloat, SomeLongFloat)): - + def union((flt1, flt2)): return SomeLongFloat() @@ -609,7 +608,7 @@ class __extend__(pairtype(SomeTuple, SomeInteger)): - + def getitem((tup1, int2)): if int2.is_immutable_constant(): try: @@ -623,7 +622,7 @@ class __extend__(pairtype(SomeList, SomeInteger)): - + def mul((lst1, int2)): return lst1.listdef.offspring() @@ -642,27 +641,27 @@ getitem_idx_key = getitem_idx def setitem((lst1, int2), s_value): - getbookkeeper().count("list_setitem", int2) + getbookkeeper().count("list_setitem", int2) lst1.listdef.mutate() lst1.listdef.generalize(s_value) setitem.can_only_throw = [IndexError] def delitem((lst1, int2)): - getbookkeeper().count("list_delitem", int2) + getbookkeeper().count("list_delitem", int2) lst1.listdef.resize() delitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] @@ -674,14 +673,14 @@ class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): - getbookkeeper().count("str_getitem", int2) + getbookkeeper().count("str_getitem", int2) return SomeUnicodeCodePoint() getitem_idx.can_only_throw = [IndexError] @@ -693,7 +692,7 @@ class __extend__(pairtype(SomeInteger, SomeString), pairtype(SomeInteger, SomeUnicodeString)): - + def mul((int1, str2)): # xxx do we want to support this getbookkeeper().count("str_mul", str2, int1) return str2.basestringclass() @@ -713,7 +712,7 @@ return result class __extend__(pairtype(SomeInteger, SomeList)): - + def mul((int1, lst2)): return lst2.listdef.offspring() @@ -786,7 +785,7 @@ class __extend__(pairtype(SomePBC, SomePBC)): - def union((pbc1, pbc2)): + def union((pbc1, pbc2)): d = pbc1.descriptions.copy() d.update(pbc2.descriptions) return SomePBC(d, can_be_None = pbc1.can_be_None or pbc2.can_be_None) @@ -803,20 +802,6 @@ s.const = False # no common desc in the two sets return s -class __extend__(pairtype(SomeGenericCallable, SomePBC)): - def union((gencall, pbc)): - for desc in pbc.descriptions: - unique_key = desc - bk = desc.bookkeeper - s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unionof(s_result, gencall.s_result) - assert gencall.s_result.contains(s_result) - return gencall - -class __extend__(pairtype(SomePBC, SomeGenericCallable)): - def union((pbc, gencall)): - return pair(gencall, pbc).union() - class __extend__(pairtype(SomeImpossibleValue, SomeObject)): def union((imp1, obj2)): return obj2 @@ -853,7 +838,6 @@ _make_none_union('SomeUnicodeString', 'can_be_None=True') _make_none_union('SomeList', 'obj.listdef') _make_none_union('SomeDict', 'obj.dictdef') -_make_none_union('SomeExternalObject', 'obj.knowntype') _make_none_union('SomeWeakRef', 'obj.classdef') # getitem on SomePBCs, in particular None fails @@ -880,12 +864,6 @@ raise AnnotatorError('add on %r' % pbc) return s_ImpossibleValue -class __extend__(pairtype(SomeExternalObject, SomeExternalObject)): - def union((ext1, ext2)): - if ext1.knowntype == ext2.knowntype: - return SomeExternalObject(ext1.knowntype) - return SomeObject() - # ____________________________________________________________ # annotation of low-level types from rpython.annotator.model import SomePtr, SomeOOInstance, SomeOOClass diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -426,8 +426,8 @@ elif ishashable(x) and x in BUILTIN_ANALYZERS: _module = getattr(x,"__module__","unknown") result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__)) - elif extregistry.is_registered(x, self.policy): - entry = extregistry.lookup(x, self.policy) + elif extregistry.is_registered(x): + entry = extregistry.lookup(x) result = entry.compute_annotation_bk(self) elif isinstance(x, lltype._ptr): result = SomePtr(lltype.typeOf(x)) diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -29,13 +29,15 @@ from __future__ import absolute_import +import inspect +import weakref from types import BuiltinFunctionType, MethodType + import rpython from rpython.tool import descriptor from rpython.tool.pairtype import pair, extendabletype -from rpython.rlib.rarithmetic import r_uint, base_int -from rpython.rlib.rarithmetic import r_singlefloat, r_longfloat -import inspect, weakref +from rpython.rlib.rarithmetic import r_uint, base_int, r_singlefloat, r_longfloat + class State(object): # A global attribute :-( Patch it with 'True' to enable checking of @@ -56,8 +58,10 @@ def __eq__(self, other): return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + def __ne__(self, other): return not (self == other) + def __repr__(self): try: reprdict = TLS.reprdict @@ -75,7 +79,7 @@ m = getattr(self, 'fmt_' + k, repr) r = m(v) if r is not None: - args.append('%s=%s'%(k, r)) + args.append('%s=%s' % (k, r)) kwds = ', '.join(args) finally: del reprdict[self] @@ -83,7 +87,7 @@ def fmt_knowntype(self, t): return t.__name__ - + def contains(self, other): if self == other: return True @@ -130,6 +134,7 @@ def can_be_none(self): return False + class SomeFloat(SomeObject): "Stands for a float or an integer." knowntype = float # if we don't know if it's a float or an int, @@ -152,6 +157,7 @@ def can_be_none(self): return False + class SomeSingleFloat(SomeObject): "Stands for an r_singlefloat." # No operation supported, not even union with a regular float @@ -161,6 +167,7 @@ def can_be_none(self): return False + class SomeLongFloat(SomeObject): "Stands for an r_longfloat." # No operation supported, not even union with a regular float @@ -170,9 +177,11 @@ def can_be_none(self): return False + class SomeInteger(SomeFloat): "Stands for an object which is known to be an integer." knowntype = int + # size is in multiples of C's sizeof(long)! def __init__(self, nonneg=False, unsigned=None, knowntype=None): assert (knowntype is None or knowntype is int or @@ -189,25 +198,29 @@ self.nonneg = unsigned or nonneg self.unsigned = unsigned # rpython.rlib.rarithmetic.r_uint + class SomeBool(SomeInteger): "Stands for true or false." knowntype = bool nonneg = True unsigned = False + def __init__(self): pass + def set_knowntypedata(self, knowntypedata): assert not hasattr(self, 'knowntypedata') if knowntypedata: self.knowntypedata = knowntypedata + class SomeStringOrUnicode(SomeObject): """Base class for shared implementation of SomeString and SomeUnicodeString. Cannot be an annotation.""" immutable = True - can_be_None=False + can_be_None = False no_nul = False # No NUL character in the string. def __init__(self, can_be_None=False, no_nul=False): @@ -226,8 +239,10 @@ d1 = self.__dict__ d2 = other.__dict__ if not TLS.check_str_without_nul: - d1 = d1.copy(); d1['no_nul'] = 0 # ignored - d2 = d2.copy(); d2['no_nul'] = 0 # ignored + d1 = d1.copy() + d1['no_nul'] = 0 + d2 = d2.copy() + d2['no_nul'] = 0 return d1 == d2 def nonnoneify(self): @@ -236,27 +251,34 @@ def nonnulify(self): return self.__class__(can_be_None=self.can_be_None, no_nul=True) + class SomeString(SomeStringOrUnicode): "Stands for an object which is known to be a string." knowntype = str + class SomeUnicodeString(SomeStringOrUnicode): "Stands for an object which is known to be an unicode string" knowntype = unicode + class SomeByteArray(SomeStringOrUnicode): knowntype = bytearray + class SomeChar(SomeString): "Stands for an object known to be a string of length 1." can_be_None = False + def __init__(self, no_nul=False): # no 'can_be_None' argument here if no_nul: self.no_nul = True + class SomeUnicodeCodePoint(SomeUnicodeString): "Stands for an object known to be a unicode codepoint." can_be_None = False + def __init__(self, no_nul=False): # no 'can_be_None' argument here if no_nul: self.no_nul = True @@ -266,11 +288,14 @@ SomeUnicodeString.basestringclass = SomeUnicodeString SomeUnicodeString.basecharclass = SomeUnicodeCodePoint + class SomeList(SomeObject): "Stands for a homogenous list of any length." knowntype = list + def __init__(self, listdef): self.listdef = listdef + def __eq__(self, other): if self.__class__ is not other.__class__: return False @@ -285,10 +310,12 @@ def can_be_none(self): return True + class SomeTuple(SomeObject): "Stands for a tuple of known length." knowntype = tuple immutable = True + def __init__(self, items): self.items = tuple(items) # tuple of s_xxx elements for i in items: @@ -300,11 +327,14 @@ def can_be_none(self): return False + class SomeDict(SomeObject): "Stands for a dict." knowntype = dict + def __init__(self, dictdef): self.dictdef = dictdef + def __eq__(self, other): if self.__class__ is not other.__class__: return False @@ -323,12 +353,13 @@ if len(const) < 20: return repr(const) else: - return '{...%s...}'%(len(const),) + return '{...%s...}' % (len(const),) class SomeIterator(SomeObject): "Stands for an iterator returning objects from a given container." knowntype = type(iter([])) # arbitrarily chose seqiter as the type + def __init__(self, s_container, *variant): self.variant = variant self.s_container = s_container @@ -336,6 +367,7 @@ def can_be_none(self): return False + class SomeInstance(SomeObject): "Stands for an instance of a (user-defined) class." @@ -347,11 +379,13 @@ def fmt_knowntype(self, kt): return None + def fmt_classdef(self, cdef): if cdef is None: return 'object' else: return cdef.name + def fmt_flags(self, flags): if flags: return repr(flags) @@ -444,7 +478,7 @@ if hasattr(self, 'const'): return None else: - return '{...%s...}'%(len(pbis),) + return '{...%s...}' % (len(pbis),) def fmt_knowntype(self, kt): if self.is_constant(): @@ -452,15 +486,6 @@ else: return kt.__name__ -class SomeGenericCallable(SomeObject): - """ Stands for external callable with known signature - """ - def __init__(self, args, result): - self.args_s = args - self.s_result = result - - def can_be_None(self): - return True class SomeBuiltin(SomeObject): "Stands for a built-in function or method with special-cased analysis." @@ -480,26 +505,18 @@ def can_be_none(self): return False + class SomeBuiltinMethod(SomeBuiltin): """ Stands for a built-in method which has got special meaning """ knowntype = MethodType -class SomeExternalObject(SomeObject): - """Stands for an object of 'external' type. External types have a Repr - controlled by rpython.rtyper.extregistry.""" - - def __init__(self, knowntype): - self.knowntype = knowntype - - def can_be_none(self): - return True class SomeImpossibleValue(SomeObject): """The empty set. Instances are placeholders for objects that will never show up at run-time, e.g. elements of an empty list.""" immutable = True - annotationcolor = (160,160,160) + annotationcolor = (160, 160, 160) def can_be_none(self): return False @@ -507,16 +524,18 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() -s_Int = SomeInteger() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) + # ____________________________________________________________ # weakrefs class SomeWeakRef(SomeObject): knowntype = weakref.ReferenceType immutable = True + def __init__(self, classdef): # 'classdef' is None for known-to-be-dead weakrefs. self.classdef = classdef @@ -526,6 +545,7 @@ from rpython.rtyper.lltypesystem import llmemory + class SomeAddress(SomeObject): immutable = True @@ -535,6 +555,7 @@ def is_null_address(self): return self.is_immutable_constant() and not self.const + # The following class is used to annotate the intermediate value that # appears in expressions of the form: # addr.signed[offset] and addr.signed[offset] = value @@ -550,11 +571,12 @@ # annotation of low-level types from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.ootypesystem import ootype + class SomePtr(SomeObject): knowntype = lltype._ptr immutable = True + def __init__(self, ll_ptrtype): assert isinstance(ll_ptrtype, lltype.Ptr) self.ll_ptrtype = ll_ptrtype @@ -562,41 +584,52 @@ def can_be_none(self): return False + class SomeInteriorPtr(SomePtr): def __init__(self, ll_ptrtype): assert isinstance(ll_ptrtype, lltype.InteriorPtr) self.ll_ptrtype = ll_ptrtype + class SomeLLADTMeth(SomeObject): immutable = True + def __init__(self, ll_ptrtype, func): self.ll_ptrtype = ll_ptrtype - self.func = func + self.func = func def can_be_none(self): return False + class SomeOOObject(SomeObject): def __init__(self): + from rpython.rtyper.ootypesystem import ootype self.ootype = ootype.Object + class SomeOOClass(SomeObject): def __init__(self, ootype): self.ootype = ootype + class SomeOOInstance(SomeObject): def __init__(self, ootype, can_be_None=False): self.ootype = ootype self.can_be_None = can_be_None + class SomeOOBoundMeth(SomeObject): immutable = True + def __init__(self, ootype, name): self.ootype = ootype self.name = name + class SomeOOStaticMeth(SomeObject): immutable = True + def __init__(self, method): self.method = method @@ -611,7 +644,10 @@ (SomeAddress(), llmemory.Address), ] + def annotation_to_lltype(s_val, info=None): + from rpython.rtyper.ootypesystem import ootype + if isinstance(s_val, SomeOOInstance): return s_val.ootype if isinstance(s_val, SomeOOStaticMeth): @@ -644,7 +680,10 @@ ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map]) + def lltype_to_annotation(T): + from rpython.rtyper.ootypesystem import ootype + try: s = ll_to_annotation_map.get(T) except TypeError: @@ -669,6 +708,7 @@ else: return s + def ll_to_annotation(v): if v is None: # i think we can only get here in the case of void-returning @@ -681,13 +721,15 @@ T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets) return SomeInteriorPtr(T) return lltype_to_annotation(lltype.typeOf(v)) - + + # ____________________________________________________________ class UnionError(Exception): """Signals an suspicious attempt at taking the union of deeply incompatible SomeXxx instances.""" + def unionof(*somevalues): "The most precise SomeValue instance that contains all the values." try: @@ -703,12 +745,14 @@ s1 = pair(s1, s2).union() return s1 + # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): for v in vars: ktd[(truth, v)] = s_obj + def merge_knowntypedata(ktd1, ktd2): r = {} for truth_v in ktd1: @@ -716,6 +760,7 @@ r[truth_v] = unionof(ktd1[truth_v], ktd2[truth_v]) return r + def not_const(s_obj): if s_obj.is_constant() and not isinstance(s_obj, SomePBC): new_s_obj = SomeObject.__new__(s_obj.__class__) @@ -727,21 +772,23 @@ s_obj = new_s_obj return s_obj + # ____________________________________________________________ # internal def commonbase(cls1, cls2): # XXX single inheritance only XXX hum l1 = inspect.getmro(cls1) - l2 = inspect.getmro(cls2) - if l1[-1] != object: - l1 = l1 + (object,) - if l2[-1] != object: - l2 = l2 + (object,) - for x in l1: - if x in l2: - return x + l2 = inspect.getmro(cls2) + if l1[-1] != object: + l1 = l1 + (object,) + if l2[-1] != object: + l2 = l2 + (object,) + for x in l1: + if x in l2: + return x assert 0, "couldn't get to commonbase of %r and %r" % (cls1, cls2) + def missing_operation(cls, name): def default_op(*args): if args and isinstance(args[0], tuple): @@ -750,12 +797,13 @@ flattened = args for arg in flattened: if arg.__class__ is SomeObject and arg.knowntype is not type: - return SomeObject() + return SomeObject() bookkeeper = rpython.annotator.bookkeeper.getbookkeeper() bookkeeper.warning("no precise annotation supplied for %s%r" % (name, args)) return s_ImpossibleValue setattr(cls, name, default_op) + class HarmlesslyBlocked(Exception): """Raised by the unaryop/binaryop to signal a harmless kind of BlockedInference: the current block is blocked, but not in a way diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -82,8 +82,8 @@ return SomeUnicodeString() elif t is types.NoneType: return s_None - elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): - entry = extregistry.lookup_type(t, bookkeeper.policy) + elif bookkeeper and extregistry.is_registered_type(t): + entry = extregistry.lookup_type(t) return entry.compute_annotation_bk(bookkeeper) elif t is type: return SomeType() @@ -97,7 +97,7 @@ def __init__(self, *argtypes): self.argtypes = argtypes - + def __call__(self, funcdesc, inputcells): from rpython.rtyper.lltypesystem import lltype args_s = [] 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 @@ -3033,33 +3033,6 @@ s = a.build_types(fun, []) assert s.const == 0 - def test_some_generic_function_call(self): - def h(x): - return int(x) - - def c(x): - return int(x) - - def g(a, x): - if x == -1: - a = None - if x < 0: - if x == -1: - a = h - else: - a = c - x = x + .01 - return a(x) - - #def fun(x): - - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) - s = a.build_types(g, [annmodel.SomeGenericCallable( - args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), - annmodel.SomeFloat()]) - assert isinstance(s, annmodel.SomeInteger) - assert not hasattr(s, 'const') - def test_compare_int_bool(self): def fun(x): return 50 < x diff --git a/rpython/annotator/test/test_signature.py b/rpython/annotator/test/test_signature.py --- a/rpython/annotator/test/test_signature.py +++ b/rpython/annotator/test/test_signature.py @@ -6,10 +6,3 @@ assert _annotation_key({str:(str, [str])}) == ('dict', (str, (str, ('list', str)))) for i in ([[str]], [str], (int, int, {str: [str]})): assert hash(_annotation_key(i)) - -def test_genericcallable(): - py.test.skip("this two annotations should be equal - fix!") - from rpython.rtyper.extfunc import genericcallable - s1 = annotation([genericcallable([str], int)]) - s2 = annotation([genericcallable([str], int)]) - assert s1 == s2 diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -9,14 +9,13 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ + SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ - SomeGenericCallable, SomeWeakRef, SomeUnicodeString + SomeWeakRef, SomeUnicodeString from rpython.annotator.bookkeeper import getbookkeeper from rpython.annotator import builtin from rpython.annotator.binaryop import _clone ## XXX where to put this? -from rpython.rtyper import extregistry from rpython.tool.error import AnnotatorError # convenience only! @@ -358,7 +357,7 @@ s_value = dct.dictdef.read_value() return (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)) - + def len(dct): if dct._is_empty(): return immutablevalue(0) @@ -751,32 +750,6 @@ else: return SomeObject() # len() on a pbc? no chance -class __extend__(SomeGenericCallable): - def call(self, args): - for arg, expected in zip(args.unpack()[0], self.args_s): - assert expected.contains(arg) - return self.s_result - -class __extend__(SomeExternalObject): - def getattr(p, s_attr): - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - s_value = entry.get_field_annotation(p.knowntype, attr) - return s_value - else: - return SomeObject() - getattr.can_only_throw = [] - - def setattr(p, s_attr, s_value): - assert s_attr.is_constant() - attr = s_attr.const - entry = extregistry.lookup_type(p.knowntype) - entry.set_field_annotation(p.knowntype, attr, s_value) - - def is_true(p): - return s_Bool - # annotation of low-level types from rpython.annotator.model import SomePtr, SomeLLADTMeth from rpython.annotator.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth @@ -843,7 +816,7 @@ return SomeOOBoundMeth(r.ootype, s_attr.const) return ll_to_annotation(v) - def setattr(r, s_attr, s_value): + def setattr(r, s_attr, s_value): assert s_attr.is_constant(), "setattr on ref %r with non-constant field-name" % r.ootype v = annotation_to_lltype(s_value) example = r.ootype._example() diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1036,6 +1036,7 @@ assert 0, 'unsupported case' def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL): + helper = self._regalloc.get_free_reg() if loc.is_reg(): assert prev_loc.type != FLOAT, 'trying to load from an \ incompatible location into a core register' @@ -1044,24 +1045,24 @@ # unspill a core register offset = prev_loc.value is_imm = check_imm_arg(offset, size=0xFFF) - if not is_imm: - self.mc.PUSH([r.lr.value], cond=cond) - self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.lr) - if not is_imm: - self.mc.POP([r.lr.value], cond=cond) + helper = r.lr if helper is None else helper + save_helper = not is_imm and helper is r.lr elif loc.is_vfp_reg(): assert prev_loc.type == FLOAT, 'trying to load from an \ incompatible location into a float register' # load spilled value into vfp reg offset = prev_loc.value is_imm = check_imm_arg(offset) - if not is_imm: - self.mc.PUSH([r.ip.value], cond=cond) - self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.ip) - if not is_imm: - self.mc.POP([r.ip.value], cond=cond) + helper = r.ip if helper is None else helper + save_helper = not is_imm and helper is r.ip else: assert 0, 'unsupported case' + if save_helper: + self.mc.PUSH([helper.value], cond=cond) + self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=helper) + if save_helper: + self.mc.POP([helper.value], cond=cond) + def _mov_imm_float_to_loc(self, prev_loc, loc, cond=c.AL): if loc.is_vfp_reg(): diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -166,6 +166,13 @@ selected_reg=selected_reg) return reg + def get_free_reg(): + free_regs = self.free_regs + for i in range(len(free_regs), -1, -1): + if free_regs[i] in self.save_around_call_regs: + continue + return free_regs[i] + class Regalloc(BaseRegalloc): @@ -250,6 +257,8 @@ selected_reg) else: return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg) + def get_free_reg(self): + return self.rm.get_free_reg() def free_temp_vars(self): self.rm.free_temp_vars() diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -7,6 +7,18 @@ from rpython.jit.backend.arm.codebuilder import ARMv7Builder from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests +from rpython.jit.backend.arm.test.test_runner import boxfloat, constfloat +from rpython.jit.metainterp.resoperation import ResOperation, rop +from rpython.jit.metainterp.history import (AbstractFailDescr, + AbstractDescr, + BasicFailDescr, + BasicFinalDescr, + BoxInt, Box, BoxPtr, + JitCellToken, TargetToken, + ConstInt, ConstPtr, + BoxObj, + ConstObj, BoxFloat, ConstFloat) + skip_unless_run_slow_tests() class TestARMCallingConvention(CallingConvTests): @@ -39,17 +51,6 @@ ops = """ [%s] i99 = call(ConstClass(func_ptr), 22, descr=calldescr) - force_spill(i0) - force_spill(i1) - force_spill(i2) - force_spill(i3) - force_spill(i4) - force_spill(i5) - force_spill(i6) - force_spill(i7) - force_spill(i8) - force_spill(i9) - force_spill(i10) guard_true(i0) [%s, i99] finish()""" % (args, args) loop = parse(ops, namespace=locals()) @@ -60,3 +61,82 @@ for x in range(11): assert self.cpu.get_int_value(deadframe, x) == x assert self.cpu.get_int_value(deadframe, 11) == 38 + + + def test_float_hf_call_mixed(self): + if not self.cpu.supports_floats: + py.test.skip("requires floats") + cpu = self.cpu + callargs = [] + def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9): + callargs.append(zip(range(12), + [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9])) + return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9 + F = lltype.Float + I = lltype.Signed + FUNC = self.FuncType([F] * 7 + [I] + [F] + [I] + [F]* 2, F) + FPTR = self.Ptr(FUNC) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + args = ([boxfloat(.1) for i in range(7)] + + [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3), + boxfloat(.4)]) + res = self.execute_operation(rop.CALL, + [funcbox] + args, + 'float', descr=calldescr) + for i,j in enumerate(callargs[0]): + box = args[i] + if box.type == 'f': + assert (i, args[i].getfloat()) == j + else: + assert (i, args[i].getint()) == j + assert abs(res.getfloat() - 4.6) < 0.0001 + + def test_float_hf_call_float(self): + if not self.cpu.supports_floats: + py.test.skip("requires floats") + cpu = self.cpu + callargs = [] + def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9): + callargs.append(zip(range(10), + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) + return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + F = lltype.Float + FUNC = self.FuncType([F] * 10, F) + FPTR = self.Ptr(FUNC) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + args = ([boxfloat(.1) for i in range(10)]) + res = self.execute_operation(rop.CALL, + [funcbox] + args, + 'float', descr=calldescr) + for i,j in enumerate(callargs[0]): + assert (i, 0.1) == j + assert abs(res.getfloat() - 1) < 0.0001 + + def test_float_hf_call_int(self): + cpu = self.cpu + callargs = [] + def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9): + callargs.append(zip(range(10), + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) + return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + + I = lltype.Signed + FUNC = self.FuncType([I] * 10, I) + FPTR = self.Ptr(FUNC) + func_ptr = llhelper(FPTR, func) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + args = ([BoxInt(1) for i in range(10)]) + res = self.execute_operation(rop.CALL, + [funcbox] + args, + 'int', descr=calldescr) + for i,j in enumerate(callargs[0]): + assert (i, 1) == j + assert res.getint() == 10 diff --git a/rpython/jit/backend/arm/test/test_regalloc_mov.py b/rpython/jit/backend/arm/test/test_regalloc_mov.py --- a/rpython/jit/backend/arm/test/test_regalloc_mov.py +++ b/rpython/jit/backend/arm/test/test_regalloc_mov.py @@ -64,11 +64,15 @@ self.instrs.append(i) return i +class MockRegalloc(object): + def get_free_reg(self): + return r('helper') class BaseMovTest(object): def setup_method(self, method): self.builder = MockBuilder() self.asm = instantiate(AssemblerARM) + self.asm._regalloc = MockRegalloc() self.asm.mc = self.builder def validate(self, expected): @@ -170,10 +174,8 @@ s = stack(8191) r6 = r(6) expected = [ - mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, s.value, cond=AL), - mi('LDR_rr', r6.value, fp.value, lr.value, cond=AL), - mi('POP', [lr.value], cond=AL)] + mi('gen_load_int', 'helper', s.value, cond=AL), + mi('LDR_rr', r6.value, fp.value, 'helper', cond=AL)] self.mov(s, r6, expected) def test_mov_float_imm_to_vfp_reg(self): @@ -195,7 +197,7 @@ def test_mov_vfp_reg_to_stack(self): reg = vfp(7) s = stack_float(3) - expected = [mi('VSTR', reg.value, fp.value, imm=188, cond=AL)] + expected = [mi('VSTR', reg.value, fp.value, imm=192, cond=AL)] self.mov(reg, s, expected) def test_mov_vfp_reg_to_large_stackloc(self): @@ -211,7 +213,7 @@ def test_mov_stack_to_vfp_reg(self): reg = vfp(7) s = stack_float(3) - expected = [mi('VLDR', reg.value, fp.value, imm=188, cond=AL)] + expected = [mi('VLDR', reg.value, fp.value, imm=192, cond=AL)] self.mov(s, reg, expected) def test_mov_big_stackloc_to_vfp_reg(self): @@ -420,10 +422,8 @@ def test_push_big_stack(self): s = stack(1025) - e = [mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, s.value, cond=AL), - mi('LDR_rr', ip.value, fp.value, lr.value, cond=AL), - mi('POP', [lr.value], cond=AL), + e = [mi('gen_load_int', 'helper', s.value, cond=AL), + mi('LDR_rr', ip.value, fp.value, 'helper', cond=AL), mi('PUSH', [ip.value], cond=AL) ] self.push(s, e) @@ -436,7 +436,7 @@ def test_push_stack_float(self): sf = stack_float(4) e = [ - mi('VLDR', vfp_ip.value, fp.value, imm=192, cond=AL), + mi('VLDR', vfp_ip.value, fp.value, imm=196, cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL), ] self.push(sf, e) @@ -444,11 +444,9 @@ def test_push_large_stackfloat(self): sf = stack_float(100) e = [ - mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, sf.value, cond=AL), - mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL), - mi('VLDR', vfp_ip.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL), + mi('gen_load_int', 'helper', sf.value, cond=AL), + mi('ADD_rr', 'helper', fp.value, 'helper', cond=AL), + mi('VLDR', vfp_ip.value, 'helper', cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL), ] self.push(sf, e) diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -598,7 +598,7 @@ return result return decorate - + def clone(self): assert self.inline_jit_merge_point, 'JitDriver.clone works only after @inline' @@ -844,7 +844,7 @@ assert s_name.is_constant() if s_name.const == 'enable_opts': assert annmodel.SomeString(can_be_None=True).contains(s_value) - else: + else: assert (s_value == annmodel.s_None or annmodel.SomeInteger().contains(s_value)) return annmodel.s_None @@ -876,7 +876,7 @@ class AsmInfo(object): """ An addition to JitDebugInfo concerning assembler. Attributes: - + ops_offset - dict of offsets of operations or None asmaddr - (int) raw address of assembler block asmlen - assembler block length @@ -986,7 +986,7 @@ def specialize_call(self, hop): from rpython.rtyper.lltypesystem import rclass, lltype - + classrepr = rclass.get_type_repr(hop.rtyper) hop.exception_cannot_occur() diff --git a/rpython/rlib/signature.py b/rpython/rlib/signature.py --- a/rpython/rlib/signature.py +++ b/rpython/rlib/signature.py @@ -1,5 +1,6 @@ from rpython.rlib import types + def signature(*paramtypes, **kwargs): """Decorate a function to specify its type signature. @@ -12,7 +13,7 @@ """ returntype = kwargs.pop('returns', None) if returntype is None: - raise TypeError, "signature: parameter 'returns' required" + raise TypeError("signature: parameter 'returns' required") def decorator(f): f._signature_ = (paramtypes, returntype) diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py --- a/rpython/rlib/types.py +++ b/rpython/rlib/types.py @@ -10,9 +10,11 @@ def float(): return model.SomeFloat() + def singlefloat(): return model.SomeSingleFloat() + def longfloat(): return model.SomeLongFloat() @@ -21,18 +23,26 @@ return model.SomeInteger() +def bool(): + return model.SomeBool() + + def unicode(): return model.SomeUnicodeString() + def unicode0(): return model.SomeUnicodeString(no_nul=True) + def str(): return model.SomeString() + def str0(): return model.SomeString(no_nul=True) + def char(): return model.SomeChar() @@ -46,21 +56,25 @@ listdef = ListDef(None, element, mutated=True, resized=True) return model.SomeList(listdef) + def array(element): listdef = ListDef(None, element, mutated=True, resized=False) return model.SomeList(listdef) + def dict(keytype, valuetype): dictdef = DictDef(None, keytype, valuetype) return model.SomeDict(dictdef) -def instance(class_): - return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(class_)) +def instance(cls): + return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(cls)) + class SelfTypeMarker(object): pass + def self(): return SelfTypeMarker() @@ -68,5 +82,6 @@ class AnyTypeMarker(object): pass + def any(): return AnyTypeMarker() diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py --- a/rpython/rtyper/extfunc.py +++ b/rpython/rtyper/extfunc.py @@ -125,23 +125,6 @@ def _freeze_(self): return True -class genericcallable(object): - """ A way to specify the callable annotation, but deferred until - we have bookkeeper - """ - def __init__(self, args, result=None): - self.args = args - self.result = result - -class _ext_callable(ExtRegistryEntry): - _type_ = genericcallable - # we defer a bit annotation here - - def compute_result_annotation(self): - return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper) - for i in self.instance.args], - annotation(self.instance.result, self.bookkeeper)) - class ExtFuncEntry(ExtRegistryEntry): safe_not_sandboxed = False @@ -249,7 +232,7 @@ llfakeimpl, oofakeimpl: optional; if provided, they are called by the llinterpreter sandboxsafe: use True if the function performs no I/O (safe for --sandbox) """ - + if export_name is None: export_name = function.__name__ diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -22,17 +22,9 @@ for k in key: selfcls._register(dict, k) else: - for basecls in selfcls.__mro__: - if '_condition_' in basecls.__dict__: - cond = basecls.__dict__['_condition_'] - break - else: - cond = None - try: - family = dict[key] - except KeyError: - family = dict[key] = ClassFamily() - family.add(selfcls, cond) + if key in dict: + raise ValueError("duplicate extregistry entry %r" % (selfcls,)) + dict[key] = selfcls def _register_value(selfcls, key): selfcls._register(EXT_REGISTRY_BY_VALUE, key) @@ -43,32 +35,6 @@ def _register_metatype(selfcls, key): selfcls._register(EXT_REGISTRY_BY_METATYPE, key) -class ClassFamily(object): - - def __init__(self): - self.default = None - self.conditionals = [] - - def add(self, cls, cond=None): - if cond is None: - assert self.default is None, ( - "duplicate extregistry entry %r" % (cls,)) - self.default = cls - else: - self.conditionals.append((cls, cond)) - - def match(self, config): - if config is not None: - matches = [cls for cls, cond in self.conditionals - if cond(config)] - if matches: - assert len(matches) == 1, ( - "multiple extregistry matches: %r" % (matches,)) - return matches[0] - if self.default: - return self.default - raise KeyError("no default extregistry entry") - class ExtRegistryEntry(object): __metaclass__ = AutoRegisteringType @@ -159,36 +125,36 @@ # ____________________________________________________________ # Public interface to access the registry -def _lookup_type_cls(tp, config): +def _lookup_type_cls(tp): try: - return EXT_REGISTRY_BY_TYPE[tp].match(config) + return EXT_REGISTRY_BY_TYPE[tp] except (KeyError, TypeError): - return EXT_REGISTRY_BY_METATYPE[type(tp)].match(config) + return EXT_REGISTRY_BY_METATYPE[type(tp)] -def lookup_type(tp, config=None): - Entry = _lookup_type_cls(tp, config) +def lookup_type(tp): + Entry = _lookup_type_cls(tp) return Entry(tp) -def is_registered_type(tp, config=None): +def is_registered_type(tp): try: - _lookup_type_cls(tp, config) + _lookup_type_cls(tp) except KeyError: return False return True -def _lookup_cls(instance, config): +def _lookup_cls(instance): try: - return EXT_REGISTRY_BY_VALUE[instance].match(config) + return EXT_REGISTRY_BY_VALUE[instance] except (KeyError, TypeError): - return _lookup_type_cls(type(instance), config) + return _lookup_type_cls(type(instance)) -def lookup(instance, config=None): - Entry = _lookup_cls(instance, config) +def lookup(instance): + Entry = _lookup_cls(instance) return Entry(type(instance), instance) -def is_registered(instance, config=None): +def is_registered(instance): try: - _lookup_cls(instance, config) + _lookup_cls(instance) except KeyError: return False return True diff --git a/rpython/rtyper/lltypesystem/rgeneric.py b/rpython/rtyper/lltypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/lltypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.lltypesystem.lltype import Ptr, FuncType - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return Ptr(FuncType(l_args, l_retval)) diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -1,6 +1,6 @@ -from rpython.rlib import rgc, jit +from rpython.rlib import rgc, jit, types from rpython.rlib.debug import ll_assert -from rpython.rlib.objectmodel import enforceargs +from rpython.rlib.signature import signature from rpython.rtyper.lltypesystem import rstr from rpython.rtyper.lltypesystem.lltype import (GcForwardReference, Ptr, GcArray, GcStruct, Void, Signed, malloc, typeOf, nullptr, typeMethod) @@ -171,7 +171,7 @@ # adapted C code - at enforceargs(None, int, None) + at signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_hint_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements. Note that @@ -227,7 +227,8 @@ if allocated < newsize or newsize < (allocated >> 1) - 5: _ll_list_resize_hint_really(l, newsize, False) - at enforceargs(None, int, None) + + at signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements, and set diff --git a/rpython/rtyper/ootypesystem/ootype.py b/rpython/rtyper/ootypesystem/ootype.py --- a/rpython/rtyper/ootypesystem/ootype.py +++ b/rpython/rtyper/ootypesystem/ootype.py @@ -1,12 +1,12 @@ import py -from py.builtin import set -from rpython.rtyper.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char -from rpython.rtyper.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \ - Primitive, isCompatibleType, enforce, saferecursive, SignedLongLong, UnsignedLongLong -from rpython.rtyper.lltypesystem.lltype import frozendict -from rpython.rtyper.lltypesystem.lltype import identityhash + +from rpython.rlib import objectmodel, types +from rpython.rlib.signature import signature from rpython.rlib.rarithmetic import intmask -from rpython.rlib import objectmodel +from rpython.rtyper.lltypesystem.lltype import (LowLevelType, Signed, Unsigned, + Float, Char, Bool, Void, UniChar, typeOf, Primitive, isCompatibleType, + enforce, saferecursive, SignedLongLong, UnsignedLongLong, frozendict, + identityhash) from rpython.tool.uid import uid @@ -75,7 +75,7 @@ def _example(self): return _class(ROOT) - + Class = Class() class Instance(OOType): @@ -111,7 +111,7 @@ def __hash__(self): return object.__hash__(self) - + def _defl(self): return self._null @@ -153,7 +153,7 @@ _, meth = self._lookup(name) if meth is not None: raise TypeError("Cannot add field %r: method already exists" % name) - + if self._superclass is not None: if self._superclass._has_field(name): raise TypeError("Field %r exists in superclass" % name) @@ -161,7 +161,7 @@ if type(defn) is not tuple: if isinstance(defn, Meth): raise TypeError("Attempting to store method in field") - + fields[name] = (defn, defn._defl()) else: ootype, default = defn @@ -198,7 +198,7 @@ def _init_instance(self, instance): if self._superclass is not None: self._superclass._init_instance(instance) - + for name, (ootype, default) in self._fields.iteritems(): instance.__dict__[name] = enforce(ootype, default) @@ -587,10 +587,10 @@ # this is the equivalent of the lltypesystem ll_newlist that is # marked as typeMethod. + @signature(types.any(), types.int(), returns=types.any()) def ll_newlist(self, length): from rpython.rtyper.ootypesystem import rlist return rlist.ll_newlist(self, length) - ll_newlist._annenforceargs_ = (None, int) # NB: We are expecting Lists of the same ITEMTYPE to compare/hash # equal. We don't redefine __eq__/__hash__ since the implementations @@ -613,7 +613,7 @@ def __hash__(self): if self.ITEM is None: raise TypeError("Can't hash uninitialized List type.") - return BuiltinADTType.__hash__(self) + return BuiltinADTType.__hash__(self) def __str__(self): return '%s(%s)' % (self.__class__.__name__, @@ -625,7 +625,7 @@ def _specialize(self, generic_types): ITEMTYPE = self._specialize_type(self.ITEM, generic_types) return self.__class__(ITEMTYPE) - + def _defl(self): return self._null @@ -644,7 +644,7 @@ # placeholders for types # make sure that each derived class has his own SELFTYPE_T # placeholder, because we want backends to distinguish that. - + SELFTYPE_T = object() ITEMTYPE_T = object() oopspec_name = 'list' @@ -694,7 +694,7 @@ def __hash__(self): if self.ITEM is None: raise TypeError("Can't hash uninitialized List type.") - return BuiltinADTType.__hash__(self) + return BuiltinADTType.__hash__(self) def __str__(self): return '%s(%s)' % (self.__class__.__name__, @@ -717,14 +717,15 @@ self.ITEM = ITEMTYPE self._init_methods() + @signature(types.any(), types.int(), returns=types.any()) def ll_newlist(self, length): from rpython.rtyper.ootypesystem import rlist return rlist.ll_newarray(self, length) - ll_newlist._annenforceargs_ = (None, int) def ll_convert_from_array(self, array): return array + class Dict(BuiltinADTType): # placeholders for types SELFTYPE_T = object() @@ -790,7 +791,7 @@ return False if not self._is_initialized() or not other._is_initialized(): return False # behave like a ForwardReference, i.e. compare by identity - return BuiltinADTType.__eq__(self, other) + return BuiltinADTType.__eq__(self, other) def __ne__(self, other): return not (self == other) @@ -812,7 +813,7 @@ self._KEYTYPE = KEYTYPE self._VALUETYPE = VALUETYPE self._init_methods() - + class CustomDict(Dict): def __init__(self, KEYTYPE=None, VALUETYPE=None): @@ -871,7 +872,7 @@ KEYTYPE = self._specialize_type(self._KEYTYPE, generic_types) VALUETYPE = self._specialize_type(self._VALUETYPE, generic_types) return self.__class__(KEYTYPE, VALUETYPE) - + # ____________________________________________________________ class _object(object): @@ -943,7 +944,7 @@ Class._null = nullruntimeclass class _instance(object): - + def __init__(self, INSTANCE): self.__dict__["_TYPE"] = INSTANCE INSTANCE._init_instance(self) @@ -958,7 +959,7 @@ DEFINST, meth = self._TYPE._lookup(name) if meth is not None: return meth._bound(DEFINST, self) - + self._TYPE._check_field(name) return self.__dict__[name] @@ -998,7 +999,7 @@ return self _enforce = _upcast - + def _downcast(self, INSTANCE): assert instanceof(self, INSTANCE) return self @@ -1023,7 +1024,7 @@ def __getattribute__(self, name): if name.startswith("_"): return object.__getattribute__(self, name) - + raise RuntimeError("Access to field in null object") def __setattr__(self, name, value): @@ -1189,7 +1190,7 @@ def __ne__(self, other): return not (self == other) - + def __hash__(self): return hash(frozendict(self.__dict__)) @@ -1227,7 +1228,7 @@ def __eq__(self, other): return self is other - + def __hash__(self): return id(self) @@ -1251,7 +1252,7 @@ class _meth(_callable): _bound_class = _bound_meth - + def __init__(self, METHOD, **attrs): assert isinstance(METHOD, Meth) _callable.__init__(self, METHOD, **attrs) @@ -1339,7 +1340,7 @@ return True else: return False - + def annotation_to_lltype(cls, ann): from rpython.annotator import model as annmodel return annmodel.annotation_to_lltype(ann) @@ -1605,7 +1606,7 @@ return len(self._list) def _ll_resize_ge(self, length): - # NOT_RPYTHON + # NOT_RPYTHON if len(self._list) < length: diff = length - len(self._list) self._list += [self._TYPE.ITEM._defl()] * diff @@ -1641,7 +1642,7 @@ class _null_list(_null_mixin(_list), _list): def __init__(self, LIST): - self.__dict__["_TYPE"] = LIST + self.__dict__["_TYPE"] = LIST class _array(_builtin_type): def __init__(self, ARRAY, length): @@ -1674,7 +1675,7 @@ class _null_array(_null_mixin(_array), _array): def __init__(self, ARRAY): - self.__dict__["_TYPE"] = ARRAY + self.__dict__["_TYPE"] = ARRAY class _dict(_builtin_type): def __init__(self, DICT): @@ -1772,7 +1773,7 @@ def ll_go_next(self): # NOT_RPYTHON self._check_stamp() - self._index += 1 + self._index += 1 if self._index >= len(self._items): return False else: @@ -1783,7 +1784,7 @@ self._check_stamp() assert 0 <= self._index < len(self._items) return self._items[self._index][0] - + def ll_current_value(self): # NOT_RPYTHON self._check_stamp() @@ -1843,7 +1844,7 @@ class _null_record(_null_mixin(_record), _record): def __init__(self, RECORD): - self.__dict__["_TYPE"] = RECORD + self.__dict__["_TYPE"] = RECORD def new(TYPE): @@ -1935,7 +1936,7 @@ def ooupcast(INSTANCE, instance): return instance._upcast(INSTANCE) - + def oodowncast(INSTANCE, instance): return instance._downcast(INSTANCE) @@ -1962,7 +1963,7 @@ def oostring(obj, base): """ Convert char, int, float, instances and str to str. - + Base is used only for formatting int: for other types is ignored and should be set to -1. For int only base 8, 10 and 16 are supported. diff --git a/rpython/rtyper/ootypesystem/rgeneric.py b/rpython/rtyper/ootypesystem/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/ootypesystem/rgeneric.py +++ /dev/null @@ -1,9 +0,0 @@ - -from rpython.rtyper.rgeneric import AbstractGenericCallableRepr -from rpython.rtyper.ootypesystem import ootype - -class GenericCallableRepr(AbstractGenericCallableRepr): - def create_low_leveltype(self): - l_args = [r_arg.lowleveltype for r_arg in self.args_r] - l_retval = self.r_result.lowleveltype - return ootype.StaticMethod(l_args, l_retval) diff --git a/rpython/rtyper/rexternalobj.py b/rpython/rtyper/rexternalobj.py deleted file mode 100644 --- a/rpython/rtyper/rexternalobj.py +++ /dev/null @@ -1,21 +0,0 @@ -from rpython.annotator import model as annmodel -from rpython.rtyper import extregistry -from rpython.rtyper.lltypesystem import lltype - -# ExternalObjects - - -class __extend__(annmodel.SomeExternalObject): - def rtyper_makerepr(self, rtyper): - # delegate to the get_repr() of the extregistrered Entry class - entry = extregistry.lookup_type(self.knowntype) - return entry.get_repr(rtyper, self) - - def rtyper_makekey(self): - # grab all attributes of the SomeExternalObject for the key - attrs = lltype.frozendict(self.__dict__) - if 'const' in attrs: - del attrs['const'] - if 'const_box' in attrs: - del attrs['const_box'] - return self.__class__, attrs diff --git a/rpython/rtyper/rgeneric.py b/rpython/rtyper/rgeneric.py deleted file mode 100644 --- a/rpython/rtyper/rgeneric.py +++ /dev/null @@ -1,56 +0,0 @@ -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.rmodel import Repr -from rpython.rtyper.rpbc import AbstractFunctionsPBCRepr -from rpython.tool.pairtype import pairtype - - -class AbstractGenericCallableRepr(Repr): - def __init__(self, rtyper, s_generic): - self.rtyper = rtyper From noreply at buildbot.pypy.org Fri Mar 22 11:15:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:15:15 +0100 (CET) Subject: [pypy-commit] pypy default: missing import Message-ID: <20130322101515.5C1F91C1558@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62653:d077b52ffc67 Date: 2013-03-22 06:14 -0400 http://bitbucket.org/pypy/pypy/changeset/d077b52ffc67/ Log: missing import diff --git a/pypy/config/test/test_makerestdoc.py b/pypy/config/test/test_makerestdoc.py --- a/pypy/config/test/test_makerestdoc.py +++ b/pypy/config/test/test_makerestdoc.py @@ -1,6 +1,7 @@ +import py + from rpython.config.config import * from pypy.config.makerestdoc import make_cmdline_overview - from pypy.tool.rest.rest import process as restcheck tempdir = py.test.ensuretemp('config') @@ -19,7 +20,7 @@ def generate_html(descr): config = Config(descr) txt = descr.make_rest_doc().text() - + result = {"": txt} for path in config.getpaths(include_groups=True): subconf, step = config._cfgimpl_get_home_by_path(path) From noreply at buildbot.pypy.org Fri Mar 22 11:33:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:33:26 +0100 (CET) Subject: [pypy-commit] pypy default: fix newbool @signature Message-ID: <20130322103326.6B5C31C1558@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62654:e094bfb176b7 Date: 2013-03-22 06:33 -0400 http://bitbucket.org/pypy/pypy/changeset/e094bfb176b7/ Log: fix newbool @signature diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -699,7 +699,7 @@ raise return None - @signature(types.bool(), returns=types.instance(W_Root)) + @signature(types.any(), types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True From noreply at buildbot.pypy.org Fri Mar 22 11:43:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 11:43:18 +0100 (CET) Subject: [pypy-commit] pypy default: random test fixes after cleanups Message-ID: <20130322104318.6DFD41C1459@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62655:8c91ef2675de Date: 2013-03-22 06:42 -0400 http://bitbucket.org/pypy/pypy/changeset/8c91ef2675de/ Log: random test fixes after cleanups 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 @@ -6,7 +6,8 @@ from rpython.annotator import model as annmodel from rpython.annotator.annrpython import RPythonAnnotator as _RPythonAnnotator from rpython.translator.translator import graphof as tgraphof -from rpython.annotator import policy +from rpython.annotator.policy import AnnotatorPolicy +from rpython.annotator.signature import Sig from rpython.annotator.listdef import ListDef, ListChangeUnallowed from rpython.annotator.dictdef import DictDef from rpython.flowspace.model import * @@ -686,17 +687,17 @@ assert s == a.bookkeeper.immutablevalue(42) def test_call_star_args(self): - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) s = a.build_types(snippet.call_star_args, [int]) assert s.knowntype == int def test_call_star_args_multiple(self): - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) s = a.build_types(snippet.call_star_args_multiple, [int]) assert s.knowntype == int def test_class_spec(self): - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) s = a.build_types(snippet.class_spec, []) assert s.items[0].knowntype == int assert s.items[1].knowntype == str @@ -705,7 +706,7 @@ x = snippet.PolyStk() def f(): return x - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) py.test.raises(Exception, a.build_types, f, []) def test_exception_deduction_with_raise1(self): @@ -2789,7 +2790,7 @@ def fun(x, y): return x+y s_nonneg = annmodel.SomeInteger(nonneg=True) - fun._annenforceargs_ = policy.Sig(int, s_nonneg) + fun._annenforceargs_ = Sig(int, s_nonneg) a = self.RPythonAnnotator() s = a.build_types(fun, [s_nonneg, s_nonneg]) @@ -2813,7 +2814,7 @@ def fun(x, y): return y s_nonneg = annmodel.SomeInteger(nonneg=True) - fun._annenforceargs_ = policy.Sig(lambda s1,s2: s1, lambda s1,s2: s1) + fun._annenforceargs_ = Sig(lambda s1,s2: s1, lambda s1,s2: s1) # means: the 2nd argument's annotation becomes the 1st argument's # input annotation @@ -3016,7 +3017,7 @@ x > y, x >= y) - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) s = a.build_types(fun, [float, float]) assert [s_item.knowntype for s_item in s.items] == [bool] * 6 @@ -3029,14 +3030,14 @@ def fun(): return g([]) - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) s = a.build_types(fun, []) assert s.const == 0 def test_compare_int_bool(self): def fun(x): return 50 < x - a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + a = self.RPythonAnnotator(policy=AnnotatorPolicy()) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeBool) @@ -3049,7 +3050,7 @@ else: v = -maxint return intmask(v * 10) - P = policy.AnnotatorPolicy() + P = AnnotatorPolicy() a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3153,8 +3154,6 @@ py.test.raises(AssertionError, a.build_types, f, []) def test_ctr_location(self): - from rpython.rlib.jit import hint - class A: _annspecialcase_ = 'specialize:ctr_location' def __init__(self, x): diff --git a/rpython/annotator/test/test_model.py b/rpython/annotator/test/test_model.py --- a/rpython/annotator/test/test_model.py +++ b/rpython/annotator/test/test_model.py @@ -1,7 +1,8 @@ import py + from rpython.annotator.model import * from rpython.annotator.listdef import ListDef -from rpython.rtyper.ootypesystem.ootype import ROOT +from rpython.rtyper.ootypesystem import ootype listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) @@ -114,7 +115,7 @@ assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltype.Ptr(S) s_p = ll_to_annotation(lltype.malloc(A, 0)) assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltype.Ptr(A) - C = ootype.Instance('C', ROOT, {}) + C = ootype.Instance('C', ootype.ROOT, {}) s_p = ll_to_annotation(ootype.new(C)) assert isinstance(s_p, SomeOOInstance) and s_p.ootype == C @@ -139,7 +140,7 @@ s_p = SomePtr(ll_ptrtype=PS) assert annotation_to_lltype(s_p) == PS py.test.raises(ValueError, "annotation_to_lltype(si0)") - C = ootype.Instance('C', ROOT, {}) + C = ootype.Instance('C', ootype.ROOT, {}) ref = SomeOOInstance(C) assert annotation_to_lltype(ref) == C s_singlefloat = SomeSingleFloat() @@ -172,10 +173,10 @@ py.test.raises(AssertionError, "unionof(SomeObject(), SomePtr(PS1))") def test_oo_union(): - C1 = ootype.Instance("C1", ROOT) + C1 = ootype.Instance("C1", ootype.ROOT) C2 = ootype.Instance("C2", C1) C3 = ootype.Instance("C3", C1) - D = ootype.Instance("D", ROOT) + D = ootype.Instance("D", ootype.ROOT) assert unionof(SomeOOInstance(C1), SomeOOInstance(C1)) == SomeOOInstance(C1) assert unionof(SomeOOInstance(C1), SomeOOInstance(C2)) == SomeOOInstance(C1) assert unionof(SomeOOInstance(C2), SomeOOInstance(C1)) == SomeOOInstance(C1) @@ -184,7 +185,7 @@ assert unionof(SomeOOInstance(C1),SomeImpossibleValue()) == SomeOOInstance(C1) assert unionof(SomeImpossibleValue(), SomeOOInstance(C1)) == SomeOOInstance(C1) - assert unionof(SomeOOInstance(C1), SomeOOInstance(D)) == SomeOOInstance(ROOT) + assert unionof(SomeOOInstance(C1), SomeOOInstance(D)) == SomeOOInstance(ootype.ROOT) def test_ooclass_array_contains(): A = ootype.Array(ootype.Signed) diff --git a/rpython/rlib/test/test_rpoll.py b/rpython/rlib/test/test_rpoll.py --- a/rpython/rlib/test/test_rpoll.py +++ b/rpython/rlib/test/test_rpoll.py @@ -1,4 +1,6 @@ -import thread, errno +import os +import errno + from rpython.rlib.rsocket import * from rpython.rlib.rpoll import * from rpython.rtyper.test.test_llinterp import interpret From noreply at buildbot.pypy.org Fri Mar 22 12:22:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 12:22:11 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130322112211.7E38A1C1459@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62656:d8b3fa6d3585 Date: 2013-03-22 07:21 -0400 http://bitbucket.org/pypy/pypy/changeset/d8b3fa6d3585/ Log: fix whatsnew 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 @@ -106,3 +106,5 @@ .. branch: pycon2013-doc-fixes Documentation fixes after going through the docs at PyCon 2013 sprint. + +.. branch: extregistry-refactor From noreply at buildbot.pypy.org Fri Mar 22 13:51:59 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 22 Mar 2013 13:51:59 +0100 (CET) Subject: [pypy-commit] pypy default: .any() and .all() are available on all numpy types, not only bools Message-ID: <20130322125159.477F91C0313@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62657:938e96a52c5e Date: 2013-03-22 13:45 +0100 http://bitbucket.org/pypy/pypy/changeset/938e96a52c5e/ Log: .any() and .all() are available on all numpy types, not only bools 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 @@ -172,15 +172,17 @@ def item(self, space): return self.get_dtype(space).itemtype.to_builtin_type(space, self) + def descr_any(self, space): + value = space.is_true(self) + return space.wrap(W_BoolBox(value)) + + def descr_all(self, space): + value = space.is_true(self) + return space.wrap(W_BoolBox(value)) + class W_BoolBox(W_GenericBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("bool") - def descr_any(self, space): - return self - - def descr_all(self, space): - return self - class W_NumberBox(W_GenericBox): _attrs_ = () @@ -423,14 +425,14 @@ __hash__ = interp2app(W_GenericBox.descr_hash), tolist = interp2app(W_GenericBox.item), + any = interp2app(W_GenericBox.descr_any), + all = interp2app(W_GenericBox.descr_all), ) W_BoolBox.typedef = TypeDef("bool_", W_GenericBox.typedef, __module__ = "numpypy", __new__ = interp2app(W_BoolBox.descr__new__.im_func), __index__ = interp2app(descr_index), - any = interp2app(W_BoolBox.descr_any), - all = interp2app(W_BoolBox.descr_all), ) W_NumberBox.typedef = TypeDef("number", W_GenericBox.typedef, 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 @@ -335,15 +335,6 @@ assert X(True) is numpy.True_ assert numpy.bool_("False") is numpy.True_ - def test_bool_any_all(self): - import numpypy as numpy - x = numpy.bool_(True) - assert x.any() - assert x.all() - x = numpy.bool_(False) - assert not x.any() - assert not x.all() - def test_int8(self): import numpypy as numpy @@ -690,6 +681,32 @@ from numpypy import dtype assert dtype('i4').alignment == 4 + def test_any_all(self): + import numpypy as numpy + x = numpy.bool_(True) + assert x.any() + assert x.all() + x = numpy.bool_(False) + assert not x.any() + assert not x.all() + # + x = numpy.float64(0) + assert not x.any() + assert not x.all() + assert isinstance(x.any(), numpy.bool_) + + def test_ravel(self): + from numpypy import float64, int8, array + x = float64(42.5).ravel() + assert x.dtype == float64 + assert (x == array([42.5])).all() + # + x = int8(42).ravel() + assert x.dtype == int8 + assert (x == array(42)).all() + + + class AppTestStrUnicodeDtypes(BaseNumpyAppTest): def test_str_unicode(self): from numpypy import str_, unicode_, character, flexible, generic From noreply at buildbot.pypy.org Fri Mar 22 13:52:00 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 22 Mar 2013 13:52:00 +0100 (CET) Subject: [pypy-commit] pypy default: implement ravel() for numpy types Message-ID: <20130322125200.987B81C0313@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62658:260f7bccabb2 Date: 2013-03-22 13:51 +0100 http://bitbucket.org/pypy/pypy/changeset/260f7bccabb2/ Log: implement ravel() for numpy types 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 @@ -180,6 +180,11 @@ value = space.is_true(self) return space.wrap(W_BoolBox(value)) + def descr_ravel(self, space): + from pypy.module.micronumpy.base import convert_to_array + w_values = space.newtuple([self]) + return convert_to_array(space, w_values) + class W_BoolBox(W_GenericBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("bool") @@ -427,6 +432,7 @@ tolist = interp2app(W_GenericBox.item), any = interp2app(W_GenericBox.descr_any), all = interp2app(W_GenericBox.descr_all), + ravel = interp2app(W_GenericBox.descr_ravel), ) W_BoolBox.typedef = TypeDef("bool_", W_GenericBox.typedef, From noreply at buildbot.pypy.org Fri Mar 22 14:47:35 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Mar 2013 14:47:35 +0100 (CET) Subject: [pypy-commit] pypy default: remove yet another usage of ann enforceargs (this time in rstr) Message-ID: <20130322134735.10DC81C0313@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62659:6747fb2b2dd2 Date: 2013-03-22 06:47 -0700 http://bitbucket.org/pypy/pypy/changeset/6747fb2b2dd2/ Log: remove yet another usage of ann enforceargs (this time in rstr) 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 @@ -1,23 +1,21 @@ from weakref import WeakValueDictionary + from rpython.annotator import model as annmodel +from rpython.rlib import jit, types +from rpython.rlib.debug import ll_assert +from rpython.rlib.objectmodel import (malloc_zero_filled, we_are_translated, + _hash_string, keepalive_until_here, specialize) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.error import TyperError -from rpython.rlib.objectmodel import malloc_zero_filled, we_are_translated -from rpython.rlib.objectmodel import _hash_string, enforceargs -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib.debug import ll_assert -from rpython.rlib import jit -from rpython.rlib.rarithmetic import ovfcheck -from rpython.rtyper.rmodel import inputconst, IntegerRepr +from rpython.rtyper.lltypesystem import ll_str, llmemory +from rpython.rtyper.lltypesystem.lltype import (GcStruct, Signed, Array, Char, + UniChar, Ptr, malloc, Bool, Void, GcArray, nullptr, cast_primitive, + typeOf, staticAdtMethod, GcForwardReference) +from rpython.rtyper.rmodel import inputconst, Repr, IntegerRepr from rpython.rtyper.rstr import (AbstractStringRepr, AbstractCharRepr, - AbstractUniCharRepr, AbstractStringIteratorRepr, - AbstractLLHelpers, AbstractUnicodeRepr) -from rpython.rtyper.lltypesystem import ll_str -from rpython.rtyper.lltypesystem.lltype import \ - GcStruct, Signed, Array, Char, UniChar, Ptr, malloc, \ - Bool, Void, GcArray, nullptr, cast_primitive, typeOf,\ - staticAdtMethod, GcForwardReference, malloc -from rpython.rtyper.rmodel import Repr -from rpython.rtyper.lltypesystem import llmemory + AbstractUniCharRepr, AbstractStringIteratorRepr, AbstractLLHelpers, + AbstractUnicodeRepr) from rpython.tool.sourcetools import func_with_new_name # ____________________________________________________________ @@ -63,7 +61,7 @@ llmemory.sizeof(CHAR_TP) * item) @jit.oopspec('stroruni.copy_contents(src, dst, srcstart, dststart, length)') - @enforceargs(None, None, int, int, int) + @signature(types.any(), types.any(), types.int(), types.int(), types.int(), returns=types.none()) def copy_string_contents(src, dst, srcstart, dststart, length): """Copies 'length' characters from the 'src' string to the 'dst' string, starting at position 'srcstart' and 'dststart'.""" @@ -266,12 +264,12 @@ def ll_strlen(s): return len(s.chars) + @signature(types.any(), types.int(), returns=types.any()) def ll_stritem_nonneg(s, i): chars = s.chars ll_assert(i >= 0, "negative str getitem index") ll_assert(i < len(chars), "str getitem index out of bound") return chars[i] - ll_stritem_nonneg._annenforceargs_ = [None, int] def ll_chr2str(ch): if typeOf(ch) is Char: @@ -511,6 +509,7 @@ return s.chars[len(s.chars) - 1] == ch @jit.elidable + @signature(types.any(), types.any(), types.int(), types.int(), returns=types.int()) def ll_find_char(s, ch, start, end): i = start if end > len(s.chars): @@ -520,7 +519,6 @@ return i i += 1 return -1 - ll_find_char._annenforceargs_ = [None, None, int, int] @jit.elidable def ll_rfind_char(s, ch, start, end): @@ -680,7 +678,7 @@ return -1 return count - @enforceargs(int, None) + @signature(types.int(), types.any(), returns=types.any()) @jit.look_inside_iff(lambda length, items: jit.loop_unrolling_heuristic( items, length)) def ll_join_strs(length, items): @@ -733,6 +731,8 @@ i += 1 return result + @jit.oopspec('stroruni.slice(s1, start, stop)') + @signature(types.any(), types.int(), types.int(), returns=types.any()) @jit.elidable def _ll_stringslice(s1, start, stop): lgt = stop - start @@ -745,8 +745,6 @@ newstr = s1.malloc(lgt) s1.copy_contents(s1, newstr, start, 0, lgt) return newstr - _ll_stringslice.oopspec = 'stroruni.slice(s1, start, stop)' - _ll_stringslice._annenforceargs_ = [None, int, int] def ll_stringslice_startonly(s1, start): return LLHelpers._ll_stringslice(s1, start, len(s1.chars)) diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py --- a/rpython/rtyper/rstr.py +++ b/rpython/rtyper/rstr.py @@ -2,8 +2,7 @@ from rpython.rlib import jit from rpython.rtyper import rint from rpython.rtyper.error import TyperError -from rpython.rtyper.lltypesystem.lltype import (Signed, Bool, Void, UniChar, - typeOf) +from rpython.rtyper.lltypesystem.lltype import Signed, Bool, Void, UniChar from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr, inputconst, Repr from rpython.rtyper.rtuple import AbstractTupleRepr from rpython.tool.pairtype import pairtype, pair From noreply at buildbot.pypy.org Fri Mar 22 17:34:05 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 22 Mar 2013 17:34:05 +0100 (CET) Subject: [pypy-commit] pypy default: a more efficient implementation of list multiplication for typed lists: Message-ID: <20130322163405.209641C1588@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62660:cfcc5f6b1c72 Date: 2013-03-22 17:31 +0100 http://bitbucket.org/pypy/pypy/changeset/cfcc5f6b1c72/ Log: a more efficient implementation of list multiplication for typed lists: so far multiplying would always clone the list and then use inplace_mul 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 @@ -1038,6 +1038,11 @@ w_item = self.wrap(item) return w_item + def mul(self, w_list, times): + l = self.unerase(w_list.lstorage) + return W_ListObject.from_storage_and_strategy( + self.space, self.erase(l * times), self) + def inplace_mul(self, w_list, times): l = self.unerase(w_list.lstorage) l *= times diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -200,6 +200,15 @@ w_res = self.space.mul(w(n), w_lis) assert self.space.eq_w(w_lis3, w_res) + def test_mul_does_not_clone(self): + # only testing right mul at the moment + w = self.space.wrap + arg = w(2) + w_lis = W_ListObject(self.space, [arg]) + w_lis.clone = None + # does not crash + self.space.mul(w_lis, w(5)) + def test_setitem(self): w = self.space.wrap w_list = W_ListObject(self.space, [w(5), w(3)]) From noreply at buildbot.pypy.org Fri Mar 22 18:50:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 18:50:04 +0100 (CET) Subject: [pypy-commit] pypy default: backout the merge of str-dtype-improvement branch. Seems new numpy is not Message-ID: <20130322175004.A1FDD1C1534@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62661:c967eefd1789 Date: 2013-03-21 22:59 -0700 http://bitbucket.org/pypy/pypy/changeset/c967eefd1789/ Log: backout the merge of str-dtype-improvement branch. Seems new numpy is not doing it any more (also mattip is flying so it would take him a while to look at it). Feel free to redo if there is some evidence this is the intended behavior diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -49,8 +49,8 @@ return shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy(space) - loop.setslice(space, shape, self, impl) + impl = impl.copy() + loop.setslice(shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -245,12 +245,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self, space): + def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(space, self.get_shape(), impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -281,11 +281,7 @@ def astype(self, space, dtype): new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - if dtype.is_str_or_unicode(): - raise OperationError(space.w_NotImplementedError, space.wrap( - "astype(%s) not implemented yet" % self.dtype)) - else: - loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) + loop.copy_from_to(self, new_arr.implementation, dtype) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -50,7 +50,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self, space): + def copy(self): scalar = Scalar(self.dtype) scalar.value = self.value return scalar diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,21 +116,12 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size - a_dt = arr.get_dtype() - if dtype.is_record_type() and a_dt.is_record_type(): - #Record types must match - for f in dtype.fields: - if f not in a_dt.fields or \ - dtype.fields[f] != a_dt.fields[f]: - raise OperationError(space.w_TypeError, - space.wrap("record type mismatch")) - elif dtype.is_record_type() or a_dt.is_record_type(): - raise OperationError(space.w_TypeError, - space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) + if _axis < 0 or len(shape) <= _axis: + raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -283,10 +283,6 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) - def convert_to(self, dtype): - # if we reach here, the record fields are guarenteed to match. - return self - class W_CharacterBox(W_FlexibleBox): pass @@ -300,6 +296,10 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.StringType) + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -313,6 +313,11 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.UnicodeType) + return self + class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -71,8 +71,6 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) - def build_and_convert(self, space, box): - return self.itemtype.build_and_convert(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -76,7 +76,7 @@ base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) arr = convert_to_array(space, w_value) - loop.flatiter_setitem(space, self.base, arr, start, step, length) + loop.flatiter_setitem(self.base, arr, start, step, length) def descr_iter(self): return self diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -258,14 +258,17 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy(space)) + return W_NDimArray(self.implementation.copy()) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - return W_NDimArray(ret) + if ret: + return W_NDimArray(ret) + raise OperationError(space.w_NotImplementedError, + space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): # copy (broadcast) values into self 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind and not dt2.is_flexible_type(): + if dt1.kind == dt2.kind: return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,23 +434,7 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - elif dt2.is_flexible_type(): - # For those operations that get here (concatenate, stack), - # flexible types take precedence over numeric type - if dt2.is_record_type(): - return dt2 - if dt1.is_str_or_unicode(): - if dt2.num == 18: - if dt2.itemtype.get_element_size() >= \ - dt1.itemtype.get_element_size(): - return dt2 - return dt1 - if dt2.itemtype.get_element_size() >= \ - dt1.itemtype.get_element_size(): - return dt2 - return dt1 - return dt2 - else: + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -65,19 +65,12 @@ obj_iter.next() return out -setslice_driver1 = jit.JitDriver(name='numpy_setslice1', +setslice_driver = jit.JitDriver(name='numpy_setslice', greens = ['shapelen', 'dtype'], - reds = 'auto') -setslice_driver2 = jit.JitDriver(name='numpy_setslice2', - greens = ['shapelen', 'dtype'], - reds = 'auto') + reds = ['target', 'source', 'target_iter', + 'source_iter']) -def setslice(space, shape, target, source): - if target.dtype.is_str_or_unicode(): - return setslice_build_and_convert(space, shape, target, source) - return setslice_to(space, shape, target, source) - -def setslice_to(space, shape, target, source): +def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -85,26 +78,15 @@ dtype = target.dtype shapelen = len(shape) while not target_iter.done(): - setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target -def setslice_build_and_convert(space, shape, target, source): - # note that unlike everything else, target and source here are - # array implementations, not arrays - target_iter = target.create_iter(shape) - source_iter = source.create_iter(shape) - dtype = target.dtype - shapelen = len(shape) - while not target_iter.done(): - setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) - target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem())) - target_iter.next() - source_iter.next() - return target - reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], @@ -376,27 +358,17 @@ ri.next() return res -flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1', +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', greens = ['dtype'], reds = 'auto') -flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2', - greens = ['dtype'], - reds = 'auto') - -def flatiter_setitem(space, arr, val, start, step, length): - dtype = arr.get_dtype() - if dtype.is_str_or_unicode(): - return flatiter_setitem_build_and_convert(space, arr, val, start, step, length) - return flatiter_setitem_to(space, arr, val, start, step, length) - -def flatiter_setitem_to(space, arr, val, start, step, length): +def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver1.jit_merge_point(dtype=dtype) + flatiter_setitem_driver.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -405,21 +377,6 @@ # WTF numpy? val_iter.reset() -def flatiter_setitem_build_and_convert(space, arr, val, start, step, length): - dtype = arr.get_dtype() - arr_iter = arr.create_iter() - val_iter = val.create_iter() - arr_iter.next_skip_x(start) - while length > 0: - flatiter_setitem_driver2.jit_merge_point(dtype=dtype) - arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem())) - # need to repeat i_nput values until all assignments are done - arr_iter.next_skip_x(step) - length -= 1 - val_iter.next() - # WTF numpy? - val_iter.reset() - fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], reds = 'auto') @@ -504,6 +461,18 @@ val_arr.descr_getitem(space, w_idx)) iter.next() +copy_from_to_driver = jit.JitDriver(greens = ['dtype'], + reds = 'auto') + +def copy_from_to(from_, to, dtype): + from_iter = from_.create_iter() + to_iter = to.create_iter() + while not from_iter.done(): + copy_from_to_driver.jit_merge_point(dtype=dtype) + to_iter.setitem(from_iter.getitem().convert_to(dtype)) + to_iter.next() + from_iter.next() + byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') 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 @@ -1480,32 +1480,6 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() - a = concatenate((array([1]), array(['abc']))) - assert str(a.dtype) == '|S3' - a = concatenate((array([]), array(['abc']))) - assert a[0] == 'abc' - a = concatenate((['abcdef'], ['abc'])) - assert a[0] == 'abcdef' - assert str(a.dtype) == '|S6' - - def test_record_concatenate(self): - # only an exact match can succeed - from numpypy import zeros, concatenate - a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), - zeros((2,),dtype=[('x', int), ('y', float)]))) - assert a.shape == (4,) - exc = raises(TypeError, concatenate, - (zeros((2,), dtype=[('x', int), ('y', float)]), - (zeros((2,), dtype=[('x', float), ('y', float)])))) - assert str(exc.value).startswith('record type mismatch') - exc = raises(TypeError, concatenate, ([1], zeros((2,), - dtype=[('x', int), ('y', float)]))) - assert str(exc.value).startswith('invalid type promotion') - exc = raises(TypeError, concatenate, (['abc'], zeros((2,), - dtype=[('x', int), ('y', float)]))) - assert str(exc.value).startswith('invalid type promotion') - - def test_std(self): from numpypy import array @@ -1676,12 +1650,6 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 - # scalar vs. array - try: - a = array([1, 2, 3.14156]).astype('S3').dtype - assert a.itemsize == 3 - except NotImplementedError: - skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array @@ -1987,7 +1955,7 @@ assert (a.transpose() == b).all() def test_flatiter(self): - from numpypy import array, flatiter, arange, zeros + from numpypy import array, flatiter, arange a = array([[10, 30], [40, 60]]) f_iter = a.flat assert f_iter.next() == 10 @@ -2003,9 +1971,6 @@ a = arange(10).reshape(5, 2) raises(IndexError, 'a.flat[(1, 2)]') assert a.flat.base is a - m = zeros((2,2), dtype='S3') - m.flat[1] = 1 - assert m[0,1] == '1' def test_flatiter_array_conv(self): from numpypy import array, dot 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 @@ -1635,7 +1635,6 @@ def get_size(self): return self.size - class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1643,7 +1642,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) @@ -1684,20 +1683,6 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) - def build_and_convert(self, space, mydtype, box): - if box.get_dtype(space).is_str_or_unicode(): - arg = box.get_dtype(space).itemtype.to_str(box) - else: - w_arg = box.descr_str(space) - arg = space.str_w(space.str(w_arg)) - arr = VoidBoxStorage(self.size, mydtype) - i = 0 - for i in range(min(len(arg), self.size)): - arr.storage[i] = arg[i] - for j in range(i + 1, self.size): - arr.storage[j] = '\x00' - return interp_boxes.W_StringBox(arr, 0, arr.dtype) - class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Fri Mar 22 18:50:06 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Mar 2013 18:50:06 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130322175006.1E8C21C1534@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62662:61bb1bd35293 Date: 2013-03-22 10:49 -0700 http://bitbucket.org/pypy/pypy/changeset/61bb1bd35293/ Log: merge diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -49,8 +49,8 @@ return shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy(space) - loop.setslice(space, shape, self, impl) + impl = impl.copy() + loop.setslice(shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -245,12 +245,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self, space): + def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(space, self.get_shape(), impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -281,11 +281,7 @@ def astype(self, space, dtype): new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - if dtype.is_str_or_unicode(): - raise OperationError(space.w_NotImplementedError, space.wrap( - "astype(%s) not implemented yet" % self.dtype)) - else: - loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) + loop.copy_from_to(self, new_arr.implementation, dtype) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -50,7 +50,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self, space): + def copy(self): scalar = Scalar(self.dtype) scalar.value = self.value return scalar diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,21 +116,12 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size - a_dt = arr.get_dtype() - if dtype.is_record_type() and a_dt.is_record_type(): - #Record types must match - for f in dtype.fields: - if f not in a_dt.fields or \ - dtype.fields[f] != a_dt.fields[f]: - raise OperationError(space.w_TypeError, - space.wrap("record type mismatch")) - elif dtype.is_record_type() or a_dt.is_record_type(): - raise OperationError(space.w_TypeError, - space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) + if _axis < 0 or len(shape) <= _axis: + raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -290,10 +290,6 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) - def convert_to(self, dtype): - # if we reach here, the record fields are guarenteed to match. - return self - class W_CharacterBox(W_FlexibleBox): pass @@ -307,6 +303,10 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.StringType) + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -320,6 +320,11 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.UnicodeType) + return self + class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -71,8 +71,6 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) - def build_and_convert(self, space, box): - return self.itemtype.build_and_convert(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -76,7 +76,7 @@ base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) arr = convert_to_array(space, w_value) - loop.flatiter_setitem(space, self.base, arr, start, step, length) + loop.flatiter_setitem(self.base, arr, start, step, length) def descr_iter(self): return self diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -258,14 +258,17 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy(space)) + return W_NDimArray(self.implementation.copy()) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - return W_NDimArray(ret) + if ret: + return W_NDimArray(ret) + raise OperationError(space.w_NotImplementedError, + space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): # copy (broadcast) values into self 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind and not dt2.is_flexible_type(): + if dt1.kind == dt2.kind: return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,23 +434,7 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - elif dt2.is_flexible_type(): - # For those operations that get here (concatenate, stack), - # flexible types take precedence over numeric type - if dt2.is_record_type(): - return dt2 - if dt1.is_str_or_unicode(): - if dt2.num == 18: - if dt2.itemtype.get_element_size() >= \ - dt1.itemtype.get_element_size(): - return dt2 - return dt1 - if dt2.itemtype.get_element_size() >= \ - dt1.itemtype.get_element_size(): - return dt2 - return dt1 - return dt2 - else: + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -65,19 +65,12 @@ obj_iter.next() return out -setslice_driver1 = jit.JitDriver(name='numpy_setslice1', +setslice_driver = jit.JitDriver(name='numpy_setslice', greens = ['shapelen', 'dtype'], - reds = 'auto') -setslice_driver2 = jit.JitDriver(name='numpy_setslice2', - greens = ['shapelen', 'dtype'], - reds = 'auto') + reds = ['target', 'source', 'target_iter', + 'source_iter']) -def setslice(space, shape, target, source): - if target.dtype.is_str_or_unicode(): - return setslice_build_and_convert(space, shape, target, source) - return setslice_to(space, shape, target, source) - -def setslice_to(space, shape, target, source): +def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -85,26 +78,15 @@ dtype = target.dtype shapelen = len(shape) while not target_iter.done(): - setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target -def setslice_build_and_convert(space, shape, target, source): - # note that unlike everything else, target and source here are - # array implementations, not arrays - target_iter = target.create_iter(shape) - source_iter = source.create_iter(shape) - dtype = target.dtype - shapelen = len(shape) - while not target_iter.done(): - setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) - target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem())) - target_iter.next() - source_iter.next() - return target - reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], @@ -376,27 +358,17 @@ ri.next() return res -flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1', +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', greens = ['dtype'], reds = 'auto') -flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2', - greens = ['dtype'], - reds = 'auto') - -def flatiter_setitem(space, arr, val, start, step, length): - dtype = arr.get_dtype() - if dtype.is_str_or_unicode(): - return flatiter_setitem_build_and_convert(space, arr, val, start, step, length) - return flatiter_setitem_to(space, arr, val, start, step, length) - -def flatiter_setitem_to(space, arr, val, start, step, length): +def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver1.jit_merge_point(dtype=dtype) + flatiter_setitem_driver.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -405,21 +377,6 @@ # WTF numpy? val_iter.reset() -def flatiter_setitem_build_and_convert(space, arr, val, start, step, length): - dtype = arr.get_dtype() - arr_iter = arr.create_iter() - val_iter = val.create_iter() - arr_iter.next_skip_x(start) - while length > 0: - flatiter_setitem_driver2.jit_merge_point(dtype=dtype) - arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem())) - # need to repeat i_nput values until all assignments are done - arr_iter.next_skip_x(step) - length -= 1 - val_iter.next() - # WTF numpy? - val_iter.reset() - fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], reds = 'auto') @@ -504,6 +461,18 @@ val_arr.descr_getitem(space, w_idx)) iter.next() +copy_from_to_driver = jit.JitDriver(greens = ['dtype'], + reds = 'auto') + +def copy_from_to(from_, to, dtype): + from_iter = from_.create_iter() + to_iter = to.create_iter() + while not from_iter.done(): + copy_from_to_driver.jit_merge_point(dtype=dtype) + to_iter.setitem(from_iter.getitem().convert_to(dtype)) + to_iter.next() + from_iter.next() + byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') 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 @@ -1480,32 +1480,6 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() - a = concatenate((array([1]), array(['abc']))) - assert str(a.dtype) == '|S3' - a = concatenate((array([]), array(['abc']))) - assert a[0] == 'abc' - a = concatenate((['abcdef'], ['abc'])) - assert a[0] == 'abcdef' - assert str(a.dtype) == '|S6' - - def test_record_concatenate(self): - # only an exact match can succeed - from numpypy import zeros, concatenate - a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), - zeros((2,),dtype=[('x', int), ('y', float)]))) - assert a.shape == (4,) - exc = raises(TypeError, concatenate, - (zeros((2,), dtype=[('x', int), ('y', float)]), - (zeros((2,), dtype=[('x', float), ('y', float)])))) - assert str(exc.value).startswith('record type mismatch') - exc = raises(TypeError, concatenate, ([1], zeros((2,), - dtype=[('x', int), ('y', float)]))) - assert str(exc.value).startswith('invalid type promotion') - exc = raises(TypeError, concatenate, (['abc'], zeros((2,), - dtype=[('x', int), ('y', float)]))) - assert str(exc.value).startswith('invalid type promotion') - - def test_std(self): from numpypy import array @@ -1676,12 +1650,6 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 - # scalar vs. array - try: - a = array([1, 2, 3.14156]).astype('S3').dtype - assert a.itemsize == 3 - except NotImplementedError: - skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array @@ -1987,7 +1955,7 @@ assert (a.transpose() == b).all() def test_flatiter(self): - from numpypy import array, flatiter, arange, zeros + from numpypy import array, flatiter, arange a = array([[10, 30], [40, 60]]) f_iter = a.flat assert f_iter.next() == 10 @@ -2003,9 +1971,6 @@ a = arange(10).reshape(5, 2) raises(IndexError, 'a.flat[(1, 2)]') assert a.flat.base is a - m = zeros((2,2), dtype='S3') - m.flat[1] = 1 - assert m[0,1] == '1' def test_flatiter_array_conv(self): from numpypy import array, dot 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 @@ -1634,7 +1634,6 @@ def get_size(self): return self.size - class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1642,7 +1641,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) @@ -1683,20 +1682,6 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) - def build_and_convert(self, space, mydtype, box): - if box.get_dtype(space).is_str_or_unicode(): - arg = box.get_dtype(space).itemtype.to_str(box) - else: - w_arg = box.descr_str(space) - arg = space.str_w(space.str(w_arg)) - arr = VoidBoxStorage(self.size, mydtype) - i = 0 - for i in range(min(len(arg), self.size)): - arr.storage[i] = arg[i] - for j in range(i + 1, self.size): - arr.storage[j] = '\x00' - return interp_boxes.W_StringBox(arr, 0, arr.dtype) - class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Fri Mar 22 22:12:28 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 22:12:28 +0100 (CET) Subject: [pypy-commit] pypy default: make sure smalllongobject can be unwrapped, add tests (thanks xentac) Message-ID: <20130322211228.EE3621C1535@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62663:5b912b8c74cf Date: 2013-03-22 17:05 -0400 http://bitbucket.org/pypy/pypy/changeset/5b912b8c74cf/ Log: make sure smalllongobject can be unwrapped, add tests (thanks xentac) diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py --- a/pypy/objspace/std/longobject.py +++ b/pypy/objspace/std/longobject.py @@ -26,6 +26,9 @@ b = b.lshift(3).or_(rbigint.fromint(tag)) return space.newlong_from_rbigint(b) + def unwrap(w_self, space): #YYYYYY + return w_self.longval() + class W_LongObject(W_AbstractLongObject): """This is a wrapper of rbigint.""" @@ -42,9 +45,6 @@ def longval(self): return self.num.tolong() - def unwrap(w_self, space): #YYYYYY - return w_self.longval() - def tofloat(self): return self.num.tofloat() diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py --- a/pypy/objspace/std/smalllongobject.py +++ b/pypy/objspace/std/smalllongobject.py @@ -36,6 +36,9 @@ def asbigint(w_self): return rbigint.fromrarith_int(w_self.longlong) + def longval(self): + return self.longlong + def __repr__(w_self): return '' % w_self.longlong diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -15,6 +15,9 @@ w_obj = space.wrap(123.456) space.raises_w(space.w_TypeError, space.bigint_w, w_obj) + w_obj = fromlong(42) + assert space.unwrap(w_obj) == 42 + def test_rint_variants(self): py.test.skip("XXX broken!") from rpython.rtyper.tool.rfficache import platform diff --git a/pypy/objspace/std/test/test_smalllongobject.py b/pypy/objspace/std/test/test_smalllongobject.py --- a/pypy/objspace/std/test/test_smalllongobject.py +++ b/pypy/objspace/std/test/test_smalllongobject.py @@ -39,6 +39,9 @@ wx = space.and_(w14000000000000, w_huge) assert space.is_true(space.eq(wx, w14000000000000)) + w_obj = W_SmallLongObject.fromint(42) + assert space.unwrap(w_obj) == 42 + class AppTestSmallLong(test_longobject.AppTestLong): spaceconfig = {"objspace.std.withsmalllong": True} From noreply at buildbot.pypy.org Fri Mar 22 22:46:41 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 22:46:41 +0100 (CET) Subject: [pypy-commit] pypy default: backout the backout of str-dtype-improvement in c967eefd1789 after discussion with fijal Message-ID: <20130322214641.1527A1C1534@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62664:f7ec62daeb1b Date: 2013-03-22 17:45 -0400 http://bitbucket.org/pypy/pypy/changeset/f7ec62daeb1b/ Log: backout the backout of str-dtype-improvement in c967eefd1789 after discussion with fijal diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -49,8 +49,8 @@ return shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: - impl = impl.copy() - loop.setslice(shape, self, impl) + impl = impl.copy(space) + loop.setslice(space, shape, self, impl) def get_size(self): return self.size // self.dtype.itemtype.get_element_size() @@ -245,12 +245,12 @@ return SliceArray(self.start, strides, backstrides, shape, self, orig_array) - def copy(self): + def copy(self, space): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.get_shape(), impl, self) + return loop.setslice(space, self.get_shape(), impl, self) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -281,7 +281,11 @@ def astype(self, space, dtype): new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) + if dtype.is_str_or_unicode(): + raise OperationError(space.w_NotImplementedError, space.wrap( + "astype(%s) not implemented yet" % self.dtype)) + else: + loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) return new_arr class ConcreteArrayNotOwning(BaseConcreteArray): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -50,7 +50,7 @@ def set_scalar_value(self, w_val): self.value = w_val.convert_to(self.dtype) - def copy(self): + def copy(self, space): scalar = Scalar(self.dtype) scalar.value = self.value return scalar diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -116,12 +116,21 @@ "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size + a_dt = arr.get_dtype() + if dtype.is_record_type() and a_dt.is_record_type(): + #Record types must match + for f in dtype.fields: + if f not in a_dt.fields or \ + dtype.fields[f] != a_dt.fields[f]: + raise OperationError(space.w_TypeError, + space.wrap("record type mismatch")) + elif dtype.is_record_type() or a_dt.is_record_type(): + raise OperationError(space.w_TypeError, + space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) - if _axis < 0 or len(shape) <= _axis: - raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 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 @@ -290,6 +290,10 @@ dtype.itemtype.store(self.arr, self.ofs, ofs, dtype.coerce(space, w_value)) + def convert_to(self, dtype): + # if we reach here, the record fields are guarenteed to match. + return self + class W_CharacterBox(W_FlexibleBox): pass @@ -303,10 +307,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.StringType) - return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -320,11 +320,6 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - from pypy.module.micronumpy import types - assert isinstance(dtype.itemtype, types.UnicodeType) - return self - class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () 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 @@ -71,6 +71,8 @@ def box_complex(self, real, imag): return self.itemtype.box_complex(real, imag) + def build_and_convert(self, space, box): + return self.itemtype.build_and_convert(space, self, box) def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -76,7 +76,7 @@ base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) arr = convert_to_array(space, w_value) - loop.flatiter_setitem(self.base, arr, start, step, length) + loop.flatiter_setitem(space, self.base, arr, start, step, length) def descr_iter(self): return self diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -258,17 +258,14 @@ return self.implementation.get_scalar_value() def descr_copy(self, space): - return W_NDimArray(self.implementation.copy()) + return W_NDimArray(self.implementation.copy(space)) def descr_get_real(self, space): return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): ret = self.implementation.get_imag(self) - if ret: - return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, - space.wrap('imag not implemented for this dtype')) + return W_NDimArray(ret) def descr_set_real(self, space, w_value): # copy (broadcast) values into self 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 @@ -414,7 +414,7 @@ if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. - if dt1.kind == dt2.kind: + if dt1.kind == dt2.kind and not dt2.is_flexible_type(): return dt2 # Everything promotes to float, and bool promotes to everything. @@ -434,7 +434,23 @@ elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): # UInt64 + signed = Float64 dtypenum = 12 - else: + elif dt2.is_flexible_type(): + # For those operations that get here (concatenate, stack), + # flexible types take precedence over numeric type + if dt2.is_record_type(): + return dt2 + if dt1.is_str_or_unicode(): + if dt2.num == 18: + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + if dt2.itemtype.get_element_size() >= \ + dt1.itemtype.get_element_size(): + return dt2 + return dt1 + return dt2 + else: # increase to the next signed type dtypenum = dt2.num + 1 newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] 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 @@ -65,12 +65,19 @@ obj_iter.next() return out -setslice_driver = jit.JitDriver(name='numpy_setslice', +setslice_driver1 = jit.JitDriver(name='numpy_setslice1', greens = ['shapelen', 'dtype'], - reds = ['target', 'source', 'target_iter', - 'source_iter']) + reds = 'auto') +setslice_driver2 = jit.JitDriver(name='numpy_setslice2', + greens = ['shapelen', 'dtype'], + reds = 'auto') -def setslice(shape, target, source): +def setslice(space, shape, target, source): + if target.dtype.is_str_or_unicode(): + return setslice_build_and_convert(space, shape, target, source) + return setslice_to(space, shape, target, source) + +def setslice_to(space, shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) @@ -78,15 +85,26 @@ dtype = target.dtype shapelen = len(shape) while not target_iter.done(): - setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, - target=target, source=source, - target_iter=target_iter, - source_iter=source_iter) + setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +def setslice_build_and_convert(space, shape, target, source): + # note that unlike everything else, target and source here are + # array implementations, not arrays + target_iter = target.create_iter(shape) + source_iter = source.create_iter(shape) + dtype = target.dtype + shapelen = len(shape) + while not target_iter.done(): + setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype) + target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem())) + target_iter.next() + source_iter.next() + return target + reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], @@ -358,17 +376,27 @@ ri.next() return res -flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', +flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1', greens = ['dtype'], reds = 'auto') -def flatiter_setitem(arr, val, start, step, length): +flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2', + greens = ['dtype'], + reds = 'auto') + +def flatiter_setitem(space, arr, val, start, step, length): + dtype = arr.get_dtype() + if dtype.is_str_or_unicode(): + return flatiter_setitem_build_and_convert(space, arr, val, start, step, length) + return flatiter_setitem_to(space, arr, val, start, step, length) + +def flatiter_setitem_to(space, arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver.jit_merge_point(dtype=dtype) + flatiter_setitem_driver1.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -377,6 +405,21 @@ # WTF numpy? val_iter.reset() +def flatiter_setitem_build_and_convert(space, arr, val, start, step, length): + dtype = arr.get_dtype() + arr_iter = arr.create_iter() + val_iter = val.create_iter() + arr_iter.next_skip_x(start) + while length > 0: + flatiter_setitem_driver2.jit_merge_point(dtype=dtype) + arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem())) + # need to repeat i_nput values until all assignments are done + arr_iter.next_skip_x(step) + length -= 1 + val_iter.next() + # WTF numpy? + val_iter.reset() + fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], reds = 'auto') @@ -461,18 +504,6 @@ val_arr.descr_getitem(space, w_idx)) iter.next() -copy_from_to_driver = jit.JitDriver(greens = ['dtype'], - reds = 'auto') - -def copy_from_to(from_, to, dtype): - from_iter = from_.create_iter() - to_iter = to.create_iter() - while not from_iter.done(): - copy_from_to_driver.jit_merge_point(dtype=dtype) - to_iter.setitem(from_iter.getitem().convert_to(dtype)) - to_iter.next() - from_iter.next() - byteswap_driver = jit.JitDriver(greens = ['dtype'], reds = 'auto') 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 @@ -1480,6 +1480,32 @@ a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) assert (b == [2, 6, 10, 2, 6, 10]).all() + a = concatenate((array([1]), array(['abc']))) + assert str(a.dtype) == '|S3' + a = concatenate((array([]), array(['abc']))) + assert a[0] == 'abc' + a = concatenate((['abcdef'], ['abc'])) + assert a[0] == 'abcdef' + assert str(a.dtype) == '|S6' + + def test_record_concatenate(self): + # only an exact match can succeed + from numpypy import zeros, concatenate + a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]), + zeros((2,),dtype=[('x', int), ('y', float)]))) + assert a.shape == (4,) + exc = raises(TypeError, concatenate, + (zeros((2,), dtype=[('x', int), ('y', float)]), + (zeros((2,), dtype=[('x', float), ('y', float)])))) + assert str(exc.value).startswith('record type mismatch') + exc = raises(TypeError, concatenate, ([1], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + exc = raises(TypeError, concatenate, (['abc'], zeros((2,), + dtype=[('x', int), ('y', float)]))) + assert str(exc.value).startswith('invalid type promotion') + + def test_std(self): from numpypy import array @@ -1650,6 +1676,12 @@ a = array('x').astype('S3').dtype assert a.itemsize == 3 + # scalar vs. array + try: + a = array([1, 2, 3.14156]).astype('S3').dtype + assert a.itemsize == 3 + except NotImplementedError: + skip('astype("S3") not implemented for numeric arrays') def test_base(self): from numpypy import array @@ -1955,7 +1987,7 @@ assert (a.transpose() == b).all() def test_flatiter(self): - from numpypy import array, flatiter, arange + from numpypy import array, flatiter, arange, zeros a = array([[10, 30], [40, 60]]) f_iter = a.flat assert f_iter.next() == 10 @@ -1971,6 +2003,9 @@ a = arange(10).reshape(5, 2) raises(IndexError, 'a.flat[(1, 2)]') assert a.flat.base is a + m = zeros((2,2), dtype='S3') + m.flat[1] = 1 + assert m[0,1] == '1' def test_flatiter_array_conv(self): from numpypy import array, dot 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 @@ -1634,6 +1634,7 @@ def get_size(self): return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1641,7 +1642,7 @@ def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) - arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) @@ -1682,6 +1683,20 @@ def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) + def build_and_convert(self, space, mydtype, box): + if box.get_dtype(space).is_str_or_unicode(): + arg = box.get_dtype(space).itemtype.to_str(box) + else: + w_arg = box.descr_str(space) + arg = space.str_w(space.str(w_arg)) + arr = VoidBoxStorage(self.size, mydtype) + i = 0 + for i in range(min(len(arg), self.size)): + arr.storage[i] = arg[i] + for j in range(i + 1, self.size): + arr.storage[j] = '\x00' + return interp_boxes.W_StringBox(arr, 0, arr.dtype) + class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Fri Mar 22 22:49:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 22 Mar 2013 22:49:11 +0100 (CET) Subject: [pypy-commit] pypy default: whitespace Message-ID: <20130322214911.8D05D1C1535@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62665:b7d6a906dc0c Date: 2013-03-22 17:48 -0400 http://bitbucket.org/pypy/pypy/changeset/b7d6a906dc0c/ Log: whitespace diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,4 +1,3 @@ - from pypy.module.micronumpy.arrayimpl import base, scalar from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ @@ -15,6 +14,7 @@ from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized + class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -82,7 +82,7 @@ return SliceArray(self.start, strides, backstrides, self.get_shape(), self, orig_array) - def set_real(self, space, orig_array, w_value): + def set_real(self, space, orig_array, w_value): tmp = self.get_real(orig_array) tmp.setslice(space, convert_to_array(space, w_value)) @@ -102,7 +102,7 @@ impl.fill(self.dtype.box(0)) return impl - def set_imag(self, space, orig_array, w_value): + def set_imag(self, space, orig_array, w_value): tmp = self.get_imag(orig_array) tmp.setslice(space, convert_to_array(space, w_value)) @@ -284,10 +284,11 @@ if dtype.is_str_or_unicode(): raise OperationError(space.w_NotImplementedError, space.wrap( "astype(%s) not implemented yet" % self.dtype)) - else: + else: loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self) return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): @@ -325,6 +326,7 @@ def base(self): return None + class ConcreteArray(ConcreteArrayNotOwning): def __init__(self, shape, dtype, order, strides, backstrides): # we allocate the actual storage later because we need to compute @@ -338,8 +340,6 @@ free_raw_storage(self.storage, track_allocation=False) - - class NonWritableArray(ConcreteArray): def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( @@ -417,6 +417,7 @@ return SliceArray(self.start, new_strides, new_backstrides, new_shape, self, orig_array) + class ArrayBuffer(RWBuffer): def __init__(self, impl): self.impl = impl From noreply at buildbot.pypy.org Sat Mar 23 00:06:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 00:06:55 +0100 (CET) Subject: [pypy-commit] buildbot default: make OJITLINUX32 work Message-ID: <20130322230655.9F63E1C1534@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r756:10ea2a8c1425 Date: 2013-03-22 19:06 -0400 http://bitbucket.org/pypy/buildbot/changeset/10ea2a8c1425/ Log: make OJITLINUX32 work diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -378,11 +378,11 @@ #"locks": [TannitCPU.access('counting')], }, {"name": OJITLINUX32, - "slavenames": ["allegro32"], + "slavenames": ["tannit32"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'linux32', - #"locks": [TannitCPU.access('counting')], + "locks": [TannitCPU.access('counting')], }, {"name" : JITLINUX32, #"slavenames": ["allegro32"], From noreply at buildbot.pypy.org Sat Mar 23 00:19:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 00:19:16 +0100 (CET) Subject: [pypy-commit] buildbot default: (fijal) remove OJITLINUX32, serves no purpose Message-ID: <20130322231916.C89B71C1534@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r757:a57131afb23f Date: 2013-03-22 19:19 -0400 http://bitbucket.org/pypy/buildbot/changeset/a57131afb23f/ Log: (fijal) remove OJITLINUX32, serves no purpose diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -248,7 +248,6 @@ JITLINUX64 = "pypy-c-jit-linux-x86-64" JITLINUXARM = "pypy-c-jit-linux-armel" JITLINUXPPC64 = "pypy-c-jit-linux-ppc-64" -OJITLINUX32 = "pypy-c-Ojit-no-jit-linux-x86-32" JITMACOSX64 = "pypy-c-jit-macosx-x86-64" JITWIN32 = "pypy-c-jit-win-x86-32" JITWIN64 = "pypy-c-jit-win-x86-64" @@ -287,7 +286,6 @@ JITLINUX64, # on allegro64, uses 1 core APPLVLLINUX32, # on tannit32, uses 1 core APPLVLLINUX64, # on allegro64, uses 1 core - OJITLINUX32, # on tannit32, uses 1 core # other platforms MACOSX32, # on minime JITWIN32, # on aurora @@ -377,13 +375,6 @@ "category": "linux64", #"locks": [TannitCPU.access('counting')], }, - {"name": OJITLINUX32, - "slavenames": ["tannit32"], - "builddir": OJITLINUX32, - "factory": pypy_OjitTranslatedTestFactory, - "category": 'linux32', - "locks": [TannitCPU.access('counting')], - }, {"name" : JITLINUX32, #"slavenames": ["allegro32"], "slavenames": ["tannit32"], From noreply at buildbot.pypy.org Sat Mar 23 00:22:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 00:22:34 +0100 (CET) Subject: [pypy-commit] buildbot default: disable JITMACOSX64 nightly until we have a working slave Message-ID: <20130322232234.DEACE1C1535@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r758:5432a4af5335 Date: 2013-03-22 19:22 -0400 http://bitbucket.org/pypy/buildbot/changeset/5432a4af5335/ Log: disable JITMACOSX64 nightly until we have a working slave diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -291,7 +291,7 @@ JITWIN32, # on aurora JITFREEBSD64, # on headless JITFREEBSD964, # on exarkun's freebsd - JITMACOSX64, # on mvt's machine + #JITMACOSX64, # no currently working machine ], branch=None, hour=0, minute=0), Nightly("nightly-2-00", [ From noreply at buildbot.pypy.org Sat Mar 23 00:39:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 00:39:40 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: close to be merged branch Message-ID: <20130322233940.C89911C1535@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: reflex-support Changeset: r62666:7ccf424c8e5c Date: 2013-03-22 16:38 -0700 http://bitbucket.org/pypy/pypy/changeset/7ccf424c8e5c/ Log: close to be merged branch From noreply at buildbot.pypy.org Sat Mar 23 00:39:44 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 00:39:44 +0100 (CET) Subject: [pypy-commit] pypy default: merge remove-list-smm, that removes two of ANY_ANY_ANY Message-ID: <20130322233944.603281C15A2@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62667:c823bec8a3d1 Date: 2013-03-22 16:39 -0700 http://bitbucket.org/pypy/pypy/changeset/c823bec8a3d1/ Log: merge remove-list-smm, that removes two of ANY_ANY_ANY diff too long, truncating to 2000 out of 7044 lines diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -538,7 +538,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -555,7 +555,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -621,7 +621,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -17,7 +17,7 @@ from pypy.interpreter.miscutils import ThreadLocals -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) @@ -219,16 +219,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True - def __spacebind__(self, space): return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -339,9 +333,8 @@ if e.match(self, self.w_KeyError): continue raise - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -350,9 +343,8 @@ self.call_function(w_exitfunc) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -424,9 +416,8 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): @@ -723,38 +714,26 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' def unpackiterable(self, w_iterable, expected_length=-1): @@ -1032,8 +1011,7 @@ def is_oldstyle_instance(self, w_obj): # xxx hack hack hack from pypy.module.__builtin__.interp_classobj import W_InstanceObject - obj = self.interpclass_w(w_obj) - return obj is not None and isinstance(obj, W_InstanceObject) + return isinstance(w_obj, W_InstanceObject) def callable(self, w_obj): if self.lookup(w_obj, "__call__") is not None: @@ -1670,7 +1648,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1687,7 +1664,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp @@ -145,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -209,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -3,10 +3,10 @@ Code and Frame. """ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root -class Code(Wrappable): +class Code(W_Root): """A code is a compiled version of some source code. Abstract base class.""" _immutable_ = True @@ -52,19 +52,20 @@ def funcrun_obj(self, func, w_obj, args): return self.funcrun(func, args.prepend(w_obj)) -class Frame(Wrappable): + +class Frame(W_Root): """A frame is an environment supporting the execution of a code object. Abstract base class.""" def __init__(self, space, w_globals=None): - self.space = space - self.w_globals = w_globals # wrapped dict of globals - self.w_locals = None # wrapped dict of locals + self.space = space + self.w_globals = w_globals # wrapped dict of globals + self.w_locals = None # wrapped dict of locals def run(self): "Abstract method to override. Runs the frame" - raise TypeError, "abstract" - + raise TypeError("abstract") + def getdictscope(self): "Get the locals as a dictionary." self.fast2locals() @@ -86,16 +87,16 @@ def getfastscope(self): "Abstract. Get the fast locals as a list." - raise TypeError, "abstract" + raise TypeError("abstract") def setfastscope(self, scope_w): """Abstract. Initialize the fast locals from a list of values, where the order is according to self.getcode().signature().""" - raise TypeError, "abstract" + raise TypeError("abstract") def getfastscopelength(self): "Abstract. Get the expected number of locals." - raise TypeError, "abstract" + raise TypeError("abstract") def fast2locals(self): # Copy values from the fastlocals to self.w_locals diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -8,20 +8,22 @@ from rpython.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from rpython.rlib import jit + funccallunrolling = unrolling_iterable(range(4)) + @jit.elidable_promote() def _get_immutable_code(func): assert not func.can_change_code return func.code -class Function(Wrappable): +class Function(W_Root): """A function is a code object captured with some environment: an object space, a dictionary of globals, default arguments, and an arbitrary 'closure' passed to the code object.""" @@ -40,7 +42,7 @@ self.w_doc = None # lazily read from code.getdocstring() self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary - self.closure = closure # normally, list of Cell instances or None + self.closure = closure # normally, list of Cell instances or None self.defs_w = defs_w self.w_func_dict = None # filled out below if needed self.w_module = None @@ -55,11 +57,15 @@ def call_args(self, args): # delegate activation to code - return self.getcode().funcrun(self, args) + w_res = self.getcode().funcrun(self, args) + assert isinstance(w_res, W_Root) + return w_res def call_obj_args(self, w_obj, args): # delegate activation to code - return self.getcode().funcrun_obj(self, w_obj, args) + w_res = self.getcode().funcrun_obj(self, w_obj, args) + assert isinstance(w_res, W_Root) + return w_res def getcode(self): if jit.we_are_jitted(): @@ -239,7 +245,6 @@ def descr_function_repr(self): return self.getrepr(self.space, 'function %s' % (self.name,)) - # delicate _all = {'': None} @@ -266,8 +271,8 @@ def descr_function__reduce__(self, space): from pypy.interpreter.gateway import BuiltinCode from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) code = self.code if isinstance(code, BuiltinCode): new_inst = mod.get('builtin_function') @@ -275,7 +280,7 @@ space.newtuple([space.wrap(code.identifier)])]) new_inst = mod.get('func_new') - w = space.wrap + w = space.wrap if self.closure is None: w_closure = space.w_None else: @@ -352,7 +357,7 @@ self.defs_w = [] return if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): - raise OperationError( space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None") ) + raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) def fdel_func_defaults(self, space): @@ -379,7 +384,6 @@ "to a string object")) raise - def fdel_func_doc(self, space): self.w_doc = space.w_None @@ -418,7 +422,7 @@ def fget_func_closure(self, space): if self.closure is not None: - w_res = space.newtuple( [ space.wrap(i) for i in self.closure ] ) + w_res = space.newtuple([space.wrap(i) for i in self.closure]) else: w_res = space.w_None return w_res @@ -437,7 +441,7 @@ return space.wrap(Method(space, w_function, None, w_cls)) -class Method(Wrappable): +class Method(W_Root): """A method is a function bound to a specific instance or class.""" _immutable_fields_ = ['w_function', 'w_instance', 'w_class'] @@ -548,18 +552,17 @@ def descr_method_eq(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, Method): + if not isinstance(w_other, Method): return space.w_NotImplemented if self.w_instance is None: - if other.w_instance is not None: + if w_other.w_instance is not None: return space.w_False else: - if other.w_instance is None: + if w_other.w_instance is None: return space.w_False - if not space.eq_w(self.w_instance, other.w_instance): + if not space.eq_w(self.w_instance, w_other.w_instance): return space.w_False - return space.eq(self.w_function, other.w_function) + return space.eq(self.w_function, w_other.w_function) def descr_method_hash(self): space = self.space @@ -575,20 +578,22 @@ mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('method_new') w_instance = self.w_instance or space.w_None - function = space.interpclass_w(self.w_function) - if isinstance(function, Function) and isinstance(function.code, BuiltinCode): + w_function = self.w_function + if (isinstance(w_function, Function) and + isinstance(w_function.code, BuiltinCode)): new_inst = mod.get('builtin_method_new') if space.is_w(w_instance, space.w_None): - tup = [self.w_class, space.wrap(function.name)] + tup = [self.w_class, space.wrap(w_function.name)] else: - tup = [w_instance, space.wrap(function.name)] - elif space.is_w( self.w_class, space.w_None ): + tup = [w_instance, space.wrap(w_function.name)] + elif space.is_w(self.w_class, space.w_None): tup = [self.w_function, w_instance] else: tup = [self.w_function, w_instance, self.w_class] return space.newtuple([new_inst, space.newtuple(tup)]) -class StaticMethod(Wrappable): + +class StaticMethod(W_Root): """The staticmethod objects.""" _immutable_fields_ = ['w_function'] @@ -604,7 +609,8 @@ instance.__init__(w_function) return space.wrap(instance) -class ClassMethod(Wrappable): + +class ClassMethod(W_Root): """The classmethod objects.""" _immutable_fields_ = ['w_function'] diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -4,20 +4,23 @@ * BuiltinCode (call interp-level code from app-level) * app2interp (embed an app-level function into an interp-level callable) * interp2app (publish an interp-level object to be visible from app-level) +* interpindirect2app (publish an interp-level object to be visible from + app-level as an indirect call to implementation) """ import sys import os import types +import inspect import py from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from pypy.interpreter.signature import Signature -from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, - SpaceCache, DescrMismatch) +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, SpaceCache, + DescrMismatch) from pypy.interpreter.error import OperationError from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from rpython.rlib import rstackovf @@ -53,7 +56,7 @@ class UnwrapSpecRecipe(object): "NOT_RPYTHON" - bases_order = [Wrappable, W_Root, ObjSpace, Arguments, object] + bases_order = [W_Root, ObjSpace, Arguments, object] def dispatch(self, el, *args): if isinstance(el, str): @@ -111,13 +114,13 @@ self.orig_arg = iter(original_sig.argnames).next def visit_self(self, cls, app_sig): - self.visit__Wrappable(cls, app_sig) + self.visit__W_Root(cls, app_sig) def checked_space_method(self, typname, app_sig): argname = self.orig_arg() assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typname, argname, self.func)) + "unwrapped %s argument %s of built-in function %r in %r should " + "not start with 'w_'" % (typname, argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname) def visit_index(self, index, app_sig): @@ -147,23 +150,18 @@ def visit_truncatedint_w(self, el, app_sig): self.checked_space_method(el, app_sig) - def visit__Wrappable(self, el, app_sig): - name = el.__name__ - argname = self.orig_arg() - assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (name, argname, self.func)) - app_sig.append(argname) - def visit__ObjSpace(self, el, app_sig): self.orig_arg() def visit__W_Root(self, el, app_sig): - assert el is W_Root, "%s is not W_Root (forgotten to put .im_func in interp2app argument?)" % (el,) argname = self.orig_arg() + if argname == 'self': + assert el is not W_Root + app_sig.append(argname) + return assert argname.startswith('w_'), ( - "argument %s of built-in function %r should " - "start with 'w_'" % (argname, self.func)) + "argument %s of built-in function %r in %r should " + "start with 'w_'" % (argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): @@ -211,15 +209,15 @@ self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) - def visit__Wrappable(self, typ): - self.run_args.append("space.interp_w(%s, %s)" % (self.use(typ), - self.scopenext())) - def visit__ObjSpace(self, el): self.run_args.append('space') def visit__W_Root(self, el): - self.run_args.append(self.scopenext()) + if el is not W_Root: + self.run_args.append("space.interp_w(%s, %s)" % (self.use(el), + self.scopenext())) + else: + self.run_args.append(self.scopenext()) def visit__Arguments(self, el): self.miniglobals['Arguments'] = Arguments @@ -348,17 +346,17 @@ self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) - def visit__Wrappable(self, typ): - self.unwrap.append("space.interp_w(%s, %s)" % (self.use(typ), - self.nextarg())) - def visit__ObjSpace(self, el): if self.finger != 0: raise FastFuncNotSupported self.unwrap.append("space") def visit__W_Root(self, el): - self.unwrap.append(self.nextarg()) + if el is not W_Root: + self.unwrap.append("space.interp_w(%s, %s)" % (self.use(el), + self.nextarg())) + else: + self.unwrap.append(self.nextarg()) def visit__Arguments(self, el): raise FastFuncNotSupported @@ -471,6 +469,7 @@ def __init__(self, default_value): self.default_value = default_value + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -536,7 +535,6 @@ # It is a list of types or singleton objects: # baseobjspace.ObjSpace is used to specify the space argument # baseobjspace.W_Root is for wrapped arguments to keep wrapped - # baseobjspace.Wrappable subclasses imply interp_w and a typecheck # argument.Arguments is for a final rest arguments Arguments object # 'args_w' for fixedview applied to rest arguments # 'w_args' for rest arguments passed as wrapped tuple @@ -555,7 +553,7 @@ assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: - assert issubclass(self_type, Wrappable) + assert issubclass(self_type, W_Root) unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type @@ -799,8 +797,31 @@ w_result = space.w_None return w_result +def interpindirect2app(unbound_meth, unwrap_spec=None): + base_cls = unbound_meth.im_class + func = unbound_meth.im_func + args = inspect.getargs(func.func_code) + if args.varargs or args.keywords: + raise TypeError("Varargs and keywords not supported in unwrap_spec") + assert not func.func_defaults + argspec = ', '.join([arg for arg in args.args[1:]]) + func_code = py.code.Source(""" + def f(w_obj, %(args)s): + return w_obj.%(func_name)s(%(args)s) + """ % {'args': argspec, 'func_name': func.func_name}) + d = {} + exec func_code.compile() in d + f = d['f'] + f.func_name = func.func_name + if unwrap_spec is None: + unwrap_spec = {} + else: + assert isinstance(unwrap_spec, dict) + unwrap_spec = unwrap_spec.copy() + unwrap_spec['w_obj'] = base_cls + return interp2app(globals()['unwrap_spec'](**unwrap_spec)(f)) -class interp2app(Wrappable): +class interp2app(W_Root): """Build a gateway that calls 'f' at interp-level.""" # Takes optionally an unwrap_spec, see BuiltinCode @@ -833,7 +854,7 @@ result = cls.instancecache[key] assert result.__class__ is cls return result - self = Wrappable.__new__(cls) + self = W_Root.__new__(cls) cls.instancecache[key] = self self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, self_type=self_type, diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -1,10 +1,10 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.pyopcode import LoopBlock from rpython.rlib import jit -class GeneratorIterator(Wrappable): +class GeneratorIterator(W_Root): "An iterator created by a generator." _immutable_fields_ = ['pycode'] @@ -94,7 +94,6 @@ w_val = self.space.w_None return self.throw(w_type, w_val, w_tb) - def throw(self, w_type, w_val, w_tb): from pypy.interpreter.pytraceback import check_traceback space = self.space @@ -164,6 +163,7 @@ jitdriver = jit.JitDriver(greens=['pycode'], reds=['self', 'frame', 'results'], name='unpack_into') + def unpack_into(self, results): """This is a hack for performance: runs the generator and collects all produced items in a list.""" diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -89,13 +89,13 @@ return None else: w_value = loader(space) - func = space.interpclass_w(w_value) # the idea of the following code is that all functions that are # directly in a mixed-module are "builtin", e.g. they get a # special type without a __get__ # note that this is not just all functions that contain a # builtin code object, as e.g. methods of builtin types have to # be normal Functions to get the correct binding behaviour + func = w_value if (isinstance(func, Function) and type(func) is not BuiltinFunction): try: diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -2,11 +2,12 @@ Module objects. """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import we_are_translated -class Module(Wrappable): + +class Module(W_Root): """A module.""" _immutable_fields_ = ["w_dict?"] diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -3,12 +3,12 @@ from pypy.interpreter import function, pycode, pyframe from pypy.interpreter.astcompiler import consts -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.mixedmodule import MixedModule -class Cell(Wrappable): +class Cell(W_Root): "A simple container for a wrapped value." def __init__(self, w_value=None): @@ -34,18 +34,17 @@ self.w_value = None def descr__cmp__(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Cell): + if not isinstance(w_other, Cell): return space.w_NotImplemented if self.w_value is None: - if other.w_value is None: + if w_other.w_value is None: return space.newint(0) return space.newint(-1) - elif other.w_value is None: + elif w_other.w_value is None: return space.newint(1) - return space.cmp(self.w_value, other.w_value) + return space.cmp(self.w_value, w_other.w_value) def descr__reduce__(self, space): w_mod = space.getbuiltinmodule('_pickle_support') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -289,29 +289,28 @@ def descr_code__eq__(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, PyCode): + if not isinstance(w_other, PyCode): return space.w_False - areEqual = (self.co_name == other.co_name and - self.co_argcount == other.co_argcount and - self.co_nlocals == other.co_nlocals and - self.co_flags == other.co_flags and - self.co_firstlineno == other.co_firstlineno and - self.co_code == other.co_code and - len(self.co_consts_w) == len(other.co_consts_w) and - len(self.co_names_w) == len(other.co_names_w) and - self.co_varnames == other.co_varnames and - self.co_freevars == other.co_freevars and - self.co_cellvars == other.co_cellvars) + areEqual = (self.co_name == w_other.co_name and + self.co_argcount == w_other.co_argcount and + self.co_nlocals == w_other.co_nlocals and + self.co_flags == w_other.co_flags and + self.co_firstlineno == w_other.co_firstlineno and + self.co_code == w_other.co_code and + len(self.co_consts_w) == len(w_other.co_consts_w) and + len(self.co_names_w) == len(w_other.co_names_w) and + self.co_varnames == w_other.co_varnames and + self.co_freevars == w_other.co_freevars and + self.co_cellvars == w_other.co_cellvars) if not areEqual: return space.w_False for i in range(len(self.co_names_w)): - if not space.eq_w(self.co_names_w[i], other.co_names_w[i]): + if not space.eq_w(self.co_names_w[i], w_other.co_names_w[i]): return space.w_False for i in range(len(self.co_consts_w)): - if not space.eq_w(self.co_consts_w[i], other.co_consts_w[i]): + if not space.eq_w(self.co_consts_w[i], w_other.co_consts_w[i]): return space.w_False return space.w_True diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -6,7 +6,7 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import gateway, function, eval, pyframe, pytraceback from pypy.interpreter.pycode import PyCode, BytecodeCorruption from rpython.tool.sourcetools import func_with_new_name @@ -607,16 +607,15 @@ if self.space.is_w(w_top, self.space.w_None): # case of a finally: block with no exception return None - unroller = self.space.interpclass_w(w_top) - if isinstance(unroller, SuspendedUnroller): + if isinstance(w_top, SuspendedUnroller): # case of a finally: block with a suspended unroller - return unroller + return w_top else: # case of an except: block. We popped the exception type self.popvalue() # Now we pop the exception value - unroller = self.space.interpclass_w(self.popvalue()) - assert unroller is not None - return unroller + w_unroller = self.popvalue() + assert w_unroller is not None + return w_unroller def BUILD_CLASS(self, oparg, next_instr): w_methodsdict = self.popvalue() @@ -944,11 +943,9 @@ w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) - unroller = self.space.interpclass_w(w_unroller) - is_app_exc = (unroller is not None and - isinstance(unroller, SApplicationException)) - if is_app_exc: - operr = unroller.operr + if isinstance(w_unroller, SApplicationException): + # app-level exception + operr = w_unroller.operr self.last_exception = operr w_traceback = self.space.wrap(operr.get_traceback()) w_suppress = self.call_contextmanager_exit_function( @@ -1144,11 +1141,15 @@ class ExitFrame(Exception): pass + class Return(ExitFrame): """Raised when exiting a frame via a 'return' statement.""" + + class Yield(ExitFrame): """Raised when exiting a frame via a 'yield' statement.""" + class RaiseWithExplicitTraceback(Exception): """Raised at interp-level by a 0- or 3-arguments 'raise' statement.""" def __init__(self, operr): @@ -1157,7 +1158,7 @@ ### Frame Blocks ### -class SuspendedUnroller(Wrappable): +class SuspendedUnroller(W_Root): """Abstract base class for interpreter-level objects that instruct the interpreter to change the control flow and the block stack. diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -4,7 +4,7 @@ from rpython.tool.error import offset2lineno -class PyTraceback(baseobjspace.Wrappable): +class PyTraceback(baseobjspace.W_Root): """Traceback object Public app-level fields: @@ -38,7 +38,7 @@ w(self.frame), w(self.lasti), w(self.next), - ] + ] nt = space.newtuple return nt([new_inst, nt(tup_base), nt(tup_state)]) @@ -61,8 +61,7 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if w_tb is None or not space.is_true(space.isinstance(w_tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) - return tb + return w_tb diff --git a/pypy/interpreter/special.py b/pypy/interpreter/special.py --- a/pypy/interpreter/special.py +++ b/pypy/interpreter/special.py @@ -1,15 +1,17 @@ +from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.baseobjspace import Wrappable -class Ellipsis(Wrappable): +class Ellipsis(W_Root): def __init__(self, space): - self.space = space + self.space = space + def descr__repr__(self): return self.space.wrap('Ellipsis') -class NotImplemented(Wrappable): + +class NotImplemented(W_Root): def __init__(self, space): - self.space = space + self.space = space + def descr__repr__(self): return self.space.wrap('NotImplemented') - 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 @@ -25,7 +25,7 @@ def d(self, w_boo): pass code = gateway.BuiltinCode(d, unwrap_spec= ['self', - gateway.W_Root], self_type=gateway.Wrappable) + gateway.W_Root], self_type=gateway.W_Root) assert code.signature() == Signature(['self', 'boo'], None, None) def e(space, w_x, w_y, __args__): pass @@ -129,6 +129,36 @@ space.call_function(w_app_g3, w('foo'), w('bar')), w('foobar')) + def test_interpindirect2app(self): + space = self.space + class BaseA(W_Root): + def method(self, space, x): + pass + + class A(BaseA): + def method(self, space, x): + return space.wrap(x + 2) + + class B(BaseA): + def method(self, space, x): + return space.wrap(x + 1) + + class FakeTypeDef(object): + rawdict = {} + bases = {} + applevel_subclasses_base = None + name = 'foo' + hasdict = False + weakrefable = False + doc = 'xyz' + + meth = gateway.interpindirect2app(BaseA.method, {'x': int}) + w_c = space.wrap(meth) + w_a = A() + w_b = B() + assert space.int_w(space.call_function(w_c, w_a, space.wrap(1))) == 1 + 2 + assert space.int_w(space.call_function(w_c, w_b, space.wrap(-10))) == -10 + 1 + def test_interp2app_unwrap_spec(self): space = self.space w = space.wrap @@ -167,7 +197,7 @@ space.wrap(True)) def test_caching_methods(self): - class Base(gateway.Wrappable): + class Base(gateway.W_Root): def f(self): return 1 diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py --- a/pypy/interpreter/test/test_typedef.py +++ b/pypy/interpreter/test/test_typedef.py @@ -1,7 +1,7 @@ import gc from pypy.interpreter import typedef from rpython.tool.udir import udir -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, interp2app # this test isn't so much to test that the objspace interface *works* @@ -139,7 +139,7 @@ cls, len(set), list(set)) def test_getsetproperty(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): pass def fget(self, space, w_self): assert self is prop @@ -151,7 +151,7 @@ assert self.space.getattr(w_obj, self.space.wrap('x')) is self.space.w_None def test_getsetproperty_arguments(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): def fget1(space, w_self): assert isinstance(space, ObjSpace) assert isinstance(w_self, W_SomeType) @@ -169,7 +169,7 @@ assert space.getattr(w_obj, space.wrap('x2')) == space.w_None def test_unhashable(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): pass W_SomeType.typedef = typedef.TypeDef( 'some_type', @@ -183,12 +183,12 @@ def test_destructor(self): space = self.space - class W_Level1(Wrappable): + class W_Level1(W_Root): def __init__(self, space1): assert space1 is space def __del__(self): space.call_method(w_seen, 'append', space.wrap(1)) - class W_Level2(Wrappable): + class W_Level2(W_Root): def __init__(self, space1): assert space1 is space def __del__(self): @@ -261,7 +261,7 @@ assert space.unwrap(w_seen) == [6, 2] def test_multiple_inheritance(self): - class W_A(Wrappable): + class W_A(W_Root): a = 1 b = 2 class W_C(W_A): @@ -270,7 +270,7 @@ a = typedef.interp_attrproperty("a", cls=W_A), b = typedef.interp_attrproperty("b", cls=W_A), ) - class W_B(Wrappable): + class W_B(W_Root): pass def standalone_method(space, w_obj): if isinstance(w_obj, W_A): @@ -305,7 +305,7 @@ assert_method(w_o2, "c", False) def test_total_ordering(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): def __init__(self, space, x): self.space = space self.x = x diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,7 +1,7 @@ import py from pypy.interpreter.argument import Arguments -from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch +from pypy.interpreter.baseobjspace import W_Root, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, WrappedDefault) @@ -381,7 +381,7 @@ """ else: cls_name = cls.__name__ - assert issubclass(cls, Wrappable) + assert issubclass(cls, W_Root) source = """ def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s): obj = space.descr_self_interp_w(%(cls_name)s, w_obj) @@ -439,7 +439,7 @@ res = miniglobals['objclass_getter'], cls return res -class GetSetProperty(Wrappable): +class GetSetProperty(W_Root): _immutable_fields_ = ["fget", "fset", "fdel"] @specialize.arg(7) @@ -542,7 +542,7 @@ GetSetProperty.typedef.acceptable_as_base_class = False -class Member(Wrappable): +class Member(W_Root): """For slots.""" _immutable_ = True @@ -677,7 +677,7 @@ weakref_descr.name = '__weakref__' def make_weakref_descr(cls): - """Make instances of the Wrappable subclass 'cls' weakrefable. + """Make instances of the W_Root subclass 'cls' weakrefable. This returns the '__weakref__' desctriptor to use for the TypeDef. Note that if the class also defines a custom '__del__', the __del__ should call self.clear_all_weakrefs() before it clears @@ -686,10 +686,13 @@ # force the interface into the given cls def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None + cls._lifeline_ = None cls.getweakref = getweakref cls.setweakref = setweakref diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -116,9 +116,8 @@ return space.builtin if space.is_true(space.isinstance(w_builtin, space.w_dict)): return module.Module(space, None, w_builtin) - builtin = space.interpclass_w(w_builtin) - if isinstance(builtin, module.Module): - return builtin + if isinstance(w_builtin, module.Module): + return w_builtin # no builtin! make a default one. Give them None, at least. builtin = module.Module(space, None) space.setitem(builtin.w_dict, space.wrap('None'), space.w_None) diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -88,11 +88,9 @@ return space.is_true(w_result) # -- case (old-style instance, old-style class) - oldstyleclass = space.interpclass_w(w_klass_or_tuple) - if isinstance(oldstyleclass, W_ClassObject): - oldstyleinst = space.interpclass_w(w_obj) - if isinstance(oldstyleinst, W_InstanceObject): - return oldstyleinst.w_class.is_subclass_of(oldstyleclass) + if isinstance(w_klass_or_tuple, W_ClassObject): + if isinstance(w_obj, W_InstanceObject): + return w_obj.w_class.is_subclass_of(w_klass_or_tuple) return _abstract_isinstance_w_helper(space, w_obj, w_klass_or_tuple) @jit.dont_look_inside @@ -152,11 +150,9 @@ return space.is_true(w_result) # -- case (old-style class, old-style class) - oldstylederived = space.interpclass_w(w_derived) - if isinstance(oldstylederived, W_ClassObject): - oldstyleklass = space.interpclass_w(w_klass_or_tuple) - if isinstance(oldstyleklass, W_ClassObject): - return oldstylederived.is_subclass_of(oldstyleklass) + if isinstance(w_derived, W_ClassObject): + if isinstance(w_klass_or_tuple, W_ClassObject): + return w_derived.is_subclass_of(w_klass_or_tuple) else: check_class(space, w_derived, "issubclass() arg 1 must be a class") # from here on, we are sure that w_derived is a class-like object @@ -171,31 +167,26 @@ # Exception helpers def exception_is_valid_obj_as_class_w(space, w_obj): - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_ClassObject): + if isinstance(w_obj, W_ClassObject): return True return BaseObjSpace.exception_is_valid_obj_as_class_w(space, w_obj) def exception_is_valid_class_w(space, w_cls): - cls = space.interpclass_w(w_cls) - if isinstance(cls, W_ClassObject): + if isinstance(w_cls, W_ClassObject): return True return BaseObjSpace.exception_is_valid_class_w(space, w_cls) def exception_getclass(space, w_obj): - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_InstanceObject): - return obj.w_class + if isinstance(w_obj, W_InstanceObject): + return w_obj.w_class return BaseObjSpace.exception_getclass(space, w_obj) def exception_issubclass_w(space, w_cls1, w_cls2): - cls1 = space.interpclass_w(w_cls1) - cls2 = space.interpclass_w(w_cls2) - if isinstance(cls1, W_ClassObject): - if isinstance(cls2, W_ClassObject): - return cls1.is_subclass_of(cls2) + if isinstance(w_cls1, W_ClassObject): + if isinstance(w_cls2, W_ClassObject): + return w_cls1.is_subclass_of(w_cls2) return False - if isinstance(cls2, W_ClassObject): + if isinstance(w_cls2, W_ClassObject): return False return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -14,7 +14,7 @@ # ____________________________________________________________ -def sorted(lst, cmp=None, key=None, reverse=None): +def sorted(lst, cmp=None, key=None, reverse=False): "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list" sorted_lst = list(lst) sorted_lst.sort(cmp, key, reverse) diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -79,8 +79,7 @@ space.wrap(' \t')), "", "eval") - codeobj = space.interpclass_w(w_code) - if not isinstance(codeobj, PyCode): + if not isinstance(w_code, PyCode): raise OperationError(space.w_TypeError, w('eval() arg 1 must be a string or code object')) @@ -102,4 +101,4 @@ # the gettopframe_nohidden()). I bet no test fails, and it's a really # obscure case. - return codeobj.exec_code(space, w_globals, w_locals) + return w_code.exec_code(space, w_globals, w_locals) diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault @@ -6,7 +6,8 @@ generic_new_descr) from pypy.objspace.descroperation import object_getattribute -class W_Super(Wrappable): + +class W_Super(W_Root): def __init__(self, space, w_starttype, w_objtype, w_self): self.w_starttype = w_starttype self.w_objtype = w_objtype @@ -91,7 +92,8 @@ super(C, self).meth(arg)""" ) -class W_Property(Wrappable): + +class W_Property(W_Root): _immutable_fields_ = ["w_fget", "w_fset", "w_fdel"] def __init__(self, space): @@ -192,4 +194,3 @@ # descriptor for the instances. W_Property.typedef.rawdict['__doc__'] = interp_attrproperty_w('w_doc', W_Property) - diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -3,7 +3,7 @@ """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef @@ -226,8 +226,8 @@ """ return min_max(space, __args__, "min") -class W_Enumerate(Wrappable): From noreply at buildbot.pypy.org Sat Mar 23 00:42:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 00:42:53 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130322234253.40EEC1C15A2@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62668:f001c220bcc4 Date: 2013-03-22 16:42 -0700 http://bitbucket.org/pypy/pypy/changeset/f001c220bcc4/ Log: fix whatsnew 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 @@ -108,3 +108,5 @@ Documentation fixes after going through the docs at PyCon 2013 sprint. .. branch: extregistry-refactor + +.. branch: remove-list-smm From noreply at buildbot.pypy.org Sat Mar 23 00:47:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 00:47:13 +0100 (CET) Subject: [pypy-commit] pypy remove-list-smm: close merged branch Message-ID: <20130322234713.DE59E1C15A1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-list-smm Changeset: r62669:86cdf9caeaea Date: 2013-03-22 16:46 -0700 http://bitbucket.org/pypy/pypy/changeset/86cdf9caeaea/ Log: close merged branch From noreply at buildbot.pypy.org Sat Mar 23 00:47:15 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 00:47:15 +0100 (CET) Subject: [pypy-commit] pypy default: dummy merge Message-ID: <20130322234715.1DD951C15A1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62670:1a3d9bf713f4 Date: 2013-03-22 16:47 -0700 http://bitbucket.org/pypy/pypy/changeset/1a3d9bf713f4/ Log: dummy merge From noreply at buildbot.pypy.org Sat Mar 23 01:35:39 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:35:39 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: initial support for method templates Message-ID: <20130323003539.DCB231C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62671:51d3f7728e91 Date: 2013-03-22 17:34 -0700 http://bitbucket.org/pypy/pypy/changeset/51d3f7728e91/ Log: initial support for method templates diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py --- a/pypy/module/cppyy/capi/__init__.py +++ b/pypy/module/cppyy/capi/__init__.py @@ -367,6 +367,30 @@ def c_method_signature(cppscope, index): return charp2str_free(_c_method_signature(cppscope.handle, index)) +_c_method_is_template = rffi.llexternal( + "cppyy_method_is_template", + [C_SCOPE, C_INDEX], rffi.INT, + threadsafe=ts_reflect, + compilation_info=backend.eci) +def c_method_is_template(cppscope, index): + return _c_method_is_template(cppscope.handle, index) +_c_method_num_template_args = rffi.llexternal( + "cppyy_method_num_template_args", + [C_SCOPE, C_INDEX], rffi.INT, + threadsafe=ts_reflect, + compilation_info=backend.eci) +_c_method_template_arg_name = rffi.llexternal( + "cppyy_method_template_arg_name", + [C_SCOPE, C_INDEX, C_INDEX], rffi.CCHARP, + threadsafe=ts_reflect, + compilation_info=backend.eci) +def c_template_args(cppscope, index): + nargs = _c_method_num_template_args(cppscope.handle, index) + args = [c_resolve_name( + charp2str_free(_c_method_template_arg_name(cppscope.handle, index, iarg))) + for iarg in range(nargs)] + return args + _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h --- a/pypy/module/cppyy/include/capi.h +++ b/pypy/module/cppyy/include/capi.h @@ -81,6 +81,10 @@ char* cppyy_method_arg_default(cppyy_scope_t scope, cppyy_index_t idx, int arg_index); char* cppyy_method_signature(cppyy_scope_t scope, cppyy_index_t idx); + int cppyy_method_is_template(cppyy_scope_t scope, cppyy_index_t idx); + int cppyy_method_num_template_args(cppyy_scope_t scope, cppyy_index_t idx); + char* cppyy_method_template_arg_name(cppyy_scope_t scope, cppyy_index_t idx, cppyy_index_t iarg); + cppyy_method_t cppyy_get_method(cppyy_scope_t scope, cppyy_index_t idx); cppyy_index_t cppyy_get_global_operator( cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char* op); diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -373,6 +373,39 @@ return "CPPFunction: %s" % self.signature() +class CPPTemplatedCall(CPPMethod): # TODO: unnecessary derivation to make rtyper happy + """Method dispatcher that first needs to resolve the template instance. + Note that the derivation is from object: the CPPMethod is a data member.""" + + _attrs_ = ['space', 'templ_args', 'method'] + _immutable_ = True + + def __init__(self, space, templ_args, containing_scope, method_index, arg_defs, args_required): + self.space = space + self.templ_args = templ_args + # TODO: might have to specialize for CPPTemplatedCall on CPPMethod/CPPFunction here + self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) + + def call(self, cppthis, args_w): + assert lltype.typeOf(cppthis) == capi.C_OBJECT + for i in range(len(args_w)): + try: + s = self.space.str_w(args_w[i]) + except OperationError: + s = self.space.str_w(self.space.getattr(args_w[i], self.space.wrap('__name__'))) + s = capi.c_resolve_name(s) + if s != self.templ_args[i]: + raise OperationError(self.space.w_TypeError, self.space.wrap( + "non-matching template (got %s where %s expected" % (s, self.templ_args[i]))) + return W_CPPBoundMethod(cppthis, self.method) + + def signature(self): + return self.method.signature() + + def __repr__(self): + return "CPPTemplatedCall: %s" % self.signature() + + class CPPConstructor(CPPMethod): """Method dispatcher that constructs new objects. This method can not have a fast path, a the allocation of the object is currently left to the @@ -500,6 +533,22 @@ ) +class W_CPPBoundMethod(Wrappable): + _attrs_ = ['cppthis', 'method'] + + def __init__(self, cppthis, method): + self.cppthis = cppthis + self.method = method + + def __call__(self, args_w): + return self.method.call(self.cppthis, args_w) + +W_CPPBoundMethod.typedef = TypeDef( + 'CPPBoundMethod', + __call__ = interp2app(W_CPPBoundMethod.__call__), +) + + class W_CPPDataMember(Wrappable): _attrs_ = ['space', 'scope', 'converter', 'offset'] _immutable_fields = ['scope', 'converter', 'offset'] @@ -766,7 +815,6 @@ self.default_constructor = None def _make_cppfunction(self, pyname, index): - default_constructor = False num_args = capi.c_method_num_args(self, index) args_required = capi.c_method_req_args(self, index) arg_defs = [] @@ -775,18 +823,18 @@ arg_dflt = capi.c_method_arg_default(self, index, i) arg_defs.append((arg_type, arg_dflt)) if capi.c_is_constructor(self, index): - cls = CPPConstructor + cppfunction = CPPConstructor(self.space, self, index, arg_defs, args_required) if args_required == 0: - default_constructor = True + self.default_constructor = cppfunction + elif capi.c_method_is_template(self, index): + templ_args = capi.c_template_args(self, index) + cppfunction = CPPTemplatedCall(self.space, templ_args, self, index, arg_defs, args_required) elif capi.c_is_staticmethod(self, index): - cls = CPPFunction + cppfunction = CPPFunction(self.space, self, index, arg_defs, args_required) elif pyname == "__setitem__": - cls = CPPSetItem + cppfunction = CPPSetItem(self.space, self, index, arg_defs, args_required) else: - cls = CPPMethod - cppfunction = cls(self.space, self, index, arg_defs, args_required) - if default_constructor: - self.default_constructor = cppfunction + cppfunction = CPPMethod(self.space, self, index, arg_defs, args_required) return cppfunction def _find_datamembers(self): diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx --- a/pypy/module/cppyy/src/cintcwrapper.cxx +++ b/pypy/module/cppyy/src/cintcwrapper.cxx @@ -675,7 +675,13 @@ char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t idx) { TFunction* f = type_get_method(handle, idx); - return cppstring_to_cstring(f->GetName()); + std::string name = f->GetName(); + TClassRef& cr = type_from_handle(handle); + if (cr.GetClass() && cppyy_is_constructor(handle, idx)) + return cppstring_to_cstring(name); + if (cppyy_method_is_template(handle, idx)) + return cppstring_to_cstring(name.substr(0, name.find('<'))); + return cppstring_to_cstring(name); } char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t idx) { @@ -726,6 +732,29 @@ } +int cppyy_method_is_template(cppyy_scope_t handle, cppyy_index_t idx) { + TClassRef& cr = type_from_handle(handle); + TFunction* f = type_get_method(handle, idx); + std::string name = f->GetName(); + return (name[name.size()-1] == '>') && (name.find('<') != std::string::npos); +} + +int cppyy_method_num_template_args(cppyy_scope_t /*handle*/, cppyy_index_t /*idx*/) { +// TODO: somehow count from the actual arguments + return 1; +} + +char* cppyy_method_template_arg_name( + cppyy_scope_t handle, cppyy_index_t idx, cppyy_index_t /*iarg*/) { +// TODO: return only the name for the requested arg + TClassRef& cr = type_from_handle(handle); + TFunction* f = type_get_method(handle, idx); + std::string name = f->GetName(); + std::string::size_type pos = name.find('<'); + return cppstring_to_cstring(resolve_typedef(name.substr(pos+1, name.size()-pos-2))); +} + + cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t idx) { TClassRef& cr = type_from_handle(handle); TFunction* f = type_get_method(handle, idx); diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx --- a/pypy/module/cppyy/src/reflexcwrapper.cxx +++ b/pypy/module/cppyy/src/reflexcwrapper.cxx @@ -384,7 +384,11 @@ std::string name; if (m.IsConstructor()) name = s.Name(Reflex::FINAL); // to get proper name for templates - else + else if (m.IsTemplateInstance()) { + name = m.Name(); + std::string::size_type pos = name.find('<'); + name = name.substr(0, pos); // strip template argument portion for overload + } else name = m.Name(); return cppstring_to_cstring(name); } @@ -444,10 +448,33 @@ return cppstring_to_cstring(sig.str()); } + +int cppyy_method_is_template(cppyy_scope_t handle, cppyy_index_t method_index) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + return m.IsTemplateInstance(); +} + +int cppyy_method_num_template_args(cppyy_scope_t handle, cppyy_index_t method_index) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + assert(m.IsTemplateInstance()); + return m.TemplateArgumentSize(); +} + +char* cppyy_method_template_arg_name( + cppyy_scope_t handle, cppyy_index_t method_index, cppyy_index_t iarg) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + assert(m.IsTemplateInstance()); + return cppstring_to_cstring( + m.TemplateArgumentAt(iarg).Name(Reflex::SCOPED|Reflex::QUALIFIED)); +} + + cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); - assert(m.IsFunctionMember()); return (cppyy_method_t)m.Stubfunction(); } diff --git a/pypy/module/cppyy/test/advancedcpp.cxx b/pypy/module/cppyy/test/advancedcpp.cxx --- a/pypy/module/cppyy/test/advancedcpp.cxx +++ b/pypy/module/cppyy/test/advancedcpp.cxx @@ -103,3 +103,14 @@ --s_instances; ::operator delete(p); } + + +// more template testing +long my_templated_method_class::get_size() { return -1; } + +long my_templated_method_class::get_char_size() { return (long)sizeof(char); } +long my_templated_method_class::get_int_size() { return (long)sizeof(int); } +long my_templated_method_class::get_long_size() { return (long)sizeof(long); } +long my_templated_method_class::get_float_size() { return (long)sizeof(float); } +long my_templated_method_class::get_double_size() { return (long)sizeof(double); } +long my_templated_method_class::get_self_size() { return (long)sizeof(my_templated_method_class); } diff --git a/pypy/module/cppyy/test/advancedcpp.h b/pypy/module/cppyy/test/advancedcpp.h --- a/pypy/module/cppyy/test/advancedcpp.h +++ b/pypy/module/cppyy/test/advancedcpp.h @@ -371,3 +371,49 @@ void* operator new(std::size_t, void* p) throw(); void operator delete(void* p, std::size_t size); }; + + +//=========================================================================== +template // more template testing +class my_templated_class { +public: + T m_b; +}; + +template +T my_templated_function(T t) { return t; } + +template class my_templated_class >; +template char my_templated_function(char); +template double my_templated_function(double); + +class my_templated_method_class { +public: + long get_size(); // to get around bug in genreflex + template long get_size(); + + long get_char_size(); + long get_int_size(); + long get_long_size(); + long get_float_size(); + long get_double_size(); + + long get_self_size(); + +private: + double m_data[3]; +}; + +template +inline long my_templated_method_class::get_size() { + return sizeof(B); +} + +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); + +typedef my_templated_method_class my_typedef_t; +template long my_templated_method_class::get_size(); diff --git a/pypy/module/cppyy/test/advancedcpp.xml b/pypy/module/cppyy/test/advancedcpp.xml --- a/pypy/module/cppyy/test/advancedcpp.xml +++ b/pypy/module/cppyy/test/advancedcpp.xml @@ -39,4 +39,10 @@ + + + + + + diff --git a/pypy/module/cppyy/test/advancedcpp_LinkDef.h b/pypy/module/cppyy/test/advancedcpp_LinkDef.h --- a/pypy/module/cppyy/test/advancedcpp_LinkDef.h +++ b/pypy/module/cppyy/test/advancedcpp_LinkDef.h @@ -66,4 +66,10 @@ #pragma link C++ class new_overloader; +#pragma link C++ class my_templated_class >; +#pragma link C++ function my_templated_function(char); +#pragma link C++ function my_templated_function(double); +#pragma link C++ class my_templated_method_class; +#pragma link C++ typedef my_typedef_t; + #endif diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -539,3 +539,43 @@ import gc gc.collect() assert cppyy.gbl.new_overloader.s_instances == 0 + + def test15_template_instantiation_with_vector_of_float(self): + """Test template instantiation with a std::vector""" + + import cppyy + + # the following will simply fail if there is a naming problem (e.g. + # std::, allocator, etc., etc.); note the parsing required ... + b = cppyy.gbl.my_templated_class(cppyy.gbl.std.vector(float))() + + for i in range(5): + b.m_b.push_back(i) + assert round(b.m_b[i], 5) == float(i) + + def test16_template_member_functions(self): + """Test template member functions lookup and calls""" + + import cppyy + + m = cppyy.gbl.my_templated_method_class() + + assert m.get_size('char')() == m.get_char_size() + assert m.get_size(int)() == m.get_int_size() + assert m.get_size(long)() == m.get_long_size() + assert m.get_size(float)() == m.get_float_size() + assert m.get_size('double')() == m.get_double_size() + assert m.get_size('my_templated_method_class')() == m.get_self_size() + assert m.get_size('my_typedef_t')() == m.get_self_size() + + def test17_template_global_functions(self): + """Test template global function lookup and calls""" + + import cppyy + + f = cppyy.gbl.my_templated_function + + assert f('c') == 'c' + assert type(f('c')) == type('c') + assert f(3.) == 3. + assert type(f(4.)) == type(4.) From noreply at buildbot.pypy.org Sat Mar 23 01:49:08 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:08 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: support for templated member functions Message-ID: <20130323004908.CCEC31C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62672:fd24e89f5e2c Date: 2013-03-21 17:44 -0700 http://bitbucket.org/pypy/pypy/changeset/fd24e89f5e2c/ Log: support for templated member functions diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py --- a/pypy/module/cppyy/capi/__init__.py +++ b/pypy/module/cppyy/capi/__init__.py @@ -367,6 +367,30 @@ def c_method_signature(cppscope, index): return charp2str_free(_c_method_signature(cppscope.handle, index)) +_c_method_is_template = rffi.llexternal( + "cppyy_method_is_template", + [C_SCOPE, C_INDEX], rffi.INT, + threadsafe=ts_reflect, + compilation_info=backend.eci) +def c_method_is_template(cppscope, index): + return _c_method_is_template(cppscope.handle, index) +_c_method_num_template_args = rffi.llexternal( + "cppyy_method_num_template_args", + [C_SCOPE, C_INDEX], rffi.INT, + threadsafe=ts_reflect, + compilation_info=backend.eci) +_c_method_template_arg_name = rffi.llexternal( + "cppyy_method_template_arg_name", + [C_SCOPE, C_INDEX, C_INDEX], rffi.CCHARP, + threadsafe=ts_reflect, + compilation_info=backend.eci) +def c_template_args(cppscope, index): + nargs = _c_method_num_template_args(cppscope.handle, index) + args = [c_resolve_name( + charp2str_free(_c_method_template_arg_name(cppscope.handle, index, iarg))) + for iarg in range(nargs)] + return args + _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h --- a/pypy/module/cppyy/include/capi.h +++ b/pypy/module/cppyy/include/capi.h @@ -81,6 +81,10 @@ char* cppyy_method_arg_default(cppyy_scope_t scope, cppyy_index_t idx, int arg_index); char* cppyy_method_signature(cppyy_scope_t scope, cppyy_index_t idx); + int cppyy_method_is_template(cppyy_scope_t scope, cppyy_index_t idx); + int cppyy_method_num_template_args(cppyy_scope_t scope, cppyy_index_t idx); + char* cppyy_method_template_arg_name(cppyy_scope_t scope, cppyy_index_t idx, cppyy_index_t iarg); + cppyy_method_t cppyy_get_method(cppyy_scope_t scope, cppyy_index_t idx); cppyy_index_t cppyy_get_global_operator( cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char* op); diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -373,6 +373,38 @@ return "CPPFunction: %s" % self.signature() +class CPPTemplatedMember(object): + """Method dispatcher that first needs to resolve the template instance. + Note that the derivation is from object: the CPPMethod is a data member.""" + + _attrs_ = ['space', 'templ_args', 'method'] + _immutable_ = True + + def __init__(self, space, templ_args, containing_scope, method_index, arg_defs, args_required): + self.space = space + self.templ_args = templ_args + self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) + + def call(self, cppthis, args_w): + assert lltype.typeOf(cppthis) == capi.C_OBJECT + for i in range(len(args_w)): + try: + s = self.space.str_w(args_w[i]) + except OperationError: + s = self.space.str_w(self.space.getattr(args_w[i], self.space.wrap('__name__'))) + s = capi.c_resolve_name(s) + if s != self.templ_args[i]: + raise OperationError(self.space.w_TypeError, self.space.wrap( + "non-matching template (got %s where %s expected" % (s, self.templ_args[i]))) + return W_CPPBoundMethod(cppthis, self.method) + + def signature(self): + return self.method.signature() + + def __repr__(self): + return "CPPTemplatedMember: %s" % self.signature() + + class CPPConstructor(CPPMethod): """Method dispatcher that constructs new objects. This method can not have a fast path, a the allocation of the object is currently left to the @@ -500,6 +532,22 @@ ) +class W_CPPBoundMethod(Wrappable): + _attrs_ = ['cppthis', 'method'] + + def __init__(self, cppthis, method): + self.cppthis = cppthis + self.method = method + + def __call__(self, args_w): + return self.method.call(self.cppthis, args_w) + +W_CPPBoundMethod.typedef = TypeDef( + 'CPPBoundMethod', + __call__ = interp2app(W_CPPBoundMethod.__call__), +) + + class W_CPPDataMember(Wrappable): _attrs_ = ['space', 'scope', 'converter', 'offset'] _immutable_fields = ['scope', 'converter', 'offset'] @@ -766,7 +814,6 @@ self.default_constructor = None def _make_cppfunction(self, pyname, index): - default_constructor = False num_args = capi.c_method_num_args(self, index) args_required = capi.c_method_req_args(self, index) arg_defs = [] @@ -775,18 +822,18 @@ arg_dflt = capi.c_method_arg_default(self, index, i) arg_defs.append((arg_type, arg_dflt)) if capi.c_is_constructor(self, index): - cls = CPPConstructor + cppfunction = CPPConstructor(self.space, self, index, arg_defs, args_required) if args_required == 0: - default_constructor = True + self.default_constructor = cppfunction elif capi.c_is_staticmethod(self, index): - cls = CPPFunction + cppfunction = CPPFunction(self.space, self, index, arg_defs, args_required) elif pyname == "__setitem__": - cls = CPPSetItem + cppfunction = CPPSetItem(self.space, self, index, arg_defs, args_required) + elif capi.c_method_is_template(self, index): + templ_args = capi.c_template_args(self, index) + cppfunction = CPPTemplatedMember(self.space, templ_args, self, index, arg_defs, args_required) else: - cls = CPPMethod - cppfunction = cls(self.space, self, index, arg_defs, args_required) - if default_constructor: - self.default_constructor = cppfunction + cppfunction = CPPMethod(self.space, self, index, arg_defs, args_required) return cppfunction def _find_datamembers(self): diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx --- a/pypy/module/cppyy/src/reflexcwrapper.cxx +++ b/pypy/module/cppyy/src/reflexcwrapper.cxx @@ -384,7 +384,11 @@ std::string name; if (m.IsConstructor()) name = s.Name(Reflex::FINAL); // to get proper name for templates - else + else if (m.IsTemplateInstance()) { + name = m.Name(); + std::string::size_type pos = name.find("<"); + name = name.substr(0, pos); // strip template argument portion for overload + } else name = m.Name(); return cppstring_to_cstring(name); } @@ -444,10 +448,31 @@ return cppstring_to_cstring(sig.str()); } +int cppyy_method_is_template(cppyy_scope_t handle, cppyy_index_t method_index) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + return m.IsTemplateInstance(); +} + +int cppyy_method_num_template_args(cppyy_scope_t handle, cppyy_index_t method_index) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + assert(m.IsTemplateInstance()); + return m.TemplateArgumentSize(); +} + +char* cppyy_method_template_arg_name( + cppyy_scope_t handle, cppyy_index_t method_index, cppyy_index_t iarg) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + assert(m.IsTemplateInstance()); + return cppstring_to_cstring( + m.TemplateArgumentAt(iarg).Name(Reflex::SCOPED|Reflex::QUALIFIED)); +} + cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); - assert(m.IsFunctionMember()); return (cppyy_method_t)m.Stubfunction(); } diff --git a/pypy/module/cppyy/test/advancedcpp.cxx b/pypy/module/cppyy/test/advancedcpp.cxx --- a/pypy/module/cppyy/test/advancedcpp.cxx +++ b/pypy/module/cppyy/test/advancedcpp.cxx @@ -103,3 +103,14 @@ --s_instances; ::operator delete(p); } + + +// more template testing +long my_templated_method_class::get_size() { return -1; } + +long my_templated_method_class::get_char_size() { return (long)sizeof(char); } +long my_templated_method_class::get_int_size() { return (long)sizeof(int); } +long my_templated_method_class::get_long_size() { return (long)sizeof(long); } +long my_templated_method_class::get_float_size() { return (long)sizeof(float); } +long my_templated_method_class::get_double_size() { return (long)sizeof(double); } +long my_templated_method_class::get_self_size() { return (long)sizeof(my_templated_method_class); } diff --git a/pypy/module/cppyy/test/advancedcpp.h b/pypy/module/cppyy/test/advancedcpp.h --- a/pypy/module/cppyy/test/advancedcpp.h +++ b/pypy/module/cppyy/test/advancedcpp.h @@ -371,3 +371,49 @@ void* operator new(std::size_t, void* p) throw(); void operator delete(void* p, std::size_t size); }; + + +//=========================================================================== +template // more template testing +class my_templated_class { +public: + T m_b; +}; + +template +T my_templated_function(T t) { return t; } + +template class my_templated_class >; +template int my_templated_function(int); +template double my_templated_function(double); + +class my_templated_method_class { +public: + long get_size(); // to get around bug in genreflex + template long get_size(); + + long get_char_size(); + long get_int_size(); + long get_long_size(); + long get_float_size(); + long get_double_size(); + + long get_self_size(); + +private: + double m_data[3]; +}; + +template +inline long my_templated_method_class::get_size() { + return sizeof(B); +} + +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); +template long my_templated_method_class::get_size(); + +typedef my_templated_method_class my_typedef_t; +template long my_templated_method_class::get_size(); diff --git a/pypy/module/cppyy/test/advancedcpp.xml b/pypy/module/cppyy/test/advancedcpp.xml --- a/pypy/module/cppyy/test/advancedcpp.xml +++ b/pypy/module/cppyy/test/advancedcpp.xml @@ -39,4 +39,10 @@ + + + + + + diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -539,3 +539,31 @@ import gc gc.collect() assert cppyy.gbl.new_overloader.s_instances == 0 + + def test15_template_instantiation_with_vector_of_float(self): + """Test template instantiation with a std::vector""" + + import cppyy + + # the following will simply fail if there is a naming problem (e.g. + # std::, allocator, etc., etc.); note the parsing required ... + b = cppyy.gbl.my_templated_class(cppyy.gbl.std.vector(float))() + + for i in range(5): + b.m_b.push_back(i) + assert round(b.m_b[i], 5) == float(i) + + def test16_template_member_functions(self): + """Test template member functions lookup and calls""" + + import cppyy + + m = cppyy.gbl.my_templated_method_class() + + assert m.get_size('char')() == m.get_char_size() + assert m.get_size(int)() == m.get_int_size() + assert m.get_size(long)() == m.get_long_size() + assert m.get_size(float)() == m.get_float_size() + assert m.get_size('double')() == m.get_double_size() + assert m.get_size('my_templated_method_class')() == m.get_self_size() + assert m.get_size('my_typedef_t')() == m.get_self_size() From noreply at buildbot.pypy.org Sat Mar 23 01:49:10 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:10 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: support for global templated functions Message-ID: <20130323004910.2A7BB1C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62673:f2c212b00402 Date: 2013-03-21 18:03 -0700 http://bitbucket.org/pypy/pypy/changeset/f2c212b00402/ Log: support for global templated functions diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -373,7 +373,7 @@ return "CPPFunction: %s" % self.signature() -class CPPTemplatedMember(object): +class CPPTemplatedCall(object): """Method dispatcher that first needs to resolve the template instance. Note that the derivation is from object: the CPPMethod is a data member.""" @@ -383,7 +383,10 @@ def __init__(self, space, templ_args, containing_scope, method_index, arg_defs, args_required): self.space = space self.templ_args = templ_args - self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) + if capi.c_is_staticmethod(containing_scope, index): + self.method = CPPFunction(space, containing_scope, method_index, arg_defs, args_require) + else: + self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) def call(self, cppthis, args_w): assert lltype.typeOf(cppthis) == capi.C_OBJECT @@ -402,7 +405,7 @@ return self.method.signature() def __repr__(self): - return "CPPTemplatedMember: %s" % self.signature() + return "CPPTemplatedCall: %s" % self.signature() class CPPConstructor(CPPMethod): @@ -825,13 +828,13 @@ cppfunction = CPPConstructor(self.space, self, index, arg_defs, args_required) if args_required == 0: self.default_constructor = cppfunction + elif capi.c_method_is_template(self, index): + templ_args = capi.c_template_args(self, index) + cppfunction = CPPTemplatedCall(self.space, templ_args, self, index, arg_defs, args_required) elif capi.c_is_staticmethod(self, index): cppfunction = CPPFunction(self.space, self, index, arg_defs, args_required) elif pyname == "__setitem__": cppfunction = CPPSetItem(self.space, self, index, arg_defs, args_required) - elif capi.c_method_is_template(self, index): - templ_args = capi.c_template_args(self, index) - cppfunction = CPPTemplatedMember(self.space, templ_args, self, index, arg_defs, args_required) else: cppfunction = CPPMethod(self.space, self, index, arg_defs, args_required) return cppfunction diff --git a/pypy/module/cppyy/test/advancedcpp.h b/pypy/module/cppyy/test/advancedcpp.h --- a/pypy/module/cppyy/test/advancedcpp.h +++ b/pypy/module/cppyy/test/advancedcpp.h @@ -384,7 +384,7 @@ T my_templated_function(T t) { return t; } template class my_templated_class >; -template int my_templated_function(int); +template char my_templated_function(char); template double my_templated_function(double); class my_templated_method_class { diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -567,3 +567,15 @@ assert m.get_size('double')() == m.get_double_size() assert m.get_size('my_templated_method_class')() == m.get_self_size() assert m.get_size('my_typedef_t')() == m.get_self_size() + + def test17_template_global_functions(self): + """Test template global function lookup and calls""" + + import cppyy + + f = cppyy.gbl.my_templated_function + + assert f('c') == 'c' + assert type(f('c')) == type('c') + assert f(3.) == 3. + assert type(f(4.)) == type(4.) From noreply at buildbot.pypy.org Sat Mar 23 01:49:11 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:11 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: fixes for rtyper Message-ID: <20130323004911.5548B1C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62674:231c0e5ca68a Date: 2013-03-21 18:12 -0700 http://bitbucket.org/pypy/pypy/changeset/231c0e5ca68a/ Log: fixes for rtyper diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -373,7 +373,7 @@ return "CPPFunction: %s" % self.signature() -class CPPTemplatedCall(object): +class CPPTemplatedCall(CPPMethod): # TODO: unnecessary derivation to make rtyper happy """Method dispatcher that first needs to resolve the template instance. Note that the derivation is from object: the CPPMethod is a data member.""" @@ -383,10 +383,8 @@ def __init__(self, space, templ_args, containing_scope, method_index, arg_defs, args_required): self.space = space self.templ_args = templ_args - if capi.c_is_staticmethod(containing_scope, index): - self.method = CPPFunction(space, containing_scope, method_index, arg_defs, args_require) - else: - self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) + # TODO: might have to specialize for CPPTemplatedCall on CPPMethod/CPPFunction here + self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) def call(self, cppthis, args_w): assert lltype.typeOf(cppthis) == capi.C_OBJECT From noreply at buildbot.pypy.org Sat Mar 23 01:49:12 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:12 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: templated methods support for CINT backend Message-ID: <20130323004912.9CABC1C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62675:0fc3d6fef5b2 Date: 2013-03-22 16:25 -0700 http://bitbucket.org/pypy/pypy/changeset/0fc3d6fef5b2/ Log: templated methods support for CINT backend diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx --- a/pypy/module/cppyy/src/cintcwrapper.cxx +++ b/pypy/module/cppyy/src/cintcwrapper.cxx @@ -675,7 +675,13 @@ char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t idx) { TFunction* f = type_get_method(handle, idx); - return cppstring_to_cstring(f->GetName()); + std::string name = f->GetName(); + TClassRef& cr = type_from_handle(handle); + if (cr.GetClass() && cppyy_is_constructor(handle, idx)) + return cppstring_to_cstring(name); + if (cppyy_method_is_template(handle, idx)) + return cppstring_to_cstring(name.substr(0, name.find('<'))); + return cppstring_to_cstring(name); } char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t idx) { @@ -726,6 +732,29 @@ } +int cppyy_method_is_template(cppyy_scope_t handle, cppyy_index_t idx) { + TClassRef& cr = type_from_handle(handle); + TFunction* f = type_get_method(handle, idx); + std::string name = f->GetName(); + return (name[name.size()-1] == '>') && (name.find('<') != std::string::npos); +} + +int cppyy_method_num_template_args(cppyy_scope_t /*handle*/, cppyy_index_t /*idx*/) { +// TODO: somehow count from the actual arguments + return 1; +} + +char* cppyy_method_template_arg_name( + cppyy_scope_t handle, cppyy_index_t idx, cppyy_index_t /*iarg*/) { +// TODO: return only the name for the requested arg + TClassRef& cr = type_from_handle(handle); + TFunction* f = type_get_method(handle, idx); + std::string name = f->GetName(); + std::string::size_type pos = name.find('<'); + return cppstring_to_cstring(resolve_typedef(name.substr(pos+1, name.size()-pos-2))); +} + + cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t idx) { TClassRef& cr = type_from_handle(handle); TFunction* f = type_get_method(handle, idx); diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx --- a/pypy/module/cppyy/src/reflexcwrapper.cxx +++ b/pypy/module/cppyy/src/reflexcwrapper.cxx @@ -386,7 +386,7 @@ name = s.Name(Reflex::FINAL); // to get proper name for templates else if (m.IsTemplateInstance()) { name = m.Name(); - std::string::size_type pos = name.find("<"); + std::string::size_type pos = name.find('<'); name = name.substr(0, pos); // strip template argument portion for overload } else name = m.Name(); @@ -448,6 +448,7 @@ return cppstring_to_cstring(sig.str()); } + int cppyy_method_is_template(cppyy_scope_t handle, cppyy_index_t method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); @@ -470,6 +471,7 @@ m.TemplateArgumentAt(iarg).Name(Reflex::SCOPED|Reflex::QUALIFIED)); } + cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); diff --git a/pypy/module/cppyy/test/advancedcpp_LinkDef.h b/pypy/module/cppyy/test/advancedcpp_LinkDef.h --- a/pypy/module/cppyy/test/advancedcpp_LinkDef.h +++ b/pypy/module/cppyy/test/advancedcpp_LinkDef.h @@ -66,4 +66,10 @@ #pragma link C++ class new_overloader; +#pragma link C++ class my_templated_class >; +#pragma link C++ function my_templated_function(char); +#pragma link C++ function my_templated_function(double); +#pragma link C++ class my_templated_method_class; +#pragma link C++ typedef my_typedef_t; + #endif From noreply at buildbot.pypy.org Sat Mar 23 01:49:13 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:13 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: coding style fixes Message-ID: <20130323004913.D9B9D1C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62676:e83ef78604e7 Date: 2013-03-22 17:43 -0700 http://bitbucket.org/pypy/pypy/changeset/e83ef78604e7/ Log: coding style fixes diff --git a/pypy/module/cppyy/test/advancedcpp.h b/pypy/module/cppyy/test/advancedcpp.h --- a/pypy/module/cppyy/test/advancedcpp.h +++ b/pypy/module/cppyy/test/advancedcpp.h @@ -26,81 +26,81 @@ //=========================================================================== class base_class { // for simple inheritance testing public: - base_class() { m_b = 1; m_db = 1.1; } - virtual ~base_class() {} - virtual int get_value() { return m_b; } - double get_base_value() { return m_db; } + base_class() { m_b = 1; m_db = 1.1; } + virtual ~base_class() {} + virtual int get_value() { return m_b; } + double get_base_value() { return m_db; } - virtual base_class* cycle(base_class* b) { return b; } - virtual base_class* clone() { return new base_class; } + virtual base_class* cycle(base_class* b) { return b; } + virtual base_class* clone() { return new base_class; } public: - int m_b; - double m_db; + int m_b; + double m_db; }; class derived_class : public base_class { public: - derived_class() { m_d = 2; m_dd = 2.2;} - virtual int get_value() { return m_d; } - double get_derived_value() { return m_dd; } - virtual base_class* clone() { return new derived_class; } + derived_class() { m_d = 2; m_dd = 2.2;} + virtual int get_value() { return m_d; } + double get_derived_value() { return m_dd; } + virtual base_class* clone() { return new derived_class; } public: - int m_d; - double m_dd; + int m_d; + double m_dd; }; //=========================================================================== class a_class { // for esoteric inheritance testing public: - a_class() { m_a = 1; m_da = 1.1; } - ~a_class() {} - virtual int get_value() = 0; + a_class() { m_a = 1; m_da = 1.1; } + ~a_class() {} + virtual int get_value() = 0; public: - int m_a; - double m_da; + int m_a; + double m_da; }; class b_class : public virtual a_class { public: - b_class() { m_b = 2; m_db = 2.2;} - virtual int get_value() { return m_b; } + b_class() { m_b = 2; m_db = 2.2;} + virtual int get_value() { return m_b; } public: - int m_b; - double m_db; + int m_b; + double m_db; }; class c_class_1 : public virtual a_class, public virtual b_class { public: - c_class_1() { m_c = 3; } - virtual int get_value() { return m_c; } + c_class_1() { m_c = 3; } + virtual int get_value() { return m_c; } public: - int m_c; + int m_c; }; class c_class_2 : public virtual b_class, public virtual a_class { public: - c_class_2() { m_c = 3; } - virtual int get_value() { return m_c; } + c_class_2() { m_c = 3; } + virtual int get_value() { return m_c; } public: - int m_c; + int m_c; }; typedef c_class_2 c_class; class d_class : public virtual c_class, public virtual a_class { public: - d_class() { m_d = 4; } - virtual int get_value() { return m_d; } + d_class() { m_d = 4; } + virtual int get_value() { return m_d; } public: - int m_d; + int m_d; }; a_class* create_c1(); @@ -114,38 +114,38 @@ //=========================================================================== namespace a_ns { // for namespace testing - extern int g_a; - int get_g_a(); + extern int g_a; + int get_g_a(); - struct b_class { - b_class() { m_b = -2; } - int m_b; - static int s_b; + struct b_class { + b_class() { m_b = -2; } + int m_b; + static int s_b; - struct c_class { - c_class() { m_c = -3; } - int m_c; - static int s_c; - }; - }; + struct c_class { + c_class() { m_c = -3; } + int m_c; + static int s_c; + }; + }; - namespace d_ns { - extern int g_d; - int get_g_d(); + namespace d_ns { + extern int g_d; + int get_g_d(); - struct e_class { - e_class() { m_e = -5; } - int m_e; - static int s_e; + struct e_class { + e_class() { m_e = -5; } + int m_e; + static int s_e; - struct f_class { - f_class() { m_f = -6; } - int m_f; - static int s_f; - }; - }; + struct f_class { + f_class() { m_f = -6; } + int m_f; + static int s_f; + }; + }; - } // namespace d_ns + } // namespace d_ns } // namespace a_ns @@ -154,46 +154,46 @@ template // for template testing class T1 { public: - T1(T t = T(1)) : m_t1(t) {} - T get_value() { return m_t1; } + T1(T t = T(1)) : m_t1(t) {} + T get_value() { return m_t1; } public: - T m_t1; + T m_t1; }; template class T2 { public: - T2(T t = T(2)) : m_t2(t) {} - T get_value() { return m_t2; } + T2(T t = T(2)) : m_t2(t) {} + T get_value() { return m_t2; } public: - T m_t2; + T m_t2; }; template class T3 { public: - T3(T t = T(3), U u = U(33)) : m_t3(t), m_u3(u) {} - T get_value_t() { return m_t3; } - U get_value_u() { return m_u3; } + T3(T t = T(3), U u = U(33)) : m_t3(t), m_u3(u) {} + T get_value_t() { return m_t3; } + U get_value_u() { return m_u3; } public: - T m_t3; - U m_u3; + T m_t3; + U m_u3; }; namespace a_ns { - template - class T4 { - public: - T4(T t = T(4)) : m_t4(t) {} - T get_value() { return m_t4; } + template + class T4 { + public: + T4(T t = T(4)) : m_t4(t) {} + T get_value() { return m_t4; } - public: - T m_t4; - }; + public: + T m_t4; + }; } // namespace a_ns @@ -218,49 +218,46 @@ //=========================================================================== class some_abstract_class { // to test abstract class handling public: - virtual void a_virtual_method() = 0; + virtual void a_virtual_method() = 0; }; class some_concrete_class : public some_abstract_class { public: - virtual void a_virtual_method() {} + virtual void a_virtual_method() {} }; //=========================================================================== -/* -TODO: methptrgetter support for std::vector<> class ref_tester { // for assignment by-ref testing public: - ref_tester() : m_i(-99) {} - ref_tester(int i) : m_i(i) {} - ref_tester(const ref_tester& s) : m_i(s.m_i) {} - ref_tester& operator=(const ref_tester& s) { - if (&s != this) m_i = s.m_i; - return *this; - } - ~ref_tester() {} + ref_tester() : m_i(-99) {} + ref_tester(int i) : m_i(i) {} + ref_tester(const ref_tester& s) : m_i(s.m_i) {} + ref_tester& operator=(const ref_tester& s) { + if (&s != this) m_i = s.m_i; + return *this; + } + ~ref_tester() {} public: - int m_i; + int m_i; }; -template class std::vector< ref_tester >; -*/ +template class std::vector; //=========================================================================== class some_convertible { // for math conversions testing public: - some_convertible() : m_i(-99), m_d(-99.) {} + some_convertible() : m_i(-99), m_d(-99.) {} - operator int() { return m_i; } - operator long() { return m_i; } - operator double() { return m_d; } + operator int() { return m_i; } + operator long() { return m_i; } + operator double() { return m_d; } public: - int m_i; - double m_d; + int m_i; + double m_d; }; @@ -279,25 +276,25 @@ //=========================================================================== class some_class_with_data { // for life-line and identity testing public: - class some_data { - public: - some_data() { ++s_num_data; } - some_data(const some_data&) { ++s_num_data; } - ~some_data() { --s_num_data; } + class some_data { + public: + some_data() { ++s_num_data; } + some_data(const some_data&) { ++s_num_data; } + ~some_data() { --s_num_data; } - static int s_num_data; - }; + static int s_num_data; + }; - some_class_with_data gime_copy() { - return *this; - } + some_class_with_data gime_copy() { + return *this; + } - const some_data& gime_data() { /* TODO: methptrgetter const support */ - return m_data; - } + const some_data& gime_data() { /* TODO: methptrgetter const support */ + return m_data; + } - int m_padding; - some_data m_data; + int m_padding; + some_data m_data; }; @@ -389,19 +386,19 @@ class my_templated_method_class { public: - long get_size(); // to get around bug in genreflex - template long get_size(); + long get_size(); // to get around bug in genreflex + template long get_size(); - long get_char_size(); - long get_int_size(); - long get_long_size(); - long get_float_size(); - long get_double_size(); + long get_char_size(); + long get_int_size(); + long get_long_size(); + long get_float_size(); + long get_double_size(); - long get_self_size(); + long get_self_size(); private: - double m_data[3]; + double m_data[3]; }; template From noreply at buildbot.pypy.org Sat Mar 23 01:49:15 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:15 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: reftester test Message-ID: <20130323004915.0EC581C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62677:3d5c68f6a4d4 Date: 2013-03-22 17:46 -0700 http://bitbucket.org/pypy/pypy/changeset/3d5c68f6a4d4/ Log: reftester test diff --git a/pypy/module/cppyy/test/advancedcpp.xml b/pypy/module/cppyy/test/advancedcpp.xml --- a/pypy/module/cppyy/test/advancedcpp.xml +++ b/pypy/module/cppyy/test/advancedcpp.xml @@ -33,6 +33,9 @@ + + + diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -579,3 +579,18 @@ assert type(f('c')) == type('c') assert f(3.) == 3. assert type(f(4.)) == type(4.) + + def test18_assign_to_return_byref( self ): + """Test assignment to an instance returned by reference""" + + from cppyy import gbl + + a = gbl.std.vector(gbl.ref_tester)() + a.push_back(gbl.ref_tester(42)) + + assert len(a) == 1 + assert a[0].m_i == 42 + + # a[0] = gbl.ref_tester(33) + # assert len(a) == 1 + # assert a[0].m_i == 33 From noreply at buildbot.pypy.org Sat Mar 23 01:49:16 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 23 Mar 2013 01:49:16 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: branch merge Message-ID: <20130323004916.4631F1C1534@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62678:7351885a2bc3 Date: 2013-03-22 17:48 -0700 http://bitbucket.org/pypy/pypy/changeset/7351885a2bc3/ Log: branch merge From noreply at buildbot.pypy.org Sat Mar 23 01:51:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 01:51:24 +0100 (CET) Subject: [pypy-commit] pypy default: fix gethostbyaddr tests for when ipv6 is not available Message-ID: <20130323005124.15C351C1535@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62679:7d54c7b1e3de Date: 2013-03-23 01:52 +0100 http://bitbucket.org/pypy/pypy/changeset/7d54c7b1e3de/ Log: fix gethostbyaddr tests for when ipv6 is not available diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -32,7 +32,19 @@ assert space.unwrap(ip) == socket.gethostbyname_ex(host) def test_gethostbyaddr(): + try: + socket.gethostbyaddr("::1") + except socket.herror: + ipv6 = False + else: + ipv6 = True for host in ["localhost", "127.0.0.1", "::1"]: + if host == "::1" and not ipv6: + from pypy.interpreter.error import OperationError + with py.test.raises(OperationError): + space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + continue ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) == socket.gethostbyaddr(host) diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -68,7 +68,17 @@ % (address_list,)) def test_gethostbyaddr(): + try: + cpy_socket.gethostbyaddr("::1") + except cpy_socket.herror: + ipv6 = False + else: + ipv6 = True for host in ["localhost", "127.0.0.1", "::1"]: + if host == "::1" and not ipv6: + with py.test.raises(HSocketError): + gethostbyaddr(host) + continue name, aliases, address_list = gethostbyaddr(host) allnames = [name] + aliases for n in allnames: From noreply at buildbot.pypy.org Sat Mar 23 01:51:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 01:51:25 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130323005125.E97E61C1535@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62680:effca682df3b Date: 2013-03-23 01:52 +0100 http://bitbucket.org/pypy/pypy/changeset/effca682df3b/ Log: merge heads diff too long, truncating to 2000 out of 7053 lines diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. 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 @@ -108,3 +108,5 @@ Documentation fixes after going through the docs at PyCon 2013 sprint. .. branch: extregistry-refactor + +.. branch: remove-list-smm diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -538,7 +538,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -555,7 +555,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -621,7 +621,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -17,7 +17,7 @@ from pypy.interpreter.miscutils import ThreadLocals -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) @@ -219,16 +219,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True - def __spacebind__(self, space): return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -339,9 +333,8 @@ if e.match(self, self.w_KeyError): continue raise - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -350,9 +343,8 @@ self.call_function(w_exitfunc) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -424,9 +416,8 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): @@ -723,38 +714,26 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' def unpackiterable(self, w_iterable, expected_length=-1): @@ -1032,8 +1011,7 @@ def is_oldstyle_instance(self, w_obj): # xxx hack hack hack from pypy.module.__builtin__.interp_classobj import W_InstanceObject - obj = self.interpclass_w(w_obj) - return obj is not None and isinstance(obj, W_InstanceObject) + return isinstance(w_obj, W_InstanceObject) def callable(self, w_obj): if self.lookup(w_obj, "__call__") is not None: @@ -1670,7 +1648,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1687,7 +1664,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp @@ -145,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -209,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -3,10 +3,10 @@ Code and Frame. """ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root -class Code(Wrappable): +class Code(W_Root): """A code is a compiled version of some source code. Abstract base class.""" _immutable_ = True @@ -52,19 +52,20 @@ def funcrun_obj(self, func, w_obj, args): return self.funcrun(func, args.prepend(w_obj)) -class Frame(Wrappable): + +class Frame(W_Root): """A frame is an environment supporting the execution of a code object. Abstract base class.""" def __init__(self, space, w_globals=None): - self.space = space - self.w_globals = w_globals # wrapped dict of globals - self.w_locals = None # wrapped dict of locals + self.space = space + self.w_globals = w_globals # wrapped dict of globals + self.w_locals = None # wrapped dict of locals def run(self): "Abstract method to override. Runs the frame" - raise TypeError, "abstract" - + raise TypeError("abstract") + def getdictscope(self): "Get the locals as a dictionary." self.fast2locals() @@ -86,16 +87,16 @@ def getfastscope(self): "Abstract. Get the fast locals as a list." - raise TypeError, "abstract" + raise TypeError("abstract") def setfastscope(self, scope_w): """Abstract. Initialize the fast locals from a list of values, where the order is according to self.getcode().signature().""" - raise TypeError, "abstract" + raise TypeError("abstract") def getfastscopelength(self): "Abstract. Get the expected number of locals." - raise TypeError, "abstract" + raise TypeError("abstract") def fast2locals(self): # Copy values from the fastlocals to self.w_locals diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -8,20 +8,22 @@ from rpython.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from rpython.rlib import jit + funccallunrolling = unrolling_iterable(range(4)) + @jit.elidable_promote() def _get_immutable_code(func): assert not func.can_change_code return func.code -class Function(Wrappable): +class Function(W_Root): """A function is a code object captured with some environment: an object space, a dictionary of globals, default arguments, and an arbitrary 'closure' passed to the code object.""" @@ -40,7 +42,7 @@ self.w_doc = None # lazily read from code.getdocstring() self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary - self.closure = closure # normally, list of Cell instances or None + self.closure = closure # normally, list of Cell instances or None self.defs_w = defs_w self.w_func_dict = None # filled out below if needed self.w_module = None @@ -55,11 +57,15 @@ def call_args(self, args): # delegate activation to code - return self.getcode().funcrun(self, args) + w_res = self.getcode().funcrun(self, args) + assert isinstance(w_res, W_Root) + return w_res def call_obj_args(self, w_obj, args): # delegate activation to code - return self.getcode().funcrun_obj(self, w_obj, args) + w_res = self.getcode().funcrun_obj(self, w_obj, args) + assert isinstance(w_res, W_Root) + return w_res def getcode(self): if jit.we_are_jitted(): @@ -239,7 +245,6 @@ def descr_function_repr(self): return self.getrepr(self.space, 'function %s' % (self.name,)) - # delicate _all = {'': None} @@ -266,8 +271,8 @@ def descr_function__reduce__(self, space): from pypy.interpreter.gateway import BuiltinCode from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) code = self.code if isinstance(code, BuiltinCode): new_inst = mod.get('builtin_function') @@ -275,7 +280,7 @@ space.newtuple([space.wrap(code.identifier)])]) new_inst = mod.get('func_new') - w = space.wrap + w = space.wrap if self.closure is None: w_closure = space.w_None else: @@ -352,7 +357,7 @@ self.defs_w = [] return if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): - raise OperationError( space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None") ) + raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) def fdel_func_defaults(self, space): @@ -379,7 +384,6 @@ "to a string object")) raise - def fdel_func_doc(self, space): self.w_doc = space.w_None @@ -418,7 +422,7 @@ def fget_func_closure(self, space): if self.closure is not None: - w_res = space.newtuple( [ space.wrap(i) for i in self.closure ] ) + w_res = space.newtuple([space.wrap(i) for i in self.closure]) else: w_res = space.w_None return w_res @@ -437,7 +441,7 @@ return space.wrap(Method(space, w_function, None, w_cls)) -class Method(Wrappable): +class Method(W_Root): """A method is a function bound to a specific instance or class.""" _immutable_fields_ = ['w_function', 'w_instance', 'w_class'] @@ -548,18 +552,17 @@ def descr_method_eq(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, Method): + if not isinstance(w_other, Method): return space.w_NotImplemented if self.w_instance is None: - if other.w_instance is not None: + if w_other.w_instance is not None: return space.w_False else: - if other.w_instance is None: + if w_other.w_instance is None: return space.w_False - if not space.eq_w(self.w_instance, other.w_instance): + if not space.eq_w(self.w_instance, w_other.w_instance): return space.w_False - return space.eq(self.w_function, other.w_function) + return space.eq(self.w_function, w_other.w_function) def descr_method_hash(self): space = self.space @@ -575,20 +578,22 @@ mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('method_new') w_instance = self.w_instance or space.w_None - function = space.interpclass_w(self.w_function) - if isinstance(function, Function) and isinstance(function.code, BuiltinCode): + w_function = self.w_function + if (isinstance(w_function, Function) and + isinstance(w_function.code, BuiltinCode)): new_inst = mod.get('builtin_method_new') if space.is_w(w_instance, space.w_None): - tup = [self.w_class, space.wrap(function.name)] + tup = [self.w_class, space.wrap(w_function.name)] else: - tup = [w_instance, space.wrap(function.name)] - elif space.is_w( self.w_class, space.w_None ): + tup = [w_instance, space.wrap(w_function.name)] + elif space.is_w(self.w_class, space.w_None): tup = [self.w_function, w_instance] else: tup = [self.w_function, w_instance, self.w_class] return space.newtuple([new_inst, space.newtuple(tup)]) -class StaticMethod(Wrappable): + +class StaticMethod(W_Root): """The staticmethod objects.""" _immutable_fields_ = ['w_function'] @@ -604,7 +609,8 @@ instance.__init__(w_function) return space.wrap(instance) -class ClassMethod(Wrappable): + +class ClassMethod(W_Root): """The classmethod objects.""" _immutable_fields_ = ['w_function'] diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -4,20 +4,23 @@ * BuiltinCode (call interp-level code from app-level) * app2interp (embed an app-level function into an interp-level callable) * interp2app (publish an interp-level object to be visible from app-level) +* interpindirect2app (publish an interp-level object to be visible from + app-level as an indirect call to implementation) """ import sys import os import types +import inspect import py from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from pypy.interpreter.signature import Signature -from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, - SpaceCache, DescrMismatch) +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, SpaceCache, + DescrMismatch) from pypy.interpreter.error import OperationError from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from rpython.rlib import rstackovf @@ -53,7 +56,7 @@ class UnwrapSpecRecipe(object): "NOT_RPYTHON" - bases_order = [Wrappable, W_Root, ObjSpace, Arguments, object] + bases_order = [W_Root, ObjSpace, Arguments, object] def dispatch(self, el, *args): if isinstance(el, str): @@ -111,13 +114,13 @@ self.orig_arg = iter(original_sig.argnames).next def visit_self(self, cls, app_sig): - self.visit__Wrappable(cls, app_sig) + self.visit__W_Root(cls, app_sig) def checked_space_method(self, typname, app_sig): argname = self.orig_arg() assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typname, argname, self.func)) + "unwrapped %s argument %s of built-in function %r in %r should " + "not start with 'w_'" % (typname, argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname) def visit_index(self, index, app_sig): @@ -147,23 +150,18 @@ def visit_truncatedint_w(self, el, app_sig): self.checked_space_method(el, app_sig) - def visit__Wrappable(self, el, app_sig): - name = el.__name__ - argname = self.orig_arg() - assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (name, argname, self.func)) - app_sig.append(argname) - def visit__ObjSpace(self, el, app_sig): self.orig_arg() def visit__W_Root(self, el, app_sig): - assert el is W_Root, "%s is not W_Root (forgotten to put .im_func in interp2app argument?)" % (el,) argname = self.orig_arg() + if argname == 'self': + assert el is not W_Root + app_sig.append(argname) + return assert argname.startswith('w_'), ( - "argument %s of built-in function %r should " - "start with 'w_'" % (argname, self.func)) + "argument %s of built-in function %r in %r should " + "start with 'w_'" % (argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): @@ -211,15 +209,15 @@ self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) - def visit__Wrappable(self, typ): - self.run_args.append("space.interp_w(%s, %s)" % (self.use(typ), - self.scopenext())) - def visit__ObjSpace(self, el): self.run_args.append('space') def visit__W_Root(self, el): - self.run_args.append(self.scopenext()) + if el is not W_Root: + self.run_args.append("space.interp_w(%s, %s)" % (self.use(el), + self.scopenext())) + else: + self.run_args.append(self.scopenext()) def visit__Arguments(self, el): self.miniglobals['Arguments'] = Arguments @@ -348,17 +346,17 @@ self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) - def visit__Wrappable(self, typ): - self.unwrap.append("space.interp_w(%s, %s)" % (self.use(typ), - self.nextarg())) - def visit__ObjSpace(self, el): if self.finger != 0: raise FastFuncNotSupported self.unwrap.append("space") def visit__W_Root(self, el): - self.unwrap.append(self.nextarg()) + if el is not W_Root: + self.unwrap.append("space.interp_w(%s, %s)" % (self.use(el), + self.nextarg())) + else: + self.unwrap.append(self.nextarg()) def visit__Arguments(self, el): raise FastFuncNotSupported @@ -471,6 +469,7 @@ def __init__(self, default_value): self.default_value = default_value + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -536,7 +535,6 @@ # It is a list of types or singleton objects: # baseobjspace.ObjSpace is used to specify the space argument # baseobjspace.W_Root is for wrapped arguments to keep wrapped - # baseobjspace.Wrappable subclasses imply interp_w and a typecheck # argument.Arguments is for a final rest arguments Arguments object # 'args_w' for fixedview applied to rest arguments # 'w_args' for rest arguments passed as wrapped tuple @@ -555,7 +553,7 @@ assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: - assert issubclass(self_type, Wrappable) + assert issubclass(self_type, W_Root) unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type @@ -799,8 +797,31 @@ w_result = space.w_None return w_result +def interpindirect2app(unbound_meth, unwrap_spec=None): + base_cls = unbound_meth.im_class + func = unbound_meth.im_func + args = inspect.getargs(func.func_code) + if args.varargs or args.keywords: + raise TypeError("Varargs and keywords not supported in unwrap_spec") + assert not func.func_defaults + argspec = ', '.join([arg for arg in args.args[1:]]) + func_code = py.code.Source(""" + def f(w_obj, %(args)s): + return w_obj.%(func_name)s(%(args)s) + """ % {'args': argspec, 'func_name': func.func_name}) + d = {} + exec func_code.compile() in d + f = d['f'] + f.func_name = func.func_name + if unwrap_spec is None: + unwrap_spec = {} + else: + assert isinstance(unwrap_spec, dict) + unwrap_spec = unwrap_spec.copy() + unwrap_spec['w_obj'] = base_cls + return interp2app(globals()['unwrap_spec'](**unwrap_spec)(f)) -class interp2app(Wrappable): +class interp2app(W_Root): """Build a gateway that calls 'f' at interp-level.""" # Takes optionally an unwrap_spec, see BuiltinCode @@ -833,7 +854,7 @@ result = cls.instancecache[key] assert result.__class__ is cls return result - self = Wrappable.__new__(cls) + self = W_Root.__new__(cls) cls.instancecache[key] = self self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, self_type=self_type, diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -1,10 +1,10 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.pyopcode import LoopBlock from rpython.rlib import jit -class GeneratorIterator(Wrappable): +class GeneratorIterator(W_Root): "An iterator created by a generator." _immutable_fields_ = ['pycode'] @@ -94,7 +94,6 @@ w_val = self.space.w_None return self.throw(w_type, w_val, w_tb) - def throw(self, w_type, w_val, w_tb): from pypy.interpreter.pytraceback import check_traceback space = self.space @@ -164,6 +163,7 @@ jitdriver = jit.JitDriver(greens=['pycode'], reds=['self', 'frame', 'results'], name='unpack_into') + def unpack_into(self, results): """This is a hack for performance: runs the generator and collects all produced items in a list.""" diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -89,13 +89,13 @@ return None else: w_value = loader(space) - func = space.interpclass_w(w_value) # the idea of the following code is that all functions that are # directly in a mixed-module are "builtin", e.g. they get a # special type without a __get__ # note that this is not just all functions that contain a # builtin code object, as e.g. methods of builtin types have to # be normal Functions to get the correct binding behaviour + func = w_value if (isinstance(func, Function) and type(func) is not BuiltinFunction): try: diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -2,11 +2,12 @@ Module objects. """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import we_are_translated -class Module(Wrappable): + +class Module(W_Root): """A module.""" _immutable_fields_ = ["w_dict?"] diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -3,12 +3,12 @@ from pypy.interpreter import function, pycode, pyframe from pypy.interpreter.astcompiler import consts -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.mixedmodule import MixedModule -class Cell(Wrappable): +class Cell(W_Root): "A simple container for a wrapped value." def __init__(self, w_value=None): @@ -34,18 +34,17 @@ self.w_value = None def descr__cmp__(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Cell): + if not isinstance(w_other, Cell): return space.w_NotImplemented if self.w_value is None: - if other.w_value is None: + if w_other.w_value is None: return space.newint(0) return space.newint(-1) - elif other.w_value is None: + elif w_other.w_value is None: return space.newint(1) - return space.cmp(self.w_value, other.w_value) + return space.cmp(self.w_value, w_other.w_value) def descr__reduce__(self, space): w_mod = space.getbuiltinmodule('_pickle_support') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -289,29 +289,28 @@ def descr_code__eq__(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, PyCode): + if not isinstance(w_other, PyCode): return space.w_False - areEqual = (self.co_name == other.co_name and - self.co_argcount == other.co_argcount and - self.co_nlocals == other.co_nlocals and - self.co_flags == other.co_flags and - self.co_firstlineno == other.co_firstlineno and - self.co_code == other.co_code and - len(self.co_consts_w) == len(other.co_consts_w) and - len(self.co_names_w) == len(other.co_names_w) and - self.co_varnames == other.co_varnames and - self.co_freevars == other.co_freevars and - self.co_cellvars == other.co_cellvars) + areEqual = (self.co_name == w_other.co_name and + self.co_argcount == w_other.co_argcount and + self.co_nlocals == w_other.co_nlocals and + self.co_flags == w_other.co_flags and + self.co_firstlineno == w_other.co_firstlineno and + self.co_code == w_other.co_code and + len(self.co_consts_w) == len(w_other.co_consts_w) and + len(self.co_names_w) == len(w_other.co_names_w) and + self.co_varnames == w_other.co_varnames and + self.co_freevars == w_other.co_freevars and + self.co_cellvars == w_other.co_cellvars) if not areEqual: return space.w_False for i in range(len(self.co_names_w)): - if not space.eq_w(self.co_names_w[i], other.co_names_w[i]): + if not space.eq_w(self.co_names_w[i], w_other.co_names_w[i]): return space.w_False for i in range(len(self.co_consts_w)): - if not space.eq_w(self.co_consts_w[i], other.co_consts_w[i]): + if not space.eq_w(self.co_consts_w[i], w_other.co_consts_w[i]): return space.w_False return space.w_True diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -6,7 +6,7 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import gateway, function, eval, pyframe, pytraceback from pypy.interpreter.pycode import PyCode, BytecodeCorruption from rpython.tool.sourcetools import func_with_new_name @@ -607,16 +607,15 @@ if self.space.is_w(w_top, self.space.w_None): # case of a finally: block with no exception return None - unroller = self.space.interpclass_w(w_top) - if isinstance(unroller, SuspendedUnroller): + if isinstance(w_top, SuspendedUnroller): # case of a finally: block with a suspended unroller - return unroller + return w_top else: # case of an except: block. We popped the exception type self.popvalue() # Now we pop the exception value - unroller = self.space.interpclass_w(self.popvalue()) - assert unroller is not None - return unroller + w_unroller = self.popvalue() + assert w_unroller is not None + return w_unroller def BUILD_CLASS(self, oparg, next_instr): w_methodsdict = self.popvalue() @@ -944,11 +943,9 @@ w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) - unroller = self.space.interpclass_w(w_unroller) - is_app_exc = (unroller is not None and - isinstance(unroller, SApplicationException)) - if is_app_exc: - operr = unroller.operr + if isinstance(w_unroller, SApplicationException): + # app-level exception + operr = w_unroller.operr self.last_exception = operr w_traceback = self.space.wrap(operr.get_traceback()) w_suppress = self.call_contextmanager_exit_function( @@ -1144,11 +1141,15 @@ class ExitFrame(Exception): pass + class Return(ExitFrame): """Raised when exiting a frame via a 'return' statement.""" + + class Yield(ExitFrame): """Raised when exiting a frame via a 'yield' statement.""" + class RaiseWithExplicitTraceback(Exception): """Raised at interp-level by a 0- or 3-arguments 'raise' statement.""" def __init__(self, operr): @@ -1157,7 +1158,7 @@ ### Frame Blocks ### -class SuspendedUnroller(Wrappable): +class SuspendedUnroller(W_Root): """Abstract base class for interpreter-level objects that instruct the interpreter to change the control flow and the block stack. diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -4,7 +4,7 @@ from rpython.tool.error import offset2lineno -class PyTraceback(baseobjspace.Wrappable): +class PyTraceback(baseobjspace.W_Root): """Traceback object Public app-level fields: @@ -38,7 +38,7 @@ w(self.frame), w(self.lasti), w(self.next), - ] + ] nt = space.newtuple return nt([new_inst, nt(tup_base), nt(tup_state)]) @@ -61,8 +61,7 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if w_tb is None or not space.is_true(space.isinstance(w_tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) - return tb + return w_tb diff --git a/pypy/interpreter/special.py b/pypy/interpreter/special.py --- a/pypy/interpreter/special.py +++ b/pypy/interpreter/special.py @@ -1,15 +1,17 @@ +from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.baseobjspace import Wrappable -class Ellipsis(Wrappable): +class Ellipsis(W_Root): def __init__(self, space): - self.space = space + self.space = space + def descr__repr__(self): return self.space.wrap('Ellipsis') -class NotImplemented(Wrappable): + +class NotImplemented(W_Root): def __init__(self, space): - self.space = space + self.space = space + def descr__repr__(self): return self.space.wrap('NotImplemented') - 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 @@ -25,7 +25,7 @@ def d(self, w_boo): pass code = gateway.BuiltinCode(d, unwrap_spec= ['self', - gateway.W_Root], self_type=gateway.Wrappable) + gateway.W_Root], self_type=gateway.W_Root) assert code.signature() == Signature(['self', 'boo'], None, None) def e(space, w_x, w_y, __args__): pass @@ -129,6 +129,36 @@ space.call_function(w_app_g3, w('foo'), w('bar')), w('foobar')) + def test_interpindirect2app(self): + space = self.space + class BaseA(W_Root): + def method(self, space, x): + pass + + class A(BaseA): + def method(self, space, x): + return space.wrap(x + 2) + + class B(BaseA): + def method(self, space, x): + return space.wrap(x + 1) + + class FakeTypeDef(object): + rawdict = {} + bases = {} + applevel_subclasses_base = None + name = 'foo' + hasdict = False + weakrefable = False + doc = 'xyz' + + meth = gateway.interpindirect2app(BaseA.method, {'x': int}) + w_c = space.wrap(meth) + w_a = A() + w_b = B() + assert space.int_w(space.call_function(w_c, w_a, space.wrap(1))) == 1 + 2 + assert space.int_w(space.call_function(w_c, w_b, space.wrap(-10))) == -10 + 1 + def test_interp2app_unwrap_spec(self): space = self.space w = space.wrap @@ -167,7 +197,7 @@ space.wrap(True)) def test_caching_methods(self): - class Base(gateway.Wrappable): + class Base(gateway.W_Root): def f(self): return 1 diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py --- a/pypy/interpreter/test/test_typedef.py +++ b/pypy/interpreter/test/test_typedef.py @@ -1,7 +1,7 @@ import gc from pypy.interpreter import typedef from rpython.tool.udir import udir -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, interp2app # this test isn't so much to test that the objspace interface *works* @@ -139,7 +139,7 @@ cls, len(set), list(set)) def test_getsetproperty(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): pass def fget(self, space, w_self): assert self is prop @@ -151,7 +151,7 @@ assert self.space.getattr(w_obj, self.space.wrap('x')) is self.space.w_None def test_getsetproperty_arguments(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): def fget1(space, w_self): assert isinstance(space, ObjSpace) assert isinstance(w_self, W_SomeType) @@ -169,7 +169,7 @@ assert space.getattr(w_obj, space.wrap('x2')) == space.w_None def test_unhashable(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): pass W_SomeType.typedef = typedef.TypeDef( 'some_type', @@ -183,12 +183,12 @@ def test_destructor(self): space = self.space - class W_Level1(Wrappable): + class W_Level1(W_Root): def __init__(self, space1): assert space1 is space def __del__(self): space.call_method(w_seen, 'append', space.wrap(1)) - class W_Level2(Wrappable): + class W_Level2(W_Root): def __init__(self, space1): assert space1 is space def __del__(self): @@ -261,7 +261,7 @@ assert space.unwrap(w_seen) == [6, 2] def test_multiple_inheritance(self): - class W_A(Wrappable): + class W_A(W_Root): a = 1 b = 2 class W_C(W_A): @@ -270,7 +270,7 @@ a = typedef.interp_attrproperty("a", cls=W_A), b = typedef.interp_attrproperty("b", cls=W_A), ) - class W_B(Wrappable): + class W_B(W_Root): pass def standalone_method(space, w_obj): if isinstance(w_obj, W_A): @@ -305,7 +305,7 @@ assert_method(w_o2, "c", False) def test_total_ordering(self): - class W_SomeType(Wrappable): + class W_SomeType(W_Root): def __init__(self, space, x): self.space = space self.x = x diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,7 +1,7 @@ import py from pypy.interpreter.argument import Arguments -from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch +from pypy.interpreter.baseobjspace import W_Root, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, WrappedDefault) @@ -381,7 +381,7 @@ """ else: cls_name = cls.__name__ - assert issubclass(cls, Wrappable) + assert issubclass(cls, W_Root) source = """ def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s): obj = space.descr_self_interp_w(%(cls_name)s, w_obj) @@ -439,7 +439,7 @@ res = miniglobals['objclass_getter'], cls return res -class GetSetProperty(Wrappable): +class GetSetProperty(W_Root): _immutable_fields_ = ["fget", "fset", "fdel"] @specialize.arg(7) @@ -542,7 +542,7 @@ GetSetProperty.typedef.acceptable_as_base_class = False -class Member(Wrappable): +class Member(W_Root): """For slots.""" _immutable_ = True @@ -677,7 +677,7 @@ weakref_descr.name = '__weakref__' def make_weakref_descr(cls): - """Make instances of the Wrappable subclass 'cls' weakrefable. + """Make instances of the W_Root subclass 'cls' weakrefable. This returns the '__weakref__' desctriptor to use for the TypeDef. Note that if the class also defines a custom '__del__', the __del__ should call self.clear_all_weakrefs() before it clears @@ -686,10 +686,13 @@ # force the interface into the given cls def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None + cls._lifeline_ = None cls.getweakref = getweakref cls.setweakref = setweakref diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -116,9 +116,8 @@ return space.builtin if space.is_true(space.isinstance(w_builtin, space.w_dict)): return module.Module(space, None, w_builtin) - builtin = space.interpclass_w(w_builtin) - if isinstance(builtin, module.Module): - return builtin + if isinstance(w_builtin, module.Module): + return w_builtin # no builtin! make a default one. Give them None, at least. builtin = module.Module(space, None) space.setitem(builtin.w_dict, space.wrap('None'), space.w_None) diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -88,11 +88,9 @@ return space.is_true(w_result) # -- case (old-style instance, old-style class) - oldstyleclass = space.interpclass_w(w_klass_or_tuple) - if isinstance(oldstyleclass, W_ClassObject): - oldstyleinst = space.interpclass_w(w_obj) - if isinstance(oldstyleinst, W_InstanceObject): - return oldstyleinst.w_class.is_subclass_of(oldstyleclass) + if isinstance(w_klass_or_tuple, W_ClassObject): + if isinstance(w_obj, W_InstanceObject): + return w_obj.w_class.is_subclass_of(w_klass_or_tuple) return _abstract_isinstance_w_helper(space, w_obj, w_klass_or_tuple) @jit.dont_look_inside @@ -152,11 +150,9 @@ return space.is_true(w_result) # -- case (old-style class, old-style class) - oldstylederived = space.interpclass_w(w_derived) - if isinstance(oldstylederived, W_ClassObject): - oldstyleklass = space.interpclass_w(w_klass_or_tuple) - if isinstance(oldstyleklass, W_ClassObject): - return oldstylederived.is_subclass_of(oldstyleklass) + if isinstance(w_derived, W_ClassObject): + if isinstance(w_klass_or_tuple, W_ClassObject): + return w_derived.is_subclass_of(w_klass_or_tuple) else: check_class(space, w_derived, "issubclass() arg 1 must be a class") # from here on, we are sure that w_derived is a class-like object @@ -171,31 +167,26 @@ # Exception helpers def exception_is_valid_obj_as_class_w(space, w_obj): - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_ClassObject): + if isinstance(w_obj, W_ClassObject): return True return BaseObjSpace.exception_is_valid_obj_as_class_w(space, w_obj) def exception_is_valid_class_w(space, w_cls): - cls = space.interpclass_w(w_cls) - if isinstance(cls, W_ClassObject): + if isinstance(w_cls, W_ClassObject): return True return BaseObjSpace.exception_is_valid_class_w(space, w_cls) def exception_getclass(space, w_obj): - obj = space.interpclass_w(w_obj) - if isinstance(obj, W_InstanceObject): - return obj.w_class + if isinstance(w_obj, W_InstanceObject): + return w_obj.w_class return BaseObjSpace.exception_getclass(space, w_obj) def exception_issubclass_w(space, w_cls1, w_cls2): - cls1 = space.interpclass_w(w_cls1) - cls2 = space.interpclass_w(w_cls2) - if isinstance(cls1, W_ClassObject): - if isinstance(cls2, W_ClassObject): - return cls1.is_subclass_of(cls2) + if isinstance(w_cls1, W_ClassObject): + if isinstance(w_cls2, W_ClassObject): + return w_cls1.is_subclass_of(w_cls2) return False - if isinstance(cls2, W_ClassObject): + if isinstance(w_cls2, W_ClassObject): return False return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -14,7 +14,7 @@ # ____________________________________________________________ -def sorted(lst, cmp=None, key=None, reverse=None): +def sorted(lst, cmp=None, key=None, reverse=False): "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list" sorted_lst = list(lst) sorted_lst.sort(cmp, key, reverse) diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -79,8 +79,7 @@ space.wrap(' \t')), "", "eval") - codeobj = space.interpclass_w(w_code) - if not isinstance(codeobj, PyCode): + if not isinstance(w_code, PyCode): raise OperationError(space.w_TypeError, w('eval() arg 1 must be a string or code object')) @@ -102,4 +101,4 @@ # the gettopframe_nohidden()). I bet no test fails, and it's a really # obscure case. - return codeobj.exec_code(space, w_globals, w_locals) + return w_code.exec_code(space, w_globals, w_locals) diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault @@ -6,7 +6,8 @@ generic_new_descr) from pypy.objspace.descroperation import object_getattribute -class W_Super(Wrappable): + +class W_Super(W_Root): def __init__(self, space, w_starttype, w_objtype, w_self): self.w_starttype = w_starttype self.w_objtype = w_objtype @@ -91,7 +92,8 @@ super(C, self).meth(arg)""" ) -class W_Property(Wrappable): + +class W_Property(W_Root): _immutable_fields_ = ["w_fget", "w_fset", "w_fdel"] def __init__(self, space): @@ -192,4 +194,3 @@ # descriptor for the instances. W_Property.typedef.rawdict['__doc__'] = interp_attrproperty_w('w_doc', W_Property) - diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -3,7 +3,7 @@ """ -from pypy.interpreter.baseobjspace import Wrappable From noreply at buildbot.pypy.org Sat Mar 23 01:51:36 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Sat, 23 Mar 2013 01:51:36 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Merge default into remove-smm-string Message-ID: <20130323005137.000CD1C1535@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62681:976bd18c379c Date: 2013-03-23 02:48 +0200 http://bitbucket.org/pypy/pypy/changeset/976bd18c379c/ Log: Merge default into remove-smm-string diff too long, truncating to 2000 out of 106641 lines diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -12,6 +12,11 @@ import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from itertools import imap as _imap +try: + from __pypy__ import newdict +except ImportError: + assert '__pypy__' not in _sys.builtin_module_names + newdict = lambda _ : {} try: from thread import get_ident as _get_ident @@ -326,8 +331,11 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = newdict('module') + namespace['OrderedDict'] = OrderedDict + namespace['_property'] = property + namespace['_tuple'] = tuple + namespace['__name__'] = 'namedtuple_%s' % typename try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,8 +34,6 @@ import struct import re -from __pypy__.builders import StringBuilder - __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1411,18 +1409,20 @@ except ImportError: from StringIO import StringIO - -class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - - def getvalue(self): - return self.builder.build() - +try: + from __pypy__.builders import StringBuilder +except ImportError: + assert '__pypy__' not in sys.builtin_module_names + StringBuilderFile = StringIO +else: + class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + self.write = self.builder.append + self.getvalue = self.builder.build def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) diff --git a/lib-python/2/sre_parse.py b/lib-python/2/sre_parse.py --- a/lib-python/2/sre_parse.py +++ b/lib-python/2/sre_parse.py @@ -19,8 +19,8 @@ try: from __pypy__ import newdict except ImportError: - def newdict(tp): - return {} + assert '__pypy__' not in sys.builtin_module_names + newdict = lambda _ : {} SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -96,18 +96,19 @@ # closer to the ones produced by cPickle in CPython from pickle import StringIO + try: from pickle import StringBuilderFile except ImportError: assert '__pypy__' not in sys.builtin_module_names - from pickle import StringIO as StringBuilderFile + StringBuilderFile = StringIO PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringIO() + self.__f = StringBuilderFile() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -33,7 +33,7 @@ modname = os.path.basename(modname) try: checkmodule(modname) - except Exception, e: + except Exception: import traceback, pdb traceback.print_exc() pdb.post_mortem(sys.exc_info()[2]) diff --git a/pypy/bin/dotviewer.py b/pypy/bin/dotviewer.py --- a/pypy/bin/dotviewer.py +++ b/pypy/bin/dotviewer.py @@ -4,6 +4,7 @@ Run with no arguments for help. """ +import os import sys sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))) from dotviewer.dotviewer import main diff --git a/pypy/bin/pyinteractive.py b/pypy/bin/pyinteractive.py --- a/pypy/bin/pyinteractive.py +++ b/pypy/bin/pyinteractive.py @@ -6,14 +6,13 @@ """ -import os, sys +import os +import sys import time sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) -import pypy from pypy.tool import option -from optparse import make_option from pypy.interpreter import main, interactive, error, gateway from rpython.config.config import OptionDescription, BoolOption, StrOption from rpython.config.config import Config, to_optparse diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -61,7 +61,6 @@ def main(): - import sys try: kwds = parse_options(sys.argv[1:]) except AssertionError: diff --git a/pypy/config/test/test_makerestdoc.py b/pypy/config/test/test_makerestdoc.py --- a/pypy/config/test/test_makerestdoc.py +++ b/pypy/config/test/test_makerestdoc.py @@ -1,6 +1,7 @@ +import py + from rpython.config.config import * from pypy.config.makerestdoc import make_cmdline_overview - from pypy.tool.rest.rest import process as restcheck tempdir = py.test.ensuretemp('config') @@ -19,7 +20,7 @@ def generate_html(descr): config = Config(descr) txt = descr.make_rest_doc().text() - + result = {"": txt} for path in config.getpaths(include_groups=True): subconf, step = config._cfgimpl_get_home_by_path(path) diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -107,8 +107,7 @@ There is a small-to-medium demo showing the translator and the annotator:: - cd demo - ../rpython/translator/goal/translate.py --view --annotate bpnn.py + python bin/rpython --view --annotate translator/goal/bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,7 +118,7 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../rpython/translator/goal/translate.py bpnn.py + python bin/rpython translator/goal/bpnn.py Translating Full Programs @@ -129,8 +128,7 @@ ``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd rpython/translator/goal - python translate.py targetrpystonedalone + python bin/rpython translator/goal/targetrpystonedalone This will produce the executable "targetrpystonedalone-c". @@ -138,6 +136,17 @@ interpreter`_. There is also an FAQ about how to set up this process for `your own interpreters`_. +There are several environment variables you can find useful while playing with the RPython: + +``PYPY_USESSION_DIR`` + RPython uses temporary session directories to store files that are generated during the + translation process(e.g., translated C files). ``PYPY_USESSION_DIR`` serves as a base directory for these session + dirs. The default value for this variable is the system's temporary dir. + +``PYPY_USESSION_KEEP`` + By default RPython keeps only the last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. + Increase this value if you want to preserve C files longer (useful when producing lots of lldebug builds). + .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters .. _`start reading sources`: diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -13,7 +13,7 @@ implemented. It's helpful to have an understanding of how the `RPython translation toolchain`_ works before digging into the sources. -Almost all JIT specific code is found in pypy/jit subdirectories. Translation +Almost all JIT specific code is found in rpython/jit subdirectories. Translation time code is in the codewriter directory. The metainterp directory holds platform independent code including the the tracer and the optimizer. Code in the backend directory is responsible for generating machine code. @@ -175,7 +175,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf +.. __: https://bitbucket.org/pypy/extradoc/src/tip/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py --- a/pypy/doc/test/test_whatsnew.py +++ b/pypy/doc/test/test_whatsnew.py @@ -1,6 +1,6 @@ import py import pypy -from commands import getoutput +from commands import getoutput, getstatusoutput ROOT = py.path.local(pypy.__file__).dirpath().dirpath() @@ -20,6 +20,9 @@ return startrev, branches def get_merged_branches(path, startrev, endrev): + if getstatusoutput('hg root')[0]: + py.test.skip('no Mercurial repo') + # X = take all the merges which are descendants of startrev and are on default # revset = all the parents of X which are not on default # ===> 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 @@ -20,16 +20,22 @@ .. branch: numpypy-longdouble Long double support for numpypy + .. branch: numpypy-disable-longdouble Since r_longdouble support is missing, disable all longdouble and derivative dtypes using ENABLED_LONG_DOUBLE = False + .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality + .. branch: indexing-by-array Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. +.. branch: str-dtype-improvement +Allow concatenation of str and numeric arrays + .. branch: signatures Improved RPython typing @@ -48,6 +54,7 @@ .. branch: fix-version-tool .. branch: popen2-removal .. branch: pickle-dumps +.. branch: scalar_get_set .. branch: release-2.0-beta1 @@ -99,3 +106,7 @@ .. branch: pycon2013-doc-fixes Documentation fixes after going through the docs at PyCon 2013 sprint. + +.. branch: extregistry-refactor + +.. branch: remove-list-smm diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.tool.ann_override import PyPyAnnotatorPolicy -from rpython.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE +from rpython.config.config import to_optparse, make_dict, SUPPRESS_USAGE from rpython.config.config import ConflictConfigError from pypy.tool.option import make_objspace from pypy.conftest import pypydir diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -629,7 +629,6 @@ # start a prompt if requested if inspect_requested(): - inteactive = False try: from _pypy_interact import interactive_console success = run_toplevel(interactive_console, mainmodule) diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -538,7 +538,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -555,7 +555,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -621,7 +621,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,27 +1,30 @@ import sys +from rpython.rlib.cache import Cache +from rpython.tool.uid import HUGEVAL_BYTES +from rpython.rlib import jit, types +from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, + compute_unique_id) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import r_uint + from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, UserDelAction, FrameTraceAction) from pypy.interpreter.error import (OperationError, operationerrfmt, new_exception_class, typed_unwrap_error_msg) from pypy.interpreter.argument import Arguments from pypy.interpreter.miscutils import ThreadLocals -from rpython.rlib.cache import Cache -from rpython.tool.uid import HUGEVAL_BYTES -from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.objectmodel import we_are_translated, newlist_hint,\ - compute_unique_id -from rpython.rlib.rarithmetic import r_uint -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) -unpackiterable_driver = jit.JitDriver(name = 'unpackiterable', - greens = ['tp'], - reds = ['items', 'w_iterator']) +unpackiterable_driver = jit.JitDriver(name='unpackiterable', + greens=['tp'], + reds=['items', 'w_iterator']) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -216,16 +219,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True - def __spacebind__(self, space): return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -336,10 +333,8 @@ if e.match(self, self.w_KeyError): continue raise - modname = self.str_w(w_modname) - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -348,9 +343,8 @@ self.call_function(w_exitfunc) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -422,14 +416,12 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): """NOT_RPYTHON""" - from pypy.tool.lib_pypy import LIB_PYPY try: return self._builtinmodule_list except AttributeError: @@ -698,6 +690,7 @@ raise return None + @signature(types.any(), types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True @@ -721,52 +714,28 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): - """ - This method should NOT be called unless you are really sure about - it. It is used inside the implementation of end_finally() in - pyopcode.py, and it's there so that it can be overridden by the - FlowObjSpace. - """ - if self.is_w(w_obj, self.w_None): - return True - obj = self.interpclass_w(w_obj) - return isinstance(obj, RequiredClass) - def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable into a real (interpreter-level) list. @@ -1042,8 +1011,7 @@ def is_oldstyle_instance(self, w_obj): # xxx hack hack hack from pypy.module.__builtin__.interp_classobj import W_InstanceObject - obj = self.interpclass_w(w_obj) - return obj is not None and isinstance(obj, W_InstanceObject) + return isinstance(w_obj, W_InstanceObject) def callable(self, w_obj): if self.lookup(w_obj, "__call__") is not None: @@ -1685,7 +1653,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1702,7 +1669,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp @@ -145,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -209,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/callbench/bltn04.py b/pypy/interpreter/callbench/bltn04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn04.py +++ /dev/null @@ -1,40 +0,0 @@ -from sup import run - -def w(N, start): - c = chr - - start() - i = 0 - while i < N: - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltn_instantiate.py b/pypy/interpreter/callbench/bltn_instantiate.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn_instantiate.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - o = object - start() - i = 0 - while i < N: - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna1.py b/pypy/interpreter/callbench/bltna1.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna1.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - while i < N: - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna2.py b/pypy/interpreter/callbench/bltna2.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna2.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - z = l.__init__ - while i < N: - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bm14.py b/pypy/interpreter/callbench/bm14.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bm14.py +++ /dev/null @@ -1,51 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f0(self): - pass - def f1(self, a): - pass - def f2(self, a, b): - pass - def f3(self, a, b, c): - pass - def f4(self, a, b, c, d): - pass - - a = A() - f0 = a.f0 - f1 = a.f1 - f2 = a.f2 - f3 = a.f3 - f4 = a.f4 - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f1(1) - f2(1, 2) - f2(1, 2) - f2(1, 2) - f3(1, 2, 3) - f3(1, 2, 3) - f4(1, 2, 3, 4) - - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f2(1, 2) - - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmabvararg.py b/pypy/interpreter/callbench/bmabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmabvararg.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f(self, a, b, *args): - pass - - a = A() - f = a.f - z = (3, 4, 5) - - start() - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmfilter.py b/pypy/interpreter/callbench/bmfilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmfilter.py +++ /dev/null @@ -1,20 +0,0 @@ -from sup import run - -def w(N, start): - x = range(50) - class A(object): - def f1(self, a): - return False - - x = range(50) - a = A() - f1 = a.f1 - flt = filter - - start() - i = 0 - while i < N: - flt(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/bmmore.py b/pypy/interpreter/callbench/bmmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmmore.py +++ /dev/null @@ -1,30 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f4(self, a, b, c, d): - pass - def f5(self, a, b, c, d, e): - pass - a = A() - f4 = a.f4 - f5 = a.f5 - - start() - i = 0 - while i < N: - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/compare.py b/pypy/interpreter/callbench/compare.py deleted file mode 100644 --- a/pypy/interpreter/callbench/compare.py +++ /dev/null @@ -1,22 +0,0 @@ -# compare.py - -import sys - -def main(cur, ref): - cur = open(cur, 'rU') - ref = open(ref, 'rU') - try: - while True: - cur_line = cur.next() - ref_line = ref.next() - cur_name, cur_t = cur_line.split() - ref_name, ref_t = ref_line.split() - assert cur_name == ref_name - cur_t = float(cur_t) - ref_t = float(ref_t) - print "%-16s %.06g (x%.02f)" % (cur_name, cur_t, cur_t/ref_t) - except StopIteration: - pass - -if __name__ == '__main__': - main(sys.argv[1], sys.argv[2]) diff --git a/pypy/interpreter/callbench/f04.py b/pypy/interpreter/callbench/f04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/f04.py +++ /dev/null @@ -1,39 +0,0 @@ -from sup import run - -def w(N, start): - def f0(): - pass - def f1(a): - pass - def f2(a, b): - pass - def f3(a, b, c): - pass - def f4(a, b, c, d): - pass - def f5(a, b, c, d, e): - pass - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fabvararg.py b/pypy/interpreter/callbench/fabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fabvararg.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - def f(a, b, *args): - pass - - z = (3, 4, 5) - start() - - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/ffilter.py b/pypy/interpreter/callbench/ffilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffilter.py +++ /dev/null @@ -1,14 +0,0 @@ -from sup import run - -def w(N, start): - def f1(a): - return False - x = range(50) - - start() - i = 0 - while i < N: - filter(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/ffunccall.py b/pypy/interpreter/callbench/ffunccall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffunccall.py +++ /dev/null @@ -1,36 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def foo(self, x): - pass - - __add__ = foo - - a = A() - a1 = A() - - start() - i = 0 - while i < N: - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - a + a1 - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fmore.py b/pypy/interpreter/callbench/fmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fmore.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - def f5(a, b, c, d, e): - pass - def f6(a, b, c, d, e, f): - pass - - start() - - i = 0 - while i < N: - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - f6(1, 2, 3, 4, 5, 6) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/inst.py b/pypy/interpreter/callbench/inst.py deleted file mode 100644 --- a/pypy/interpreter/callbench/inst.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def __init__(self): - pass - - class B(object): - def __init__(self, x, y): - pass - - start() - i = 0 - while i < N: - A() - A() - A() - A() - A() - B(1, 2) - B(1, 2) - B(1, 2) - B(1, 2) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/inst_no_init.py b/pypy/interpreter/callbench/inst_no_init.py deleted file mode 100644 --- a/pypy/interpreter/callbench/inst_no_init.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - pass - - start() - i = 0 - while i < N: - A() - A() - A() - A() - A() - A() - A() - A() - A() - A() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/instcall.py b/pypy/interpreter/callbench/instcall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/instcall.py +++ /dev/null @@ -1,35 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def __call__(self): - pass - - a = A() - - start() - i = 0 - while i < N: - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - a() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/sup.py b/pypy/interpreter/callbench/sup.py deleted file mode 100644 --- a/pypy/interpreter/callbench/sup.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys, time - -def ref(N, start): - start() - i = 0 - while i < N: - i+=1 - - -def run(func, n): - n *= int(sys.argv[1]) - st = [None] - t = time.time - - def start(): - st[0] = t() - - ref(n, start) - elapsed_ref1 = t() - st[0] - ref(n, start) - elapsed_ref2 = t() - st[0] - ref(n, start) - elapsed_ref3 = t() - st[0] - elapsed_ref = min(elapsed_ref1, elapsed_ref2, elapsed_ref3) - - func(n, start) - elapsed1 = t() - st[0] - func(n, start) - elapsed2 = t() - st[0] - func(n, start) - elapsed3 = t() - st[0] - elapsed = min(elapsed1, elapsed2, elapsed3) - - #if elapsed < elapsed_ref*10: - # print "not enough meat", elapsed, elapsed_ref - - print sys.argv[0].replace('.py', ''), elapsed-elapsed_ref - - diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -3,10 +3,10 @@ Code and Frame. """ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root -class Code(Wrappable): +class Code(W_Root): """A code is a compiled version of some source code. Abstract base class.""" _immutable_ = True @@ -52,19 +52,20 @@ def funcrun_obj(self, func, w_obj, args): return self.funcrun(func, args.prepend(w_obj)) -class Frame(Wrappable): + +class Frame(W_Root): """A frame is an environment supporting the execution of a code object. Abstract base class.""" def __init__(self, space, w_globals=None): - self.space = space - self.w_globals = w_globals # wrapped dict of globals - self.w_locals = None # wrapped dict of locals + self.space = space + self.w_globals = w_globals # wrapped dict of globals + self.w_locals = None # wrapped dict of locals def run(self): "Abstract method to override. Runs the frame" - raise TypeError, "abstract" - + raise TypeError("abstract") + def getdictscope(self): "Get the locals as a dictionary." self.fast2locals() @@ -86,16 +87,16 @@ def getfastscope(self): "Abstract. Get the fast locals as a list." - raise TypeError, "abstract" + raise TypeError("abstract") def setfastscope(self, scope_w): """Abstract. Initialize the fast locals from a list of values, where the order is according to self.getcode().signature().""" - raise TypeError, "abstract" + raise TypeError("abstract") def getfastscopelength(self): "Abstract. Get the expected number of locals." - raise TypeError, "abstract" + raise TypeError("abstract") def fast2locals(self): # Copy values from the fastlocals to self.w_locals diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -1,6 +1,5 @@ import sys From noreply at buildbot.pypy.org Sat Mar 23 02:12:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 02:12:27 +0100 (CET) Subject: [pypy-commit] pypy remove-array-smm: start removing SMMs from array module Message-ID: <20130323011227.A71B21C1535@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-array-smm Changeset: r62682:3b16f25b9050 Date: 2013-03-22 18:11 -0700 http://bitbucket.org/pypy/pypy/changeset/3b16f25b9050/ Log: start removing SMMs from array module diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -814,7 +814,7 @@ f = d['f'] f.func_name = func.func_name if unwrap_spec is None: - unwrap_spec = {} + unwrap_spec = getattr(func, 'unwrap_spec', {}) else: assert isinstance(unwrap_spec, dict) unwrap_spec = unwrap_spec.copy() diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -2,7 +2,7 @@ from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, interpindirect2app from pypy.interpreter.typedef import GetSetProperty, make_weakref_descr from pypy.module._file.interp_file import W_File from pypy.objspace.std.model import W_Object @@ -52,7 +52,6 @@ return a -array_append = SMM('append', 2) array_extend = SMM('extend', 2) array_count = SMM('count', 2) @@ -86,6 +85,13 @@ class W_ArrayBase(W_Object): + def descr_append(self, space, w_x): + """ append(x) + + Append new value x to the end of the array. + """ + raise NotImplementedError + @staticmethod def register(typeorder): typeorder[W_ArrayBase] = [] @@ -97,6 +103,7 @@ itemsize = GetSetProperty(descr_itemsize), typecode = GetSetProperty(descr_typecode), __weakref__ = make_weakref_descr(W_ArrayBase), + append = interpindirect2app(W_ArrayBase.descr_append), ) W_ArrayBase.typedef.registermethods(globals()) @@ -343,6 +350,13 @@ item = float(item) return space.wrap(item) + # interface + + def descr_append(self, space, w_x): + x = self.item_w(w_x) + self.setlen(self.len + 1) + self.buffer[self.len - 1] = x + # Basic get/set/append/extend methods def len__Array(space, self): @@ -394,11 +408,6 @@ def setslice__Array_ANY_ANY_ANY(space, self, w_i, w_j, w_x): space.setitem(self, space.newslice(w_i, w_j, space.w_None), w_x) - def array_append__Array_ANY(space, self, w_x): - x = self.item_w(w_x) - self.setlen(self.len + 1) - self.buffer[self.len - 1] = x - def array_extend__Array_ANY(space, self, w_iterable): self.extend(w_iterable) From noreply at buildbot.pypy.org Sat Mar 23 04:24:40 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Sat, 23 Mar 2013 04:24:40 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Remove bytearrayinterface.py (not really that much comminality). Message-ID: <20130323032440.789681C1535@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62683:24c6aa9c589b Date: 2013-03-23 05:24 +0200 http://bitbucket.org/pypy/pypy/changeset/24c6aa9c589b/ Log: Remove bytearrayinterface.py (not really that much comminality). diff --git a/pypy/objspace/std/bytearrayinterface.py b/pypy/objspace/std/bytearrayinterface.py deleted file mode 100644 --- a/pypy/objspace/std/bytearrayinterface.py +++ /dev/null @@ -1,67 +0,0 @@ -from pypy.objspace.std.model import W_Object -from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.objspace.std.inttype import wrapint - - -class W_AbstractBytearrayObject(W_Object): - pass - - -class BytearrayInterface(object): - @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) - def ljust(w_self, space, arg, fillchar=' '): - """S.ljust(width[, fillchar]) -> string - - Return S left justified in a string of length width. Padding - is done using the specified fill character (default is a space). - """ - assert isinstance(w_self, W_AbstractBytearrayObject) - u_self = w_self.data - if len(fillchar) != 1: - raise OperationError(space.w_TypeError, - space.wrap("ljust() argument 2 must be a single character")) - - d = arg - len(u_self) - if d > 0: - lst = [0] * max(arg, len(u_self)) - fillchar = fillchar[0] # annotator hint: it's a single character - lst[:len(u_self)] = u_self - for i in range(d): - lst[len(u_self) + i] = fillchar - else: - lst = u_self.data[:] - - return space.newbytearray(lst) - - @unwrap_spec(w_self=W_Root, arg=int, fillchar=str) - def rjust(w_self, space, arg, fillchar=' '): - """S.rjust(width[, fillchar]) -> string - - Return S right justified in a string of length width. Padding - is done using the specified fill character (default is a space). - """ - u_self = w_self.data - assert isinstance(w_self, W_AbstractBytearrayObject) - if len(fillchar) != 1: - raise OperationError(space.w_TypeError, - space.wrap("rjust() argument 2 must be a single character")) - - d = arg - len(u_self) - if d > 0: - lst = [0] * max(arg, len(u_self)) - fillchar = fillchar[0] # annotator hint: it's a single character - for i in range(d): - lst[i] = fillchar - lst[len(u_self)-1:] = u_self - else: - lst = u_self.data[:] - - return space.newbytearray(lst) - - -def bytearray_interface_methods(): - """Convenience function which collects all BytearrayInterface methods into a dict""" - return dict((name, interp2app(method)) for - name, method in BytearrayInterface.__dict__.items() - if not name.startswith('_')) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -26,7 +26,7 @@ ) from rpython.tool.sourcetools import func_with_new_name from pypy.objspace.std.contiguousstring import StringMethods -from pypy.objspace.std.bytearrayinterface import W_AbstractBytearrayObject +from pypy.objspace.std.bytearraytype import W_AbstractBytearrayObject class W_BytearrayObject(W_AbstractBytearrayObject): diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -1,4 +1,5 @@ -from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.interpreter.baseobjspace import W_Root +from pypy.objspace.std.model import W_Object from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.objspace.std.register_all import register_all @@ -18,14 +19,66 @@ from rpython.rlib.objectmodel import newlist_hint, resizelist_hint from pypy.objspace.std.bytearrayinterface import bytearray_interface_methods + +class W_AbstractBytearrayObject(W_Object): + pass + str_join = SMM('join', 2, defaults=(None,-1)) bytearray_append = SMM('append', 2) bytearray_extend = SMM('extend', 2) -bytearray_insert = SMM('insert', 3, - doc="B.insert(index, int) -> None\n\n" - "Insert a single item into the bytearray before " - "the given index.") + + + at unwrap_spec(w_self=W_Root, arg=int, fillchar=str) +def bytearray_ljust(w_self, space, arg, fillchar=' '): + """S.ljust(width[, fillchar]) -> string + + Return S left justified in a string of length width. Padding + is done using the specified fill character (default is a space). + """ + assert isinstance(w_self, W_AbstractBytearrayObject) + u_self = w_self.data + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("ljust() argument 2 must be a single character")) + + d = arg - len(u_self) + if d > 0: + lst = [0] * max(arg, len(u_self)) + fillchar = fillchar[0] # annotator hint: it's a single character + lst[:len(u_self)] = u_self + for i in range(d): + lst[len(u_self) + i] = fillchar + else: + lst = u_self.data[:] + + return space.newbytearray(lst) + + + at unwrap_spec(w_self=W_Root, arg=int, fillchar=str) +def bytearray_rjust(w_self, space, arg, fillchar=' '): + """S.rjust(width[, fillchar]) -> string + + Return S right justified in a string of length width. Padding + is done using the specified fill character (default is a space). + """ + u_self = w_self.data + assert isinstance(w_self, W_AbstractBytearrayObject) + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("rjust() argument 2 must be a single character")) + + d = arg - len(u_self) + if d > 0: + lst = [0] * max(arg, len(u_self)) + fillchar = fillchar[0] # annotator hint: it's a single character + for i in range(d): + lst[i] = fillchar + lst[len(u_self)-1:] = u_self + else: + lst = u_self.data[:] + + return space.newbytearray(lst) @unwrap_spec(index=int, val='str_or_int') @@ -214,9 +267,10 @@ __hash__ = None, __reduce__ = interp2app(descr_bytearray__reduce__), fromhex = interp2app(descr_fromhex, as_classmethod=True), + ljust=interp2app(bytearray_ljust), + rjust=interp2app(bytearray_rjust), insert=interp2app(bytearray_insert), pop=interp2app(bytearray_pop), remove=interp2app(bytearray_remove), - **bytearray_interface_methods() ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Sat Mar 23 05:48:23 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 05:48:23 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): use isinstance_w instead of isinstance where possible Message-ID: <20130323044823.74BDE1C15A4@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62684:5f5a605ccb6c Date: 2013-03-22 21:48 -0700 http://bitbucket.org/pypy/pypy/changeset/5f5a605ccb6c/ Log: (alex, fijal): use isinstance_w instead of isinstance where possible diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1144,7 +1144,7 @@ assert space.eq_w(get_num("-0"), space.wrap(0)) assert space.eq_w(get_num("-0xAAAAAAL"), space.wrap(-0xAAAAAAL)) n = get_num(str(-sys.maxint - 1)) - assert space.is_true(space.isinstance(n, space.w_int)) + assert space.isinstance_w(n, space.w_int) for num in ("0o53", "0O53", "0o0000053", "0O00053"): assert space.eq_w(get_num(num), space.wrap(053)) for num in ("0b00101", "0B00101", "0b101", "0B101"): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1031,9 +1031,6 @@ def issequence_w(self, w_obj): return (self.findattr(w_obj, self.wrap("__getitem__")) is not None) - def isinstance_w(self, w_obj, w_type): - return self.is_true(self.isinstance(w_obj, w_type)) - # The code below only works # for the simple case (new-style instance). # These methods are patched with the full logic by the __builtin__ @@ -1345,7 +1342,7 @@ # This is all interface for gateway.py. def gateway_int_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.int_w(self.int(w_obj)) diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -183,7 +183,7 @@ # w_type = self.w_type w_value = self.get_w_value(space) - while space.is_true(space.isinstance(w_type, space.w_tuple)): + while space.isinstance_w(w_type, space.w_tuple): w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): @@ -198,7 +198,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.is_true(space.isinstance(w_value, space.w_tuple)): + if space.isinstance_w(w_value, space.w_tuple): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -208,7 +208,7 @@ def descr_function__new__(space, w_subtype, w_code, w_globals, w_name=None, w_argdefs=None, w_closure=None): code = space.interp_w(Code, w_code) - if not space.is_true(space.isinstance(w_globals, space.w_dict)): + if not space.isinstance_w(w_globals, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("expected dict")) if not space.is_none(w_name): name = space.str_w(w_name) @@ -356,7 +356,7 @@ if space.is_w(w_defaults, space.w_None): self.defs_w = [] return - if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): + if not space.isinstance_w(w_defaults, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -81,7 +81,7 @@ def descr__reduce__(self, space): w_name = space.finditem(self.w_dict, space.wrap('__name__')) if (w_name is None or - not space.is_true(space.isinstance(w_name, space.w_str))): + not space.isinstance_w(w_name, space.w_str)): # maybe raise exception here (XXX this path is untested) return space.w_None w_modules = space.sys.get('modules') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -232,7 +232,7 @@ def getdocstring(self, space): if self.co_consts_w: # it is probably never empty w_first = self.co_consts_w[0] - if space.is_true(space.isinstance(w_first, space.w_basestring)): + if space.isinstance_w(w_first, space.w_basestring): return w_first return space.w_None @@ -246,20 +246,20 @@ else: consts[num] = self.space.unwrap(w) num += 1 - return new.code( self.co_argcount, - self.co_nlocals, - self.co_stacksize, - self.co_flags, - self.co_code, - tuple(consts), - tuple(self.co_names), - tuple(self.co_varnames), - self.co_filename, - self.co_name, - self.co_firstlineno, - self.co_lnotab, - tuple(self.co_freevars), - tuple(self.co_cellvars) ) + return new.code(self.co_argcount, + self.co_nlocals, + self.co_stacksize, + self.co_flags, + self.co_code, + tuple(consts), + tuple(self.co_names), + tuple(self.co_varnames), + self.co_filename, + self.co_name, + self.co_firstlineno, + self.co_lnotab, + tuple(self.co_freevars), + tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): from pypy.interpreter.pyframe import CPythonFrame @@ -349,12 +349,12 @@ if nlocals < 0: raise OperationError(space.w_ValueError, space.wrap("code: nlocals must not be negative")) - if not space.is_true(space.isinstance(w_constants, space.w_tuple)): + if not space.isinstance_w(w_constants, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("Expected tuple for constants")) - consts_w = space.fixedview(w_constants) - names = unpack_str_tuple(space, w_names) - varnames = unpack_str_tuple(space, w_varnames) + consts_w = space.fixedview(w_constants) + names = unpack_str_tuple(space, w_names) + varnames = unpack_str_tuple(space, w_varnames) if w_freevars is not None: freevars = unpack_str_tuple(space, w_freevars) else: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -777,12 +777,12 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space - if space.is_true(space.isinstance(w_2, space.w_tuple)): + if space.isinstance_w(w_2, space.w_tuple): for w_t in space.fixedview(w_2): - if space.is_true(space.isinstance(w_t, space.w_str)): + if space.isinstance_w(w_t, space.w_str): msg = "catching of string exceptions is deprecated" space.warn(space.wrap(msg), space.w_DeprecationWarning) - elif space.is_true(space.isinstance(w_2, space.w_str)): + elif space.isinstance_w(w_2, space.w_str): msg = "catching of string exceptions is deprecated" space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.newbool(space.exception_match(w_1, w_2)) @@ -796,7 +796,7 @@ w_result = getattr(self, attr)(w_1, w_2) break else: - raise BytecodeCorruption, "bad COMPARE_OP oparg" + raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) def IMPORT_NAME(self, nameindex, next_instr): diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -61,7 +61,6 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - if w_tb is None or not space.is_true(space.isinstance(w_tb, - space.gettypeobject(PyTraceback.typedef))): + if w_tb is None or not space.isinstance_w(w_tb, space.gettypeobject(PyTraceback.typedef)): raise OperationError(space.w_TypeError, space.wrap(msg)) return w_tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -342,7 +342,7 @@ # a couple of helpers for the Proto classes above, factored out to reduce # the translated code size def check_new_dictionary(space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("setting dictionary to a non-dict")) from pypy.objspace.std import dictmultiobject @@ -552,7 +552,7 @@ self.w_cls = w_cls def typecheck(self, space, w_obj): - if not space.is_true(space.isinstance(w_obj, self.w_cls)): + if not space.isinstance_w(w_obj, self.w_cls): raise operationerrfmt(space.w_TypeError, "descriptor '%s' for '%s'" " objects doesn't apply to '%s' object", diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -114,7 +114,7 @@ else: if w_builtin is space.builtin: # common case return space.builtin - if space.is_true(space.isinstance(w_builtin, space.w_dict)): + if space.isinstance_w(w_builtin, space.w_dict): return module.Module(space, None, w_builtin) if isinstance(w_builtin, module.Module): return w_builtin diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -8,10 +8,12 @@ """ from rpython.rlib import jit + +from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace from pypy.interpreter.error import OperationError from pypy.module.__builtin__.interp_classobj import W_ClassObject from pypy.module.__builtin__.interp_classobj import W_InstanceObject -from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace + def _get_bases(space, w_cls): """Returns 'cls.__bases__'. Returns None if there is @@ -23,7 +25,7 @@ if not e.match(space, space.w_AttributeError): raise # propagate other errors return None - if space.is_true(space.isinstance(w_bases, space.w_tuple)): + if space.isinstance_w(w_bases, space.w_tuple): return w_bases else: return None @@ -50,7 +52,7 @@ # -- case (anything, tuple) # XXX it might be risky that the JIT sees this - if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)): + if space.isinstance_w(w_klass_or_tuple, space.w_tuple): for w_klass in space.fixedview(w_klass_or_tuple): if abstract_isinstance_w(space, w_obj, w_klass, allow_override): return True @@ -129,8 +131,7 @@ """Implementation for the full 'issubclass(derived, klass_or_tuple)'.""" # -- case (class-like-object, tuple-of-classes) - # XXX it might be risky that the JIT sees this - if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)): + if space.isinstance_w(w_klass_or_tuple, space.w_tuple): for w_klass in space.fixedview(w_klass_or_tuple): if abstract_issubclass_w(space, w_derived, w_klass, allow_override): return True diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -7,6 +7,7 @@ from pypy.interpreter.astcompiler import consts, ast from pypy.interpreter.gateway import unwrap_spec + @unwrap_spec(filename=str, mode=str, flags=int, dont_inherit=int) def compile(space, w_source, filename, mode, flags=0, dont_inherit=0): """Compile the source string (a Python module, statement or expression) @@ -25,10 +26,10 @@ ast_node = None w_ast_type = space.gettypeobject(ast.AST.typedef) str_ = None - if space.is_true(space.isinstance(w_source, w_ast_type)): + if space.isinstance_w(w_source, w_ast_type): ast_node = space.interp_w(ast.mod, w_source) ast_node.sync_app_attrs(space) - elif space.is_true(space.isinstance(w_source, space.w_unicode)): + elif space.isinstance_w(w_source, space.w_unicode): w_utf_8_source = space.call_method(w_source, "encode", space.wrap("utf-8")) str_ = space.str_w(w_utf_8_source) @@ -72,8 +73,8 @@ """ w = space.wrap - if (space.is_true(space.isinstance(w_code, space.w_str)) or - space.is_true(space.isinstance(w_code, space.w_unicode))): + if (space.isinstance_w(w_code, space.w_str) or + space.isinstance_w(w_code, space.w_unicode)): w_code = compile(space, space.call_method(w_code, 'lstrip', space.wrap(' \t')), diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -47,7 +47,8 @@ n = 0 return n - at unwrap_spec(w_step = WrappedDefault(1)) + + at unwrap_spec(w_step=WrappedDefault(1)) def range_int(space, w_x, w_y=None, w_step=None): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to @@ -60,24 +61,24 @@ w_start = w_x w_stop = w_y - if space.is_true(space.isinstance(w_stop, space.w_float)): + if space.isinstance_w(w_stop, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer end argument expected, got float.")) - if space.is_true(space.isinstance(w_start, space.w_float)): + if space.isinstance_w(w_start, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer start argument expected, got float.")) - if space.is_true(space.isinstance(w_step, space.w_float)): + if space.isinstance_w(w_step, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer step argument expected, got float.")) w_start = space.int(w_start) - w_stop = space.int(w_stop) - w_step = space.int(w_step) + w_stop = space.int(w_stop) + w_step = space.int(w_step) try: start = space.int_w(w_start) - stop = space.int_w(w_stop) - step = space.int_w(w_step) + stop = space.int_w(w_stop) + step = space.int_w(w_step) except OperationError, e: if not e.match(space, space.w_OverflowError): raise @@ -107,7 +108,7 @@ start = lo = space.bigint_w(w_start) hi = space.bigint_w(w_stop) - step = st = space.bigint_w(w_step) + step = st = space.bigint_w(w_step) if not step.tobool(): raise OperationError(space.w_ValueError, diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -25,10 +25,10 @@ # XXX it's not clear that we have to catch the TypeError... def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict): - if not space.is_true(space.isinstance(w_bases, space.w_tuple)): + if not space.isinstance_w(w_bases, space.w_tuple): raise_type_err(space, 'bases', 'tuple', w_bases) - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise_type_err(space, 'bases', 'tuple', w_bases) if not space.is_true(space.contains(w_dict, space.wrap("__doc__"))): @@ -68,27 +68,24 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError( space.w_TypeError, space.wrap("__dict__ must be a dictionary object")) self.w_dict = w_dict def setname(self, space, w_newname): - if not space.is_true(space.isinstance(w_newname, space.w_str)): - raise OperationError( - space.w_TypeError, - space.wrap("__name__ must be a string object")) + if not space.isinstance_w(w_newname, space.w_str): + raise OperationError(space.w_TypeError, + space.wrap("__name__ must be a string object") + ) self.name = space.str_w(w_newname) def setbases(self, space, w_bases): - # XXX in theory, this misses a check against inheritance cycles - # although on pypy we don't get a segfault for infinite - # recursion anyway - if not space.is_true(space.isinstance(w_bases, space.w_tuple)): - raise OperationError( - space.w_TypeError, - space.wrap("__bases__ must be a tuple object")) + if not space.isinstance_w(w_bases, space.w_tuple): + raise OperationError(space.w_TypeError, + space.wrap("__bases__ must be a tuple object") + ) bases_w = space.fixedview(w_bases) for w_base in bases_w: if not isinstance(w_base, W_ClassObject): @@ -194,7 +191,7 @@ if not e.match(space, space.w_AttributeError): raise return "?" - if space.is_true(space.isinstance(w_mod, space.w_str)): + if space.isinstance_w(w_mod, space.w_str): return space.str_w(w_mod) return "?" @@ -464,7 +461,7 @@ def descr_len(self, space): w_meth = self.getattr(space, '__len__') w_result = space.call_function(w_meth) - if space.is_true(space.isinstance(w_result, space.w_int)): + if space.isinstance_w(w_result, space.w_int): if space.is_true(space.lt(w_result, space.wrap(0))): raise OperationError( space.w_ValueError, @@ -532,7 +529,7 @@ if w_func is None: return space.w_True w_result = space.call_function(w_func) - if space.is_true(space.isinstance(w_result, space.w_int)): + if space.isinstance_w(w_result, space.w_int): if space.is_true(space.lt(w_result, space.wrap(0))): raise OperationError( space.w_ValueError, @@ -594,16 +591,16 @@ def descr_hash(self, space): w_func = self.getattr(space, '__hash__', False) if w_func is None: - w_eq = self.getattr(space, '__eq__', False) - w_cmp = self.getattr(space, '__cmp__', False) + w_eq = self.getattr(space, '__eq__', False) + w_cmp = self.getattr(space, '__cmp__', False) if w_eq is not None or w_cmp is not None: raise OperationError(space.w_TypeError, space.wrap("unhashable instance")) else: return space.wrap(compute_identity_hash(self)) w_ret = space.call_function(w_func) - if (not space.is_true(space.isinstance(w_ret, space.w_int)) and - not space.is_true(space.isinstance(w_ret, space.w_long))): + if (not space.isinstance_w(w_ret, space.w_int) and + not space.isinstance_w(w_ret, space.w_long)): raise OperationError( space.w_TypeError, space.wrap("__hash__ must return int or long")) @@ -654,7 +651,6 @@ if space.eq_w(w_x, w_obj): return space.w_True - def descr_pow(self, space, w_other, w_modulo=None): if space.is_none(w_modulo): w_a, w_b = _coerce_helper(space, self, w_other) diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -3,6 +3,7 @@ from rpython.rlib.rstring import UnicodeBuilder from rpython.rlib.objectmodel import we_are_translated + class CodecState(object): def __init__(self, space): self.codec_search_path = [] @@ -35,11 +36,11 @@ space.wrap(endpos), space.wrap(reason)) w_res = space.call_function(w_errorhandler, w_exc) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2 - or not space.is_true(space.isinstance( + or not space.isinstance_w( space.getitem(w_res, space.wrap(0)), - space.w_unicode))): + space.w_unicode)): if decode: msg = ("decoding error handler must return " "(unicode, int) tuple, not %s") @@ -135,8 +136,7 @@ w_result = space.call_function(w_search, space.wrap(normalized_encoding)) if not space.is_w(w_result, space.w_None): - if not (space.is_true(space.isinstance(w_result, - space.w_tuple)) and + if not (space.isinstance_w(w_result, space.w_tuple) and space.len_w(w_result) == 4): raise OperationError( space.w_TypeError, @@ -322,8 +322,7 @@ w_decoder = space.getitem(lookup_codec(space, encoding), space.wrap(1)) if space.is_true(w_decoder): w_res = space.call_function(w_decoder, w_obj, space.wrap(errors)) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) - or space.len_w(w_res) != 2): + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2): raise OperationError( space.w_TypeError, space.wrap("encoder must return a tuple (object, integer)")) @@ -493,7 +492,7 @@ self.w_mapping = w_mapping # fast path for all the stuff in the encodings module - if space.is_true(space.isinstance(w_mapping, space.w_tuple)): + if space.isinstance_w(w_mapping, space.w_tuple): self.mapping_w = space.fixedview(w_mapping) else: self.mapping_w = None diff --git a/pypy/module/_locale/interp_locale.py b/pypy/module/_locale/interp_locale.py --- a/pypy/module/_locale/interp_locale.py +++ b/pypy/module/_locale/interp_locale.py @@ -118,11 +118,12 @@ _strcoll = rlocale.external('strcoll', [rffi.CCHARP, rffi.CCHARP], rffi.INT) _wcscoll = rlocale.external('wcscoll', [rffi.CWCHARP, rffi.CWCHARP], rffi.INT) + def strcoll(space, w_s1, w_s2): "string,string -> int. Compares two strings according to the locale." - if space.is_true(space.isinstance(w_s1, space.w_str)) and \ - space.is_true(space.isinstance(w_s2, space.w_str)): + if (space.isinstance_w(w_s1, space.w_str) and + space.isinstance_w(w_s2, space.w_str)): s1, s2 = space.str_w(w_s1), space.str_w(w_s2) s1_c = rffi.str2charp(s1) @@ -133,11 +134,6 @@ rffi.free_charp(s1_c) rffi.free_charp(s2_c) - #if not space.is_true(space.isinstance(w_s1, space.w_unicode)) and \ - # not space.is_true(space.isinstance(w_s2, space.w_unicode)): - # raise OperationError(space.w_ValueError, - # space.wrap("strcoll arguments must be strings")) - s1, s2 = space.unicode_w(w_s1), space.unicode_w(w_s2) s1_c = rffi.unicode2wcharp(s1) diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -28,9 +28,9 @@ if w_n is None: w_n = space.newint(int(time.time())) else: - if space.is_true(space.isinstance(w_n, space.w_int)): + if space.isinstance_w(w_n, space.w_int): w_n = space.abs(w_n) - elif space.is_true(space.isinstance(w_n, space.w_long)): + elif space.isinstance_w(w_n, space.w_long): w_n = space.abs(w_n) else: # XXX not perfectly like CPython @@ -59,7 +59,7 @@ return space.newtuple(state) def setstate(self, space, w_state): - if not space.is_true(space.isinstance(w_state, space.w_tuple)): + if not space.isinstance_w(w_state, space.w_tuple): errstring = space.wrap("state vector must be tuple") raise OperationError(space.w_TypeError, errstring) if space.len_w(w_state) != rrandom.N + 1: @@ -78,7 +78,7 @@ self._rnd.index = space.int_w(w_item) def jumpahead(self, space, w_n): - if space.is_true(space.isinstance(w_n, space.w_long)): + if space.isinstance_w(w_n, space.w_long): num = space.bigint_w(w_n) n = intmask(num.uintmask()) else: diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py --- a/pypy/module/_rawffi/array.py +++ b/pypy/module/_rawffi/array.py @@ -163,7 +163,7 @@ return itemsize * self.length def decodeslice(self, space, w_slice): - if not space.is_true(space.isinstance(w_slice, space.w_slice)): + if not space.isinstance_w(w_slice, space.w_slice): raise OperationError(space.w_TypeError, space.wrap('index must be int or slice')) letter = self.shape.itemcode diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -91,7 +91,7 @@ def unpack_simple_shape(space, w_shape): # 'w_shape' must be either a letter or a tuple (struct, 1). - if space.is_true(space.isinstance(w_shape, space.w_str)): + if space.isinstance_w(w_shape, space.w_str): letter = space.str_w(w_shape) return letter2tp(space, letter) else: @@ -102,7 +102,7 @@ def unpack_shape_with_length(space, w_shape): # Allow 'w_shape' to be a letter or any (shape, number). # The result is always a W_Array. - if space.is_true(space.isinstance(w_shape, space.w_str)): + if space.isinstance_w(w_shape, space.w_str): letter = space.str_w(w_shape) return letter2tp(space, letter) else: @@ -171,7 +171,7 @@ else: ffi_restype = ffi_type_void - if space.is_true(space.isinstance(w_name, space.w_str)): + if space.isinstance_w(w_name, space.w_str): name = space.str_w(w_name) try: @@ -183,8 +183,7 @@ except LibFFIError: raise got_libffi_error(space) - elif (_MS_WINDOWS and - space.is_true(space.isinstance(w_name, space.w_int))): + elif (_MS_WINDOWS and space.isinstance_w(w_name, space.w_int)): ordinal = space.int_w(w_name) try: ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes, @@ -311,12 +310,13 @@ raise NotImplementedError("abstract base class") def unwrap_truncate_int(TP, space, w_arg): - if space.is_true(space.isinstance(w_arg, space.w_int)): + if space.isinstance_w(w_arg, space.w_int): return rffi.cast(TP, space.int_w(w_arg)) else: return rffi.cast(TP, space.bigint_w(w_arg).ulonglongmask()) unwrap_truncate_int._annspecialcase_ = 'specialize:arg(0)' + def unwrap_value(space, push_func, add_arg, argdesc, letter, w_arg): w = space.wrap if letter in TYPEMAP_PTR_LETTERS: diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py --- a/pypy/module/_rawffi/structure.py +++ b/pypy/module/_rawffi/structure.py @@ -32,7 +32,7 @@ name = space.str_w(l_w[0]) except OperationError: raise OperationError(space.w_TypeError, space.wrap( - "structure field name must be string not %s" % + "structure field name must be string not %s" % space.type(l_w[0]).getname(space))) tp = unpack_shape_with_length(space, l_w[1]) @@ -153,7 +153,7 @@ bitsizes = None self.fields = fields self.size = size - self.alignment = alignment + self.alignment = alignment self.ll_positions = pos self.ll_bitsizes = bitsizes self.name_to_index = name_to_index @@ -223,11 +223,10 @@ self.alignment, fieldtypes) return self.ffi_struct.ffistruct - + def __del__(self): if self.ffi_struct: lltype.free(self.ffi_struct, flavor='raw') - @unwrap_spec(union=bool, pack=int) @@ -236,7 +235,7 @@ raise OperationError(space.w_ValueError, space.wrap( "_pack_ must be a non-negative integer")) - if space.is_true(space.isinstance(w_shapeinfo, space.w_tuple)): + if space.isinstance_w(w_shapeinfo, space.w_tuple): w_size, w_alignment = space.fixedview(w_shapeinfo, expected_length=2) S = W_Structure(space, None, space.int_w(w_size), space.int_w(w_alignment), union) @@ -372,7 +371,7 @@ def __del__(self): if self.ll_buffer: self._free() - + W_StructureInstanceAutoFree.typedef = TypeDef( 'StructureInstanceAutoFree', __repr__ = interp2app(W_StructureInstance.descr_repr), diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -255,9 +255,9 @@ # host can be None, string or unicode if space.is_w(w_host, space.w_None): host = None - elif space.is_true(space.isinstance(w_host, space.w_str)): + elif space.isinstance_w(w_host, space.w_str): host = space.str_w(w_host) - elif space.is_true(space.isinstance(w_host, space.w_unicode)): + elif space.isinstance_w(w_host, space.w_unicode): w_shost = space.call_method(w_host, "encode", space.wrap("idna")) host = space.str_w(w_shost) else: @@ -268,9 +268,9 @@ # port can be None, int or string if space.is_w(w_port, space.w_None): port = None - elif space.is_true(space.isinstance(w_port, space.w_int)): + elif space.isinstance_w(w_port, space.w_int): port = str(space.int_w(w_port)) - elif space.is_true(space.isinstance(w_port, space.w_str)): + elif space.isinstance_w(w_port, space.w_str): port = space.str_w(w_port) else: raise OperationError(space.w_TypeError, diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -231,7 +231,7 @@ "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info -def test_unknown_addr_as_object(): +def test_unknown_addr_as_object(): from pypy.module._socket.interp_socket import addr_as_object c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw') c_addr.c_sa_data[0] = 'c' @@ -240,7 +240,7 @@ # to be short enough so we have some data, 1 sounds good enough # + sizeof USHORT w_obj = addr_as_object(rsocket.Address(c_addr, 1 + 2), -1, space) - assert space.is_true(space.isinstance(w_obj, space.w_tuple)) + assert space.isinstance_w(w_obj, space.w_tuple) assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15 assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c' diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -101,18 +101,24 @@ """Make a StrMatchContext or a UnicodeMatchContext for searching in the given w_string object.""" space = self.space - if pos < 0: pos = 0 - if endpos < pos: endpos = pos - if space.is_true(space.isinstance(w_string, space.w_unicode)): + if pos < 0: + pos = 0 + if endpos < pos: + endpos = pos + if space.isinstance_w(w_string, space.w_unicode): unicodestr = space.unicode_w(w_string) - if pos > len(unicodestr): pos = len(unicodestr) - if endpos > len(unicodestr): endpos = len(unicodestr) + if pos > len(unicodestr): + pos = len(unicodestr) + if endpos > len(unicodestr): + endpos = len(unicodestr) return rsre_core.UnicodeMatchContext(self.code, unicodestr, pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) - if pos > len(str): pos = len(str) - if endpos > len(str): endpos = len(str) + if pos > len(str): + pos = len(str) + if endpos > len(str): + endpos = len(str) return rsre_core.StrMatchContext(self.code, str, pos, endpos, self.flags) @@ -212,7 +218,7 @@ w_filter = w_ptemplate filter_is_callable = True else: - if space.is_true(space.isinstance(w_ptemplate, space.w_unicode)): + if space.isinstance_w(w_ptemplate, space.w_unicode): filter_as_unicode = space.unicode_w(w_ptemplate) literal = u'\\' not in filter_as_unicode else: @@ -267,7 +273,7 @@ sublist_w.append(slice_w(space, ctx, last_pos, ctx.end, space.w_None)) - if space.is_true(space.isinstance(w_string, space.w_unicode)): + if space.isinstance_w(w_string, space.w_unicode): w_emptystr = space.wrap(u'') else: w_emptystr = space.wrap('') @@ -381,15 +387,15 @@ return space.call_method(w_re, '_expand', space.wrap(self.srepat), space.wrap(self), w_template) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def start_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[0]) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def end_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[1]) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def span_w(self, w_groupnum): start, end = self.do_span(w_groupnum) return self.space.newtuple([self.space.wrap(start), diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py --- a/pypy/module/_weakref/interp__weakref.py +++ b/pypy/module/_weakref/interp__weakref.py @@ -92,8 +92,7 @@ w_weakreftype = space.gettypeobject(W_Weakref.typedef) for wref in self.other_refs_weak.items(): w_ref = wref() - if (w_ref is not None and - space.is_true(space.isinstance(w_ref, w_weakreftype))): + if (w_ref is not None and space.isinstance_w(w_ref, w_weakreftype)): return w_ref return space.w_None @@ -103,8 +102,8 @@ def __init__(self, space, oldlifeline=None): self.space = space if oldlifeline is not None: - self.cached_weakref = oldlifeline.cached_weakref - self.cached_proxy = oldlifeline.cached_proxy + self.cached_weakref = oldlifeline.cached_weakref + self.cached_proxy = oldlifeline.cached_proxy self.other_refs_weak = oldlifeline.other_refs_weak def __del__(self): diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -108,9 +108,9 @@ raise OperationError(space.w_TypeError, errstring) elif isinstance(w_hkey, W_HKEY): return w_hkey.hkey - elif space.is_true(space.isinstance(w_hkey, space.w_int)): + elif space.isinstance_w(w_hkey, space.w_int): return rffi.cast(rwinreg.HKEY, space.int_w(w_hkey)) - elif space.is_true(space.isinstance(w_hkey, space.w_long)): + elif space.isinstance_w(w_hkey, space.w_long): return rffi.cast(rwinreg.HKEY, space.uint_w(w_hkey)) else: errstring = space.wrap("The object is not a PyHKEY object") @@ -266,7 +266,7 @@ buf = None if typ == rwinreg.REG_DWORD: - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): buflen = rffi.sizeof(rwin32.DWORD) buf1 = lltype.malloc(rffi.CArray(rwin32.DWORD), 1, flavor='raw') buf1[0] = space.uint_w(w_value) @@ -278,7 +278,7 @@ buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') buf[0] = '\0' else: - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): w_value = space.call_method(w_value, 'encode', space.wrap('mbcs')) buf = rffi.str2charp(space.str_w(w_value)) @@ -289,7 +289,7 @@ buflen = 1 buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') buf[0] = '\0' - elif space.is_true(space.isinstance(w_value, space.w_list)): + elif space.isinstance_w(w_value, space.w_list): strings = [] buflen = 0 @@ -298,7 +298,7 @@ while True: try: w_item = space.next(w_iter) - if space.is_true(space.isinstance(w_item, space.w_unicode)): + if space.isinstance_w(w_item, space.w_unicode): w_item = space.call_method(w_item, 'encode', space.wrap('mbcs')) item = space.str_w(w_item) diff --git a/pypy/module/cpyext/complexobject.py b/pypy/module/cpyext/complexobject.py --- a/pypy/module/cpyext/complexobject.py +++ b/pypy/module/cpyext/complexobject.py @@ -12,21 +12,24 @@ Py_complex_fields = (("real", rffi.DOUBLE), ("imag", rffi.DOUBLE)) cpython_struct("Py_complex", Py_complex_fields, Py_complex_t) + @cpython_api([lltype.Float, lltype.Float], PyObject) def PyComplex_FromDoubles(space, real, imag): return space.newcomplex(real, imag) + @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_RealAsDouble(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_complex)): + if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.realval else: return space.float_w(w_obj) + @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_ImagAsDouble(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_complex)): + if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.imagval else: diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -29,7 +29,7 @@ space.setitem(w_globals, space.wrap("__builtins__"), w_builtin) # Get the __import__ function from the builtins - if space.is_true(space.isinstance(w_builtin, space.w_dict)): + if space.isinstance_w(w_builtin, space.w_dict): w_import = space.getitem(w_builtin, space.wrap("__import__")) else: w_import = space.getattr(w_builtin, space.wrap("__import__")) diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py --- a/pypy/module/cpyext/intobject.py +++ b/pypy/module/cpyext/intobject.py @@ -69,6 +69,7 @@ space.wrap("an integer is required, got NULL")) return space.uint_w(space.int(w_obj)) + @cpython_api([PyObject], rffi.ULONG, error=-1) def PyInt_AsUnsignedLongMask(space, w_obj): """Will first attempt to cast the object to a PyIntObject or @@ -76,13 +77,14 @@ unsigned long. This function does not check for overflow. """ w_int = space.int(w_obj) - if space.is_true(space.isinstance(w_int, space.w_int)): + if space.isinstance_w(w_int, space.w_int): num = space.int_w(w_int) return r_uint(num) else: num = space.bigint_w(w_int) return num.uintmask() + @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyInt_AsUnsignedLongLongMask(space, w_obj): """Will first attempt to cast the object to a PyIntObject or @@ -90,7 +92,7 @@ unsigned long long, without checking for overflow. """ w_int = space.int(w_obj) - if space.is_true(space.isinstance(w_int, space.w_int)): + if space.isinstance_w(w_int, space.w_int): num = space.int_w(w_int) return r_ulonglong(num) else: diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py --- a/pypy/module/cpyext/pyerrors.py +++ b/pypy/module/cpyext/pyerrors.py @@ -182,7 +182,7 @@ exc is a class object, this also returns true when given is an instance of a subclass. If exc is a tuple, all exceptions in the tuple (and recursively in subtuples) are searched for a match.""" - if (space.is_true(space.isinstance(w_given, space.w_BaseException)) or + if (space.isinstance_w(w_given, space.w_BaseException) or space.is_oldstyle_instance(w_given)): w_given_type = space.exception_getclass(w_given) else: diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -304,7 +304,7 @@ api.PyUnicode_Decode(b_text, 4, b_encoding, None)) == u'caf\xe9' w_text = api.PyUnicode_FromEncodedObject(space.wrap("test"), b_encoding, None) - assert space.is_true(space.isinstance(w_text, space.w_unicode)) + assert space.isinstance_w(w_text, space.w_unicode) assert space.unwrap(w_text) == "test" assert api.PyUnicode_FromEncodedObject(space.wrap(u"test"), b_encoding, None) is None diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -248,7 +248,7 @@ Py_DecRef(space, base_object_pyo) def check_descr(space, w_self, w_type): - if not space.is_true(space.isinstance(w_self, w_type)): + if not space.isinstance_w(w_self, w_type): raise DescrMismatch() class GettersAndSetters: @@ -489,7 +489,7 @@ pto.c_tp_as_sequence = heaptype.c_as_sequence pto.c_tp_as_mapping = heaptype.c_as_mapping pto.c_tp_as_buffer = heaptype.c_as_buffer - + return rffi.cast(PyObject, heaptype) def type_attach(space, py_obj, w_type): @@ -734,4 +734,4 @@ return if w_obj.is_cpytype(): w_obj.mutated(None) - + diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -1,6 +1,5 @@ from pypy.interpreter.error import OperationError from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rtyper.lltypesystem import llmemory from pypy.module.unicodedata import unicodedb from pypy.module.cpyext.api import ( CANNOT_FAIL, Py_ssize_t, build_type_checkers, cpython_api, @@ -388,7 +387,7 @@ # - unicode is disallowed # - raise TypeError for non-string types - if space.is_true(space.isinstance(w_obj, space.w_unicode)): + if space.isinstance_w(w_obj, space.w_unicode): w_meth = None else: try: diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -156,7 +156,7 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("setting exceptions's dictionary to a non-dict")) self.w_dict = w_dict diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -182,7 +182,7 @@ def _log_any(space, w_x, base): # base is supposed to be positive or 0.0, which means we use e try: - if space.is_true(space.isinstance(w_x, space.w_long)): + if space.isinstance_w(w_x, space.w_long): # special case to support log(extremely-large-long) num = space.bigint_w(w_x) result = num.log(base) diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py --- a/pypy/module/operator/interp_operator.py +++ b/pypy/module/operator/interp_operator.py @@ -233,8 +233,8 @@ raise OperationError(space.w_TypeError, space.wrap("non-sequence object can't be repeated")) - if not (space.is_true(space.isinstance(w_obj2, space.w_int)) or \ - space.is_true(space.isinstance(w_obj2, space.w_long))): + if not (space.isinstance_w(w_obj2, space.w_int) or + space.isinstance_w(w_obj2, space.w_long)): # second arg has to be int/long raise OperationError(space.w_TypeError, space.wrap('an integer is required')) diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -82,7 +82,7 @@ # perform binds if w_vars is None: pass - elif space.is_true(space.isinstance(w_vars, space.w_dict)): + elif space.isinstance_w(w_vars, space.w_dict): self._setBindVariablesByName(space, w_vars, 1, 0, 0) else: self._setBindVariablesByPos(space, w_vars, 1, 0, 0) @@ -114,7 +114,7 @@ def executemany(self, space, w_stmt, w_list_of_args): if space.is_w(w_stmt, space.w_None): w_stmt = None - if not space.is_true(space.isinstance(w_list_of_args, space.w_list)): + if not space.isinstance_w(w_list_of_args, space.w_list): raise OperationError( space.w_TypeError, space.wrap("list expected")) @@ -137,7 +137,7 @@ for i in range(numrows): w_arguments = args_w[i] deferred = i < numrows - 1 - if space.is_true(space.isinstance(w_arguments, space.w_dict)): + if space.isinstance_w(w_arguments, space.w_dict): self._setBindVariablesByName( space, w_arguments, numrows, i, deferred) else: @@ -317,7 +317,7 @@ if e.match(space, get(space).w_DatabaseError): attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') try: - status = roci.OCIAttrGet( + roci.OCIAttrGet( self.handle, roci.OCI_HTYPE_STMT, rffi.cast(roci.dvoidp, attrptr), lltype.nullptr(roci.Ptr(roci.ub4).TO), @@ -603,7 +603,7 @@ def _setBindVariableHelper(self, space, w_value, origVar, numElements, arrayPos, defer): - valueIsVariable = space.is_true(space.isinstance(w_value, get(space).w_Variable)) + valueIsVariable = space.isinstance_w(w_value, get(space).w_Variable) newVar = None # handle case where variable is already bound @@ -859,8 +859,6 @@ def _createRow(self, space): items_w = [] - numItems = len(self.fetchVariables) - # acquire the value for each item for var in self.fetchVariables: assert isinstance(var, interp_variable.W_Variable) @@ -981,9 +979,9 @@ size = varType.size # determine the number of elements to create - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): numElements = space.len_w(w_value) - elif space.is_true(space.isinstance(w_value, space.w_int)): + elif space.isinstance_w(w_value, space.w_int): numElements = space.int_w(w_value) else: raise OperationError( @@ -995,7 +993,7 @@ var.makeArray(space) # set the value, if applicable - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): var.setArrayValue(space, w_value) return var diff --git a/pypy/module/oracle/interp_variable.py b/pypy/module/oracle/interp_variable.py --- a/pypy/module/oracle/interp_variable.py +++ b/pypy/module/oracle/interp_variable.py @@ -425,7 +425,7 @@ def setArrayValue(self, space, w_value): # ensure we have an array to set - if not space.is_true(space.isinstance(w_value, space.w_list)): + if not space.isinstance_w(w_value, space.w_list): raise OperationError( space.w_TypeError, space.wrap("expecting array data")) @@ -514,7 +514,7 @@ wantBytes = self.charsetForm == roci.SQLCS_IMPLICIT if wantBytes: - if space.is_true(space.isinstance(w_value, space.w_str)): + if space.isinstance_w(w_value, space.w_str): buf = config.StringBuffer() buf.fill(space, w_value) size = buf.size @@ -523,7 +523,7 @@ space.w_TypeError, space.wrap("expecting string or buffer data")) else: - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): buf = config.StringBuffer() buf.fill_with_unicode(space, w_value) size = buf.size @@ -760,7 +760,7 @@ rffi.cast(roci.Ptr(roci.OCINumber), self.data), pos) - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): integerValuePtr = lltype.malloc(roci.Ptr(lltype.Signed).TO, 1, flavor='raw') try: @@ -776,7 +776,7 @@ finally: lltype.free(integerValuePtr, flavor='raw') return - elif space.is_true(space.isinstance(w_value, space.w_long)): + elif space.isinstance_w(w_value, space.w_long): text_buf = config.StringBuffer() text_buf.fill(space, space.str(w_value)) format_buf = config.StringBuffer() @@ -793,7 +793,7 @@ status, "NumberVar_SetValue(): from long") return # XXX The bool case was already processed above - elif space.is_true(space.isinstance(w_value, space.w_float)): + elif space.isinstance_w(w_value, space.w_float): doubleValuePtr = lltype.malloc(roci.Ptr(lltype.Float).TO, 1, flavor='raw') try: @@ -808,7 +808,7 @@ finally: lltype.free(doubleValuePtr, flavor='raw') return - elif space.is_true(space.isinstance(w_value, get(space).w_DecimalType)): + elif space.isinstance_w(w_value, get(space).w_DecimalType): w_text, w_format = transform.DecimalToFormatAndText(self.environment, w_value) text_buf = config.StringBuffer() text_buf.fill(space, w_text) @@ -856,14 +856,14 @@ dataptr = rffi.ptradd( rffi.cast(roci.Ptr(roci.OCIDate), self.data), pos) - if space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if space.isinstance_w(w_value, get(space).w_DateTimeType): year = space.int_w(space.getattr(w_value, space.wrap('year'))) month = space.int_w(space.getattr(w_value, space.wrap('month'))) day = space.int_w(space.getattr(w_value, space.wrap('day'))) hour = space.int_w(space.getattr(w_value, space.wrap('hour'))) minute = space.int_w(space.getattr(w_value, space.wrap('minute'))) second = space.int_w(space.getattr(w_value, space.wrap('second'))) - elif space.is_true(space.isinstance(w_value, get(space).w_DateType)): + elif space.isinstance_w(w_value, get(space).w_DateType): year = space.int_w(space.getattr(w_value, space.wrap('year'))) month = space.int_w(space.getattr(w_value, space.wrap('month'))) day = space.int_w(space.getattr(w_value, space.wrap('day'))) @@ -933,7 +933,7 @@ def setValueProc(self, space, pos, w_value): # make sure a timestamp is being bound - if not space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if not space.isinstance_w(w_value, get(space).w_DateTimeType): raise OperationError( space.w_TypeError, space.wrap("expecting timestamp data")) @@ -985,8 +985,7 @@ self.environment, self.getDataptr(pos)) def setValueProc(self, space, pos, w_value): - if not space.is_true(space.isinstance(w_value, - get(space).w_TimedeltaType)): + if not space.isinstance_w(w_value, get(space).w_TimedeltaType): raise OperationError( space.w_TypeError, space.wrap("expecting timedelta data")) @@ -1208,7 +1207,7 @@ def setValueProc(self, space, pos, w_value): from pypy.module.oracle import interp_cursor w_CursorType = space.gettypeobject(interp_cursor.W_Cursor.typedef) - if not space.is_true(space.isinstance(w_value, w_CursorType)): + if not space.isinstance_w(w_value, w_CursorType): raise OperationError( space.w_TypeError, space.wrap("expecting cursor")) @@ -1414,7 +1413,7 @@ from pypy.objspace.std.typeobject import W_TypeObject moduledict = get(space) - if not space.is_true(space.isinstance(w_type, space.w_type)): + if not space.isinstance_w(w_type, space.w_type): raise OperationError( space.w_TypeError, space.wrap("Variable_TypeByPythonType(): type expected")) @@ -1435,49 +1434,49 @@ if space.is_w(w_value, space.w_None): return VT_String, 1, numElements - if space.is_true(space.isinstance(w_value, space.w_str)): + if space.isinstance_w(w_value, space.w_str): size = space.len_w(w_value) if size > config.MAX_STRING_CHARS: return VT_LongString, size, numElements else: return VT_String, size, numElements - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): size = space.len_w(w_value) return VT_NationalCharString, size, numElements - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): return VT_Integer, 0, numElements - if space.is_true(space.isinstance(w_value, space.w_long)): + if space.isinstance_w(w_value, space.w_long): return VT_LongInteger, 0, numElements - if space.is_true(space.isinstance(w_value, space.w_float)): + if space.isinstance_w(w_value, space.w_float): return VT_Float, 0, numElements # XXX cxBinary # XXX bool - if space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if space.isinstance_w(w_value, get(space).w_DateTimeType): return VT_DateTime, 0, numElements - if space.is_true(space.isinstance(w_value, get(space).w_DateType)): + if space.isinstance_w(w_value, get(space).w_DateType): return VT_Date, 0, numElements # XXX Delta from pypy.module.oracle import interp_cursor - if space.is_true(space.isinstance( # XXX is there an easier way? + if space.isinstance_w( # XXX is there an easier way? w_value, - space.gettypeobject(interp_cursor.W_Cursor.typedef))): + space.gettypeobject(interp_cursor.W_Cursor.typedef)): return VT_Cursor, 0, numElements - if space.is_true(space.isinstance(w_value, get(space).w_DecimalType)): + if space.isinstance_w(w_value, get(space).w_DecimalType): return VT_NumberAsString, 0, numElements # handle arrays - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): elements_w = space.listview(w_value) for w_element in elements_w: if not space.is_w(w_element, space.w_None): @@ -1497,8 +1496,7 @@ space.wrap(cursor), w_value, space.wrap(numElements)) - if not space.is_true(space.isinstance(w_var, - get(space).w_Variable)): + if not space.isinstance_w(w_var, get(space).w_Variable): raise OperationError( space.w_TypeError, space.wrap("expecting variable from input type handler")) @@ -1519,7 +1517,7 @@ if space.is_w(var, space.w_None): varType, size, numElements = typeByValue(space, w_value, numElements) var = varType(cursor, numElements, size) - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): var.makeArray(space) assert isinstance(var, W_Variable) @@ -1539,7 +1537,7 @@ def newVariableByType(space, cursor, w_value, numElements): # passing an integer is assumed to be a string - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): size = space.int_w(w_value) if size > config.MAX_STRING_CHARS: varType = VT_LongString @@ -1548,12 +1546,11 @@ return varType(cursor, numElements, size) # passing an array of two elements define an array - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): return newArrayVariableByType(space, cursor, w_value) # handle directly bound variables - if space.is_true(space.isinstance(w_value, - get(space).w_Variable)): + if space.isinstance_w(w_value, get(space).w_Variable): return space.interp_w(W_Variable, w_value) # everything else ought to be a Python type diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1080,6 +1080,7 @@ func = declare_new_w_star(name) globals()[name] = func + @unwrap_spec(fd=c_int) def ttyname(space, fd): try: @@ -1087,9 +1088,10 @@ except OSError, e: raise wrap_oserror(space, e) + def confname_w(space, w_name, namespace): # XXX slightly non-nice, reuses the sysconf of the underlying os module - if space.is_true(space.isinstance(w_name, space.w_basestring)): + if space.isinstance_w(w_name, space.w_basestring): try: num = namespace[space.str_w(w_name)] except KeyError: diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -796,7 +796,7 @@ Return a new XML parser object.""" if space.is_none(w_encoding): encoding = None - elif space.is_true(space.isinstance(w_encoding, space.w_str)): + elif space.isinstance_w(w_encoding, space.w_str): encoding = space.str_w(w_encoding) else: type_name = space.type(w_encoding).getname(space) @@ -807,7 +807,7 @@ if space.is_none(w_namespace_separator): namespace_separator = 0 - elif space.is_true(space.isinstance(w_namespace_separator, space.w_str)): + elif space.isinstance_w(w_namespace_separator, space.w_str): separator = space.str_w(w_namespace_separator) if len(separator) == 0: namespace_separator = 0 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 @@ -83,7 +83,7 @@ def _maybe_float(self, w_obj): space = self.space - if space.is_true(space.isinstance(w_obj, space.w_float)): + if space.isinstance_w(w_obj, space.w_float): msg = "struct: integer argument expected, got float" else: msg = "integer argument expected, got non-integer" diff --git a/pypy/module/termios/interp_termios.py b/pypy/module/termios/interp_termios.py --- a/pypy/module/termios/interp_termios.py +++ b/pypy/module/termios/interp_termios.py @@ -24,7 +24,7 @@ w_builtin = space.getbuiltinmodule('__builtin__') cc = [] for w_c in space.unpackiterable(w_cc): - if space.is_true(space.isinstance(w_c, space.w_int)): + if space.isinstance_w(w_c, space.w_int): ch = space.call_function(space.getattr(w_builtin, space.wrap('chr')), w_c) cc.append(space.str_w(ch)) diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py --- a/pypy/module/thread/os_thread.py +++ b/pypy/module/thread/os_thread.py @@ -146,6 +146,7 @@ space.threadlocals.setup_threads(space) bootstrapper.setup(space) + def reinit_threads(space): "Called in the child process after a fork()" space.threadlocals.reinit_threads(space) @@ -167,10 +168,10 @@ when the function raises an unhandled exception; a stack trace will be printed unless the exception is SystemExit.""" setup_threads(space) - if not space.is_true(space.isinstance(w_args, space.w_tuple)): + if not space.isinstance_w(w_args, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("2nd arg must be a tuple")) - if w_kwargs is not None and not space.is_true(space.isinstance(w_kwargs, space.w_dict)): + if w_kwargs is not None and not space.isinstance_w(w_kwargs, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("optional 3rd arg must be a dictionary")) if not space.is_true(space.callable(w_callable)): diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -33,7 +33,7 @@ if MAXUNICODE > 0xFFFF: # Target is wide build def unichr_to_code_w(space, w_unichr): - if not space.is_true(space.isinstance(w_unichr, space.w_unicode)): + if not space.isinstance_w(w_unichr, space.w_unicode): raise OperationError(space.w_TypeError, space.wrap( 'argument 1 must be unicode')) @@ -53,7 +53,7 @@ else: # Target is narrow build def unichr_to_code_w(space, w_unichr): - if not space.is_true(space.isinstance(w_unichr, space.w_unicode)): + if not space.isinstance_w(w_unichr, space.w_unicode): raise OperationError(space.w_TypeError, space.wrap( 'argument 1 must be unicode')) @@ -178,7 +178,7 @@ @unwrap_spec(form=str) def normalize(self, space, form, w_unistr): - if not space.is_true(space.isinstance(w_unistr, space.w_unicode)): + if not space.isinstance_w(w_unistr, space.w_unicode): raise OperationError(space.w_TypeError, space.wrap('argument 2 must be unicode')) if form == 'NFC': composed = True diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -363,7 +363,7 @@ "'%s' object does not define __format__", typename) w_res = space.get_and_call_function(w_descr, w_obj, w_format_spec) - if not space.is_true(space.isinstance(w_res, space.w_basestring)): + if not space.isinstance_w(w_res, space.w_basestring): typename = space.type(w_obj).getname(space) restypename = space.type(w_res).getname(space) raise operationerrfmt(space.w_TypeError, @@ -453,10 +453,10 @@ return w_result elif space.is_w(w_resulttype, space.w_long): return space.hash(w_result) - elif space.is_true(space.isinstance(w_result, space.w_int)): + elif space.isinstance_w(w_result, space.w_int): # be careful about subclasses of 'int'... return space.wrap(space.int_w(w_result)) - elif space.is_true(space.isinstance(w_result, space.w_long)): + elif space.isinstance_w(w_result, space.w_long): # be careful about subclasses of 'long'... bigint = space.bigint_w(w_result) return space.wrap(bigint.hash()) @@ -507,12 +507,12 @@ if w_res is None or space.is_w(w_res, space.w_None): raise OperationError(space.w_TypeError, space.wrap("coercion failed")) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) or + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2): raise OperationError(space.w_TypeError, space.wrap("coercion should return None or 2-tuple")) w_res = space.newtuple([space.getitem(w_res, space.wrap(1)), space.getitem(w_res, space.wrap(0))]) - elif (not space.is_true(space.isinstance(w_res, space.w_tuple)) or + elif (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2): raise OperationError(space.w_TypeError, space.wrap("coercion should return None or 2-tuple")) @@ -522,8 +522,12 @@ return space._type_issubtype(w_sub, w_type) @specialize.arg_or_var(2) + def isinstance_w(space, w_inst, w_type): + return space._type_isinstance(w_inst, w_type) + + @specialize.arg_or_var(2) def isinstance(space, w_inst, w_type): - return space.wrap(space._type_isinstance(w_inst, w_type)) + return space.wrap(space.isinstance_w(w_inst, w_type)) def issubtype_allow_override(space, w_sub, w_type): w_check = space.lookup(w_type, "__subclasscheck__") @@ -809,7 +813,7 @@ ('long', '__long__', ("space.w_int", "space.w_long")), ('float', '__float__', ("space.w_float",))]: - l = ["space.is_true(space.isinstance(w_result, %s))" % x + l = ["space.isinstance_w(w_result, %s)" % x for x in checkerspec] checker = " or ".join(l) source = """if 1: @@ -849,7 +853,7 @@ typename) w_result = space.get_and_call_function(w_impl, w_obj) - if space.is_true(space.isinstance(w_result, space.w_str)): + if space.isinstance_w(w_result, space.w_str): return w_result try: result = space.str_w(w_result) diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -99,7 +99,6 @@ class FakeObjSpace(ObjSpace): - def __init__(self, config=None): self._seen_extras = [] ObjSpace.__init__(self, config=config) @@ -242,6 +241,11 @@ def type(self, w_obj): return w_some_type() + def isinstance_w(self, w_inst, w_type): + is_root(w_inst) + is_root(w_type) + return NonConstant(True) + def unpackiterable(self, w_iterable, expected_length=-1): is_root(w_iterable) if expected_length < 0: diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -616,10 +616,6 @@ return True return self.type(w_inst).issubtype(w_type) - @specialize.arg_or_var(2) - def isinstance_w(space, w_inst, w_type): - return space._type_isinstance(w_inst, w_type) - def setup_isinstance_cache(self): # This assumes that all classes in the stdobjspace implementing a # particular app-level type are distinguished by a common base class. diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -1,14 +1,13 @@ +import sys import py -import sys -from pypy.interpreter.error import OperationError -from pypy.objspace.std.dictmultiobject import \ - W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \ - StringDictStrategy, ObjectDictStrategy -class TestW_DictObject: +from pypy.objspace.std.dictmultiobject import (W_DictMultiObject, + setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, StringDictStrategy, + ObjectDictStrategy) + +class TestW_DictObject(object): def test_empty(self): - space = self.space d = self.space.newdict() assert not self.space.is_true(d) assert type(d.strategy) is not ObjectDictStrategy @@ -895,6 +894,7 @@ return str return type(w_obj) w_str = str + def str_w(self, string): assert isinstance(string, str) return string @@ -906,8 +906,9 @@ def wrap(self, obj): return obj - def isinstance(self, obj, klass): + def isinstance_w(self, obj, klass): return isinstance(obj, klass) + isinstance = isinstance_w def newtuple(self, l): return tuple(l) diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py --- a/pypy/tool/pytest/appsupport.py +++ b/pypy/tool/pytest/appsupport.py @@ -206,7 +206,7 @@ self.type, self.value, self.traceback = sys.exc_info() return _ExceptionInfo -""") +""") try: return space.call_function(space._w_ExceptionInfo) finally: @@ -215,7 +215,7 @@ def pypyraises(space, w_ExpectedException, w_expr, __args__): """A built-in function providing the equivalent of py.test.raises().""" args_w, kwds_w = __args__.unpack() - if space.is_true(space.isinstance(w_expr, space.w_str)): + if space.isinstance_w(w_expr, space.w_str): if args_w: raise OperationError(space.w_TypeError, space.wrap("raises() takes no argument " From noreply at buildbot.pypy.org Sat Mar 23 05:54:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 05:54:41 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_gateway Message-ID: <20130323045441.E33571C15A3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62685:61814711d83a Date: 2013-03-22 21:54 -0700 http://bitbucket.org/pypy/pypy/changeset/61814711d83a/ Log: fix test_gateway 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 @@ -24,8 +24,12 @@ assert code.signature() == Signature(['x', 'y'], 'hello', None) def d(self, w_boo): pass + + class W_X(W_Root): + pass + code = gateway.BuiltinCode(d, unwrap_spec= ['self', - gateway.W_Root], self_type=gateway.W_Root) + gateway.W_Root], self_type=W_X) assert code.signature() == Signature(['self', 'boo'], None, None) def e(space, w_x, w_y, __args__): pass From noreply at buildbot.pypy.org Sat Mar 23 05:58:07 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 05:58:07 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): fix blatant typo Message-ID: <20130323045807.297681C15A4@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62686:17f998ffa9a3 Date: 2013-03-22 21:57 -0700 http://bitbucket.org/pypy/pypy/changeset/17f998ffa9a3/ Log: (alex, fijal): fix blatant typo diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -166,8 +166,8 @@ selected_reg=selected_reg) return reg - def get_free_reg(): - free_regs = self.free_regs + def get_free_reg(self): + free_regs = self.free_regs for i in range(len(free_regs), -1, -1): if free_regs[i] in self.save_around_call_regs: continue @@ -365,7 +365,7 @@ # ------------------------------------------------------------ def perform_llong(self, op, args, fcond): return self.assembler.regalloc_emit_llong(op, args, fcond, self) - + def perform_math(self, op, args, fcond): return self.assembler.regalloc_emit_math(op, args, self, fcond) @@ -442,7 +442,7 @@ res = self.force_allocate_reg(op.result) self.possibly_free_var(op.result) return [reg1, reg2, res] - + def prepare_op_int_force_ge_zero(self, op, fcond): argloc = self.make_sure_var_in_reg(op.getarg(0)) resloc = self.force_allocate_reg(op.result, [op.getarg(0)]) From noreply at buildbot.pypy.org Sat Mar 23 06:00:47 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 06:00:47 +0100 (CET) Subject: [pypy-commit] pypy default: random whitespace fixes Message-ID: <20130323050047.B3E941C15A3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62687:b8ad9699db5c Date: 2013-03-22 22:00 -0700 http://bitbucket.org/pypy/pypy/changeset/b8ad9699db5c/ Log: random whitespace fixes diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -257,6 +257,7 @@ selected_reg) else: return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg) + def get_free_reg(self): return self.rm.get_free_reg() @@ -287,8 +288,7 @@ operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables - longevity, last_real_usage = compute_vars_longevity( - inputargs, operations) + longevity, last_real_usage = compute_vars_longevity(inputargs, operations) self.longevity = longevity self.last_real_usage = last_real_usage fm = self.frame_manager @@ -588,7 +588,6 @@ res = self.force_allocate_reg(op.result) return [loc0, res] - def _prepare_guard(self, op, args=None): if args is None: args = [] @@ -664,8 +663,7 @@ return arglocs def prepare_op_guard_no_exception(self, op, fcond): - loc = self.make_sure_var_in_reg( - ConstInt(self.cpu.pos_exception())) + loc = self.make_sure_var_in_reg(ConstInt(self.cpu.pos_exception())) arglocs = self._prepare_guard(op, [loc]) return arglocs @@ -1019,7 +1017,6 @@ def prepare_op_call_malloc_nursery_varsize_small(self, op, fcond): size_box = op.getarg(0) assert isinstance(size_box, BoxInt) - size = size_box.getint() self.rm.force_allocate_reg(op.result, selected_reg=r.r0) t = TempInt() @@ -1121,8 +1118,7 @@ prepare_op_float_add = prepare_float_op(name='prepare_op_float_add') prepare_op_float_sub = prepare_float_op(name='prepare_op_float_sub') prepare_op_float_mul = prepare_float_op(name='prepare_op_float_mul') - prepare_op_float_truediv = prepare_float_op( - name='prepare_op_float_truediv') + prepare_op_float_truediv = prepare_float_op(name='prepare_op_float_truediv') prepare_op_float_lt = prepare_float_op(float_result=False, name='prepare_op_float_lt') prepare_op_float_le = prepare_float_op(float_result=False, From noreply at buildbot.pypy.org Sat Mar 23 06:07:51 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 06:07:51 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): fix obvious typo Message-ID: <20130323050751.0FA8C1C15A5@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62688:8cc0faa67469 Date: 2013-03-22 22:07 -0700 http://bitbucket.org/pypy/pypy/changeset/8cc0faa67469/ Log: (alex, fijal): fix obvious typo diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -168,7 +168,7 @@ def get_free_reg(self): free_regs = self.free_regs - for i in range(len(free_regs), -1, -1): + for i in range(len(free_regs) - 1, -1, -1): if free_regs[i] in self.save_around_call_regs: continue return free_regs[i] From noreply at buildbot.pypy.org Sat Mar 23 07:58:30 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 07:58:30 +0100 (CET) Subject: [pypy-commit] pypy default: further optimize RStringIO by splitting write into fast/slow helper functions. the fast path is now truly as fast as StringBuilder alone. Message-ID: <20130323065830.E68CB1C1456@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62689:e0174cd99015 Date: 2013-03-23 01:33 -0400 http://bitbucket.org/pypy/pypy/changeset/e0174cd99015/ Log: further optimize RStringIO by splitting write into fast/slow helper functions. the fast path is now truly as fast as StringBuilder alone. diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -58,41 +58,44 @@ # Idea: for the common case of a sequence of write() followed # by only getvalue(), self.bigbuffer remains empty. It is only # used to handle the more complicated cases. - p = self.pos - if p != AT_END: # slow or semi-fast paths - assert p >= 0 - endp = p + len(buffer) - if self.bigbuffer is not None and len(self.bigbuffer) >= endp: - # semi-fast path: the write is entirely inside self.bigbuffer - for i in range(len(buffer)): - self.bigbuffer[p + i] = buffer[i] - self.pos = endp - return - else: - # slow path: collect all data into self.bigbuffer and - # handle the various cases - self.copy_into_bigbuffer() - fitting = len(self.bigbuffer) - p - if fitting > 0: - # the write starts before the end of the data - fitting = min(len(buffer), fitting) - for i in range(fitting): - self.bigbuffer[p+i] = buffer[i] - if len(buffer) > fitting: - # the write extends beyond the end of the data - self.bigbuffer += buffer[fitting:] - endp = AT_END - self.pos = endp - return - else: - # the write starts at or beyond the end of the data - self.bigbuffer += '\x00' * (-fitting) - self.pos = AT_END # fall-through to the fast path - # Fast path. + if self.pos == AT_END: + self._fast_write(buffer) + else: + self._slow_write(buffer) + + def _fast_write(self, buffer): if self.strings is None: self.strings = StringBuilder() self.strings.append(buffer) + def _slow_write(self, buffer): + p = self.pos + assert p >= 0 + endp = p + len(buffer) + if self.bigbuffer is not None and len(self.bigbuffer) >= endp: + # semi-fast path: the write is entirely inside self.bigbuffer + for i in range(len(buffer)): + self.bigbuffer[p + i] = buffer[i] + else: + # slow path: collect all data into self.bigbuffer and + # handle the various cases + self.copy_into_bigbuffer() + fitting = len(self.bigbuffer) - p + if fitting > 0: + # the write starts before the end of the data + fitting = min(len(buffer), fitting) + for i in range(fitting): + self.bigbuffer[p + i] = buffer[i] + if len(buffer) > fitting: + # the write extends beyond the end of the data + self.bigbuffer += buffer[fitting:] + endp = AT_END + else: + # the write starts at or beyond the end of the data + self.bigbuffer += '\x00' * (-fitting) + buffer + endp = AT_END + self.pos = endp + def seek(self, position, mode=0): if mode == 1: if self.pos == AT_END: From noreply at buildbot.pypy.org Sat Mar 23 07:58:32 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 07:58:32 +0100 (CET) Subject: [pypy-commit] pypy default: prefix this RStringIO internal function with underscore Message-ID: <20130323065832.2BAF81C1456@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62690:1778c83c7eb0 Date: 2013-03-23 02:52 -0400 http://bitbucket.org/pypy/pypy/changeset/1778c83c7eb0/ Log: prefix this RStringIO internal function with underscore diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -28,11 +28,19 @@ def is_closed(self): return self.closed + def _copy_into_bigbuffer(self): + """Copy all the data into the list of characters self.bigbuffer.""" + if self.bigbuffer is None: + self.bigbuffer = [] + if self.strings is not None: + self.bigbuffer += self.strings.build() + self.strings = None + def getvalue(self): """If self.strings contains more than 1 string, join all the strings together. Return the final single string.""" if self.bigbuffer is not None: - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() return ''.join(self.bigbuffer) if self.strings is not None: return self.strings.build() @@ -46,14 +54,6 @@ result += self.strings.getlength() return result - def copy_into_bigbuffer(self): - """Copy all the data into the list of characters self.bigbuffer.""" - if self.bigbuffer is None: - self.bigbuffer = [] - if self.strings is not None: - self.bigbuffer += self.strings.build() - self.strings = None - def write(self, buffer): # Idea: for the common case of a sequence of write() followed # by only getvalue(), self.bigbuffer remains empty. It is only @@ -79,7 +79,7 @@ else: # slow path: collect all data into self.bigbuffer and # handle the various cases - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() fitting = len(self.bigbuffer) - p if fitting > 0: # the write starts before the end of the data @@ -126,7 +126,7 @@ if p == AT_END or n == 0: return '' assert p >= 0 - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() mysize = len(self.bigbuffer) count = mysize - p if n >= 0: @@ -145,7 +145,7 @@ if p == AT_END or size == 0: return '' assert p >= 0 - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() end = len(self.bigbuffer) if size >= 0 and size < end - p: end = p + size @@ -164,7 +164,7 @@ # position to the end. assert size >= 0 if self.bigbuffer is None or size > len(self.bigbuffer): - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() else: # we can drop all extra strings if self.strings is not None: From noreply at buildbot.pypy.org Sat Mar 23 07:58:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 07:58:33 +0100 (CET) Subject: [pypy-commit] pypy default: switch pickle/cPickle back to using cStringIO now that it's as fast as StringBuilder (removing pypy modifications of stdlib) Message-ID: <20130323065833.67F491C1456@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62691:ab34cd919592 Date: 2013-03-21 03:21 -0400 http://bitbucket.org/pypy/pypy/changeset/ab34cd919592/ Log: switch pickle/cPickle back to using cStringIO now that it's as fast as StringBuilder (removing pypy modifications of stdlib) diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1409,26 +1409,11 @@ except ImportError: from StringIO import StringIO -try: - from __pypy__.builders import StringBuilder -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO -else: - class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - self.getvalue = self.builder.build - def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -97,18 +97,12 @@ from pickle import StringIO -try: - from pickle import StringBuilderFile -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO - PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringBuilderFile() + self.__f = StringIO() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) @@ -126,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() From noreply at buildbot.pypy.org Sat Mar 23 11:26:00 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 11:26:00 +0100 (CET) Subject: [pypy-commit] pypy default: rStringIO reset pos on close, test Message-ID: <20130323102600.77C971C1527@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62692:632c98832fb6 Date: 2013-03-23 06:25 -0400 http://bitbucket.org/pypy/pypy/changeset/632c98832fb6/ Log: rStringIO reset pos on close, test diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -24,6 +24,7 @@ self.closed = True self.strings = None self.bigbuffer = None + self.pos = AT_END def is_closed(self): return self.closed diff --git a/rpython/rlib/test/test_rStringIO.py b/rpython/rlib/test/test_rStringIO.py --- a/rpython/rlib/test/test_rStringIO.py +++ b/rpython/rlib/test/test_rStringIO.py @@ -49,6 +49,10 @@ assert f.tell() == i assert f.getvalue() == '01XXXXXXXXXXXXXXXXX' + f.seek(1) + f.close() + assert f.tell() == 0 + def test_read(): f = RStringIO() assert f.read() == '' From noreply at buildbot.pypy.org Sat Mar 23 16:08:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Mar 2013 16:08:06 +0100 (CET) Subject: [pypy-commit] pypy.org extradoc: Add a general flattr button. Message-ID: <20130323150806.270C71C106C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r379:0b69490cfc12 Date: 2013-03-23 16:07 +0100 http://bitbucket.org/pypy/pypy.org/changeset/0b69490cfc12/ Log: Add a general flattr button. diff --git a/archive.html b/archive.html --- a/archive.html +++ b/archive.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/compat.html b/compat.html --- a/compat.html +++ b/compat.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/contact.html b/contact.html --- a/contact.html +++ b/contact.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/download.html b/download.html --- a/download.html +++ b/download.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/features.html b/features.html --- a/features.html +++ b/features.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/howtohelp.html b/howtohelp.html --- a/howtohelp.html +++ b/howtohelp.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/index.html b/index.html --- a/index.html +++ b/index.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/numpydonate.html b/numpydonate.html --- a/numpydonate.html +++ b/numpydonate.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
@@ -65,7 +67,7 @@ at the latest, we will try our best to make PyPy support NumPy anyway. We however reserve the right to shift any unused funds to other PyPy activities when that date is reached. Of course, since the Conservancy is a -501(c)(3) charitable organization incorporated in NY, USA, all funds will, +501©(3) charitable organization incorporated in NY, USA, all funds will, regardless of their use, be spent in a way that benefits the general public, the advancement of Open Source and Free Software, and in particular the PyPy community and the PyPy codebase.

diff --git a/people.html b/people.html --- a/people.html +++ b/people.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/performance.html b/performance.html --- a/performance.html +++ b/performance.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/py3donate.html b/py3donate.html --- a/py3donate.html +++ b/py3donate.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/source/_layouts/site.genshi b/source/_layouts/site.genshi --- a/source/_layouts/site.genshi +++ b/source/_layouts/site.genshi @@ -68,6 +68,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/sponsor.html b/sponsor.html --- a/sponsor.html +++ b/sponsor.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/success.html b/success.html --- a/success.html +++ b/success.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
diff --git a/tmdonate.html b/tmdonate.html --- a/tmdonate.html +++ b/tmdonate.html @@ -35,6 +35,8 @@
Follow the conversation on Twitter
Subscribe to the RSS Feed
+
From noreply at buildbot.pypy.org Sat Mar 23 18:30:22 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 18:30:22 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): removed float_w multimethod Message-ID: <20130323173022.B49821C016E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62693:9bdbaa4b41e9 Date: 2013-03-23 10:29 -0700 http://bitbucket.org/pypy/pypy/changeset/9bdbaa4b41e9/ Log: (alex, fijal): removed float_w multimethod diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -211,6 +211,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def float_w(self, space): + raise OperationError(space.w_TypeError, + typed_unwrap_error_msg(space, "float", self)) + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -1308,6 +1312,9 @@ def bigint_w(self, w_obj): return w_obj.bigint_w(self) + def float_w(self, w_obj): + return w_obj.float_w(self) + def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. if not self.is_true(self.isinstance(w_obj, self.w_str)): @@ -1670,4 +1677,4 @@ 'newslice', 'call_args', 'marshal_w', - ] +] diff --git a/pypy/objspace/std/default.py b/pypy/objspace/std/default.py --- a/pypy/objspace/std/default.py +++ b/pypy/objspace/std/default.py @@ -1,6 +1,5 @@ """Default implementation for some operation.""" -from pypy.interpreter.error import OperationError, typed_unwrap_error_msg from pypy.objspace.std.register_all import register_all @@ -9,8 +8,4 @@ def init__ANY(space, w_obj, __args__): pass -def float_w__ANY(space,w_obj): - raise OperationError(space.w_TypeError, - typed_unwrap_error_msg(space, "float", w_obj)) - register_all(vars()) diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -55,6 +55,9 @@ def unwrap(w_self, space): return w_self.floatval + def float_w(self, space): + return self.floatval + def __repr__(self): return "" % self.floatval @@ -114,9 +117,6 @@ else: return space.newint(value) -def float_w__Float(space, w_float): - return w_float.floatval - def _char_from_hex(number): return "0123456789abcdef"[number] 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 @@ -64,6 +64,9 @@ def bigint_w(w_self, space): return rbigint.fromint(w_self.intval) + def float_w(self, space): + return float(self.intval) + registerimplementation(W_IntObject) # NB: This code is shared by smallintobject.py, and thus no other Int diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py --- a/pypy/objspace/std/longobject.py +++ b/pypy/objspace/std/longobject.py @@ -84,6 +84,9 @@ def bigint_w(w_self, space): return w_self.num + def float_w(self, space): + return self.num.tofloat() + def __repr__(self): return '' % self.num.tolong() 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 @@ -436,7 +436,6 @@ init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) # special visible multimethods - float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float # NOTE: when adding more sometype_w() methods, you need to write a # stub in default.py to raise a space.w_TypeError marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) @@ -449,4 +448,3 @@ del mm pow.extras['defaults'] = (None,) - diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py --- a/pypy/objspace/std/smalllongobject.py +++ b/pypy/objspace/std/smalllongobject.py @@ -66,6 +66,10 @@ def bigint_w(w_self, space): return w_self.asbigint() + def float_w(self, space): + return float(self.longlong) + + registerimplementation(W_SmallLongObject) # ____________________________________________________________ From noreply at buildbot.pypy.org Sat Mar 23 18:30:24 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 18:30:24 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130323173024.1EA891C016E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62694:a36881021f46 Date: 2013-03-23 10:30 -0700 http://bitbucket.org/pypy/pypy/changeset/a36881021f46/ Log: merged upstream diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1409,26 +1409,11 @@ except ImportError: from StringIO import StringIO -try: - from __pypy__.builders import StringBuilder -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO -else: - class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - self.getvalue = self.builder.build - def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -97,18 +97,12 @@ from pickle import StringIO -try: - from pickle import StringBuilderFile -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO - PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringBuilderFile() + self.__f = StringIO() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) @@ -126,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -24,15 +24,24 @@ self.closed = True self.strings = None self.bigbuffer = None + self.pos = AT_END def is_closed(self): return self.closed + def _copy_into_bigbuffer(self): + """Copy all the data into the list of characters self.bigbuffer.""" + if self.bigbuffer is None: + self.bigbuffer = [] + if self.strings is not None: + self.bigbuffer += self.strings.build() + self.strings = None + def getvalue(self): """If self.strings contains more than 1 string, join all the strings together. Return the final single string.""" if self.bigbuffer is not None: - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() return ''.join(self.bigbuffer) if self.strings is not None: return self.strings.build() @@ -46,53 +55,48 @@ result += self.strings.getlength() return result - def copy_into_bigbuffer(self): - """Copy all the data into the list of characters self.bigbuffer.""" - if self.bigbuffer is None: - self.bigbuffer = [] - if self.strings is not None: - self.bigbuffer += self.strings.build() - self.strings = None - def write(self, buffer): # Idea: for the common case of a sequence of write() followed # by only getvalue(), self.bigbuffer remains empty. It is only # used to handle the more complicated cases. - p = self.pos - if p != AT_END: # slow or semi-fast paths - assert p >= 0 - endp = p + len(buffer) - if self.bigbuffer is not None and len(self.bigbuffer) >= endp: - # semi-fast path: the write is entirely inside self.bigbuffer - for i in range(len(buffer)): - self.bigbuffer[p + i] = buffer[i] - self.pos = endp - return - else: - # slow path: collect all data into self.bigbuffer and - # handle the various cases - self.copy_into_bigbuffer() - fitting = len(self.bigbuffer) - p - if fitting > 0: - # the write starts before the end of the data - fitting = min(len(buffer), fitting) - for i in range(fitting): - self.bigbuffer[p+i] = buffer[i] - if len(buffer) > fitting: - # the write extends beyond the end of the data - self.bigbuffer += buffer[fitting:] - endp = AT_END - self.pos = endp - return - else: - # the write starts at or beyond the end of the data - self.bigbuffer += '\x00' * (-fitting) - self.pos = AT_END # fall-through to the fast path - # Fast path. + if self.pos == AT_END: + self._fast_write(buffer) + else: + self._slow_write(buffer) + + def _fast_write(self, buffer): if self.strings is None: self.strings = StringBuilder() self.strings.append(buffer) + def _slow_write(self, buffer): + p = self.pos + assert p >= 0 + endp = p + len(buffer) + if self.bigbuffer is not None and len(self.bigbuffer) >= endp: + # semi-fast path: the write is entirely inside self.bigbuffer + for i in range(len(buffer)): + self.bigbuffer[p + i] = buffer[i] + else: + # slow path: collect all data into self.bigbuffer and + # handle the various cases + self._copy_into_bigbuffer() + fitting = len(self.bigbuffer) - p + if fitting > 0: + # the write starts before the end of the data + fitting = min(len(buffer), fitting) + for i in range(fitting): + self.bigbuffer[p + i] = buffer[i] + if len(buffer) > fitting: + # the write extends beyond the end of the data + self.bigbuffer += buffer[fitting:] + endp = AT_END + else: + # the write starts at or beyond the end of the data + self.bigbuffer += '\x00' * (-fitting) + buffer + endp = AT_END + self.pos = endp + def seek(self, position, mode=0): if mode == 1: if self.pos == AT_END: @@ -123,7 +127,7 @@ if p == AT_END or n == 0: return '' assert p >= 0 - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() mysize = len(self.bigbuffer) count = mysize - p if n >= 0: @@ -142,7 +146,7 @@ if p == AT_END or size == 0: return '' assert p >= 0 - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() end = len(self.bigbuffer) if size >= 0 and size < end - p: end = p + size @@ -161,7 +165,7 @@ # position to the end. assert size >= 0 if self.bigbuffer is None or size > len(self.bigbuffer): - self.copy_into_bigbuffer() + self._copy_into_bigbuffer() else: # we can drop all extra strings if self.strings is not None: diff --git a/rpython/rlib/test/test_rStringIO.py b/rpython/rlib/test/test_rStringIO.py --- a/rpython/rlib/test/test_rStringIO.py +++ b/rpython/rlib/test/test_rStringIO.py @@ -49,6 +49,10 @@ assert f.tell() == i assert f.getvalue() == '01XXXXXXXXXXXXXXXXX' + f.seek(1) + f.close() + assert f.tell() == 0 + def test_read(): f = RStringIO() assert f.read() == '' From noreply at buildbot.pypy.org Sat Mar 23 18:39:44 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 18:39:44 +0100 (CET) Subject: [pypy-commit] pypy default: bools are also floats Message-ID: <20130323173944.878421C016E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62695:2b95d7427cbd Date: 2013-03-23 10:39 -0700 http://bitbucket.org/pypy/pypy/changeset/2b95d7427cbd/ Log: bools are also floats 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 @@ -10,28 +10,31 @@ from pypy.objspace.std.booltype import bool_typedef as typedef _immutable_fields_ = ['boolval'] - def __init__(w_self, boolval): - w_self.boolval = not not boolval + def __init__(self, boolval): + self.boolval = not not boolval - def __nonzero__(w_self): - raise Exception, "you cannot do that, you must use space.is_true()" + def __nonzero__(self): + raise Exception("you cannot do that, you must use space.is_true()") - def __repr__(w_self): + def __repr__(self): """ representation for debugging purposes """ - return "%s(%s)" % (w_self.__class__.__name__, w_self.boolval) + return "%s(%s)" % (self.__class__.__name__, self.boolval) - def unwrap(w_self, space): - return w_self.boolval + def unwrap(self, space): + return self.boolval - def int_w(w_self, space): - return int(w_self.boolval) + def int_w(self, space): + return int(self.boolval) - def uint_w(w_self, space): - intval = int(w_self.boolval) + def uint_w(self, space): + intval = int(self.boolval) return r_uint(intval) - def bigint_w(w_self, space): - return rbigint.fromint(int(w_self.boolval)) + def bigint_w(self, space): + return rbigint.fromint(int(self.boolval)) + + def float_w(self, space): + return float(self.boolval) registerimplementation(W_BoolObject) From noreply at buildbot.pypy.org Sat Mar 23 18:46:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 18:46:24 +0100 (CET) Subject: [pypy-commit] benchmarks default: add PYTHONPATH to translate Message-ID: <20130323174624.F00DA1C106C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r199:1d3fb65004f7 Date: 2013-03-23 10:46 -0700 http://bitbucket.org/pypy/benchmarks/changeset/1d3fb65004f7/ Log: add PYTHONPATH to translate diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -148,7 +148,7 @@ pypy-c-jit in the nightly benchmarks, we are not interested in ``changed_python`` (aka pypy-c-nojit) right now. """ - + options['bm_env']['PYTHONPATH'] = relative('lib/pypy') translate_py = relative('lib/pypy/rpython/bin/rpython') target = relative('lib/pypy/pypy/goal/targetpypystandalone.py') #targetnop = relative('lib/pypy/pypy/translator/goal/targetnopstandalone.py') From noreply at buildbot.pypy.org Sat Mar 23 18:48:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 18:48:28 +0100 (CET) Subject: [pypy-commit] benchmarks default: like this Message-ID: <20130323174828.82B491C016E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r200:485f81da89eb Date: 2013-03-23 10:48 -0700 http://bitbucket.org/pypy/benchmarks/changeset/485f81da89eb/ Log: like this diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -148,13 +148,14 @@ pypy-c-jit in the nightly benchmarks, we are not interested in ``changed_python`` (aka pypy-c-nojit) right now. """ - options['bm_env']['PYTHONPATH'] = relative('lib/pypy') translate_py = relative('lib/pypy/rpython/bin/rpython') target = relative('lib/pypy/pypy/goal/targetpypystandalone.py') #targetnop = relative('lib/pypy/pypy/translator/goal/targetnopstandalone.py') args = base_python + [translate_py, '--source', '--dont-write-c-files', '-O2', target] logging.info('Running %s', ' '.join(args)) - proc = subprocess.Popen(args, stderr=subprocess.PIPE) + environ = os.environ.copy() + environ['PYTHONPATH'] = relative('lib/pypy') + proc = subprocess.Popen(args, stderr=subprocess.PIPE, env=environ) out, err = proc.communicate() retcode = proc.poll() if retcode != 0: From noreply at buildbot.pypy.org Sat Mar 23 19:01:54 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Mar 2013 19:01:54 +0100 (CET) Subject: [pypy-commit] pypy default: the rpython pattern for getting sets is actually to use None as a key Message-ID: <20130323180154.B795C1C016E@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62696:b91a591ea2c0 Date: 2013-03-23 13:28 +0100 http://bitbucket.org/pypy/pypy/changeset/b91a591ea2c0/ Log: the rpython pattern for getting sets is actually to use None as a key 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 @@ -76,32 +76,32 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False assert isinstance(other, AbstractVirtualStructStateInfo) assert len(self.fielddescrs) == len(self.fieldstate) assert len(other.fielddescrs) == len(other.fieldstate) if len(self.fielddescrs) != len(other.fielddescrs): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for i in range(len(self.fielddescrs)): if other.fielddescrs[i] is not self.fielddescrs[i]: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.fieldstate[i].generalization_of(other.fieldstate[i], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -167,23 +167,23 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if len(self.fieldstate) != len(other.fieldstate): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for i in range(len(self.fieldstate)): if not self.fieldstate[i].generalization_of(other.fieldstate[i], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -222,36 +222,36 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False assert isinstance(other, VArrayStructStateInfo) if len(self.fielddescrs) != len(other.fielddescrs): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False p = 0 for i in range(len(self.fielddescrs)): if len(self.fielddescrs[i]) != len(other.fielddescrs[i]): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for j in range(len(self.fielddescrs[i])): if self.fielddescrs[i][j] is not other.fielddescrs[i][j]: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.fieldstate[p].generalization_of(other.fieldstate[p], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False p += 1 return True @@ -310,42 +310,42 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not isinstance(other, NotVirtualStateInfo): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if other.level < self.level: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if self.level == LEVEL_CONSTANT: if not self.constbox.same_constant(other.constbox): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False elif self.level == LEVEL_KNOWNCLASS: if not self.known_class.same_constant(other.known_class): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.intbound.contains_bound(other.intbound): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if self.lenbound and other.lenbound: if self.lenbound.mode != other.lenbound.mode or \ self.lenbound.descr != other.lenbound.descr or \ not self.lenbound.bound.contains_bound(other.lenbound.bound): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False elif self.lenbound: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True From noreply at buildbot.pypy.org Sat Mar 23 19:01:56 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Mar 2013 19:01:56 +0100 (CET) Subject: [pypy-commit] pypy default: use None for values in dicts that represent sets Message-ID: <20130323180156.05C4D1C016E@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r62697:5105b0e54476 Date: 2013-03-23 18:47 +0100 http://bitbucket.org/pypy/pypy/changeset/5105b0e54476/ Log: use None for values in dicts that represent sets diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -180,7 +180,7 @@ if self.boxes_created_this_iteration is not None: for box in self.inputargs: - self.boxes_created_this_iteration[box] = True + self.boxes_created_this_iteration[box] = None short_boxes = ShortBoxes(self.optimizer, inputargs, self.boxes_created_this_iteration) @@ -241,7 +241,7 @@ for box in self.inputargs: if box in seen: continue - seen[box] = True + seen[box] = None preamble_value = exported_state.exported_values[box] value = self.optimizer.getvalue(box) value.import_from(preamble_value, self.optimizer) @@ -291,7 +291,7 @@ i = 0 while i < len(newoperations): op = newoperations[i] - self.boxes_created_this_iteration[op.result] = True + self.boxes_created_this_iteration[op.result] = None args = op.getarglist() if op.is_guard(): args = args + op.getfailargs() @@ -363,7 +363,7 @@ else: op = newoperations[i] - self.boxes_created_this_iteration[op.result] = True + self.boxes_created_this_iteration[op.result] = None args = op.getarglist() if op.is_guard(): args = args + op.getfailargs() @@ -471,7 +471,7 @@ # self.optimizer.loop.logops.repr_of_resop(op)) optimizer.send_extra_operation(op) - seen[op.result] = True + seen[op.result] = None if op.is_ovf(): guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) optimizer.send_extra_operation(guard) @@ -498,7 +498,7 @@ value_guards = [] self.short.append(op) - self.short_seen[op.result] = True + self.short_seen[op.result] = None if emit and self.short_inliner: newop = self.short_inliner.inline_op(op) self.optimizer.send_extra_operation(newop) 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 @@ -663,7 +663,7 @@ raise BoxNotProducable if self.availible_boxes is not None and box not in self.availible_boxes: raise BoxNotProducable - self.short_boxes_in_production[box] = True + self.short_boxes_in_production[box] = None if box in self.potential_ops: ops = self.prioritized_alternatives(box) From noreply at buildbot.pypy.org Sat Mar 23 19:16:18 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 19:16:18 +0100 (CET) Subject: [pypy-commit] pypy default: remove inaccurate comment Message-ID: <20130323181618.45AA11C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62698:5ec2a7b19989 Date: 2013-03-23 11:15 -0700 http://bitbucket.org/pypy/pypy/changeset/5ec2a7b19989/ Log: remove inaccurate comment diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1501,9 +1501,9 @@ dummy_lock = DummyLock() -## Table describing the regular part of the interface of object spaces, -## namely all methods which only take w_ arguments and return a w_ result -## (if any). Note: keep in sync with rpython.flowspace.operation.Table. +# Table describing the regular part of the interface of object spaces, +# namely all methods which only take w_ arguments and return a w_ result +# (if any). ObjSpace.MethodTable = [ # method name # symbol # number of arguments # special method name(s) From noreply at buildbot.pypy.org Sat Mar 23 19:16:19 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 19:16:19 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130323181619.AAAF41C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62699:24594993c81f Date: 2013-03-23 11:16 -0700 http://bitbucket.org/pypy/pypy/changeset/24594993c81f/ Log: merged upstream diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -180,7 +180,7 @@ if self.boxes_created_this_iteration is not None: for box in self.inputargs: - self.boxes_created_this_iteration[box] = True + self.boxes_created_this_iteration[box] = None short_boxes = ShortBoxes(self.optimizer, inputargs, self.boxes_created_this_iteration) @@ -241,7 +241,7 @@ for box in self.inputargs: if box in seen: continue - seen[box] = True + seen[box] = None preamble_value = exported_state.exported_values[box] value = self.optimizer.getvalue(box) value.import_from(preamble_value, self.optimizer) @@ -291,7 +291,7 @@ i = 0 while i < len(newoperations): op = newoperations[i] - self.boxes_created_this_iteration[op.result] = True + self.boxes_created_this_iteration[op.result] = None args = op.getarglist() if op.is_guard(): args = args + op.getfailargs() @@ -363,7 +363,7 @@ else: op = newoperations[i] - self.boxes_created_this_iteration[op.result] = True + self.boxes_created_this_iteration[op.result] = None args = op.getarglist() if op.is_guard(): args = args + op.getfailargs() @@ -471,7 +471,7 @@ # self.optimizer.loop.logops.repr_of_resop(op)) optimizer.send_extra_operation(op) - seen[op.result] = True + seen[op.result] = None if op.is_ovf(): guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) optimizer.send_extra_operation(guard) @@ -498,7 +498,7 @@ value_guards = [] self.short.append(op) - self.short_seen[op.result] = True + self.short_seen[op.result] = None if emit and self.short_inliner: newop = self.short_inliner.inline_op(op) self.optimizer.send_extra_operation(newop) 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 @@ -76,32 +76,32 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False assert isinstance(other, AbstractVirtualStructStateInfo) assert len(self.fielddescrs) == len(self.fieldstate) assert len(other.fielddescrs) == len(other.fieldstate) if len(self.fielddescrs) != len(other.fielddescrs): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for i in range(len(self.fielddescrs)): if other.fielddescrs[i] is not self.fielddescrs[i]: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.fieldstate[i].generalization_of(other.fieldstate[i], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -167,23 +167,23 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if len(self.fieldstate) != len(other.fieldstate): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for i in range(len(self.fieldstate)): if not self.fieldstate[i].generalization_of(other.fieldstate[i], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -222,36 +222,36 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False assert isinstance(other, VArrayStructStateInfo) if len(self.fielddescrs) != len(other.fielddescrs): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False p = 0 for i in range(len(self.fielddescrs)): if len(self.fielddescrs[i]) != len(other.fielddescrs[i]): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for j in range(len(self.fielddescrs[i])): if self.fielddescrs[i][j] is not other.fielddescrs[i][j]: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.fieldstate[p].generalization_of(other.fieldstate[p], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False p += 1 return True @@ -310,42 +310,42 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not isinstance(other, NotVirtualStateInfo): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if other.level < self.level: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if self.level == LEVEL_CONSTANT: if not self.constbox.same_constant(other.constbox): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False elif self.level == LEVEL_KNOWNCLASS: if not self.known_class.same_constant(other.known_class): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.intbound.contains_bound(other.intbound): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if self.lenbound and other.lenbound: if self.lenbound.mode != other.lenbound.mode or \ self.lenbound.descr != other.lenbound.descr or \ not self.lenbound.bound.contains_bound(other.lenbound.bound): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False elif self.lenbound: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -663,7 +663,7 @@ raise BoxNotProducable if self.availible_boxes is not None and box not in self.availible_boxes: raise BoxNotProducable - self.short_boxes_in_production[box] = True + self.short_boxes_in_production[box] = None if box in self.potential_ops: ops = self.prioritized_alternatives(box) From noreply at buildbot.pypy.org Sat Mar 23 20:02:09 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 20:02:09 +0100 (CET) Subject: [pypy-commit] pypy default: (fijal, alex) kill 'int' as a multimethod Message-ID: <20130323190209.6105D1C016E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62700:e258f1470515 Date: 2013-03-23 12:01 -0700 http://bitbucket.org/pypy/pypy/changeset/e258f1470515/ Log: (fijal, alex) kill 'int' as a multimethod diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -189,11 +189,6 @@ BoolOption("withtproxy", "support transparent proxies", default=True), - BoolOption("withsmallint", "use tagged integers", - default=False, - requires=[("objspace.std.withprebuiltint", False), - ("translation.taggedpointers", True)]), - BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -204,9 +199,7 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False, - requires=[("objspace.std.withsmallint", False)]), - # ^^^ because of missing delegate_xx2yy + default=False), BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -223,6 +223,22 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def int(self, space): + w_impl = space.lookup(self, '__int__') + if w_impl is None: + typename = space.type(self).getname(space) + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for int(): '%s'", + typename) + w_result = space.get_and_call_function(w_impl, self) + + if (space.isinstance_w(w_result, space.w_int) or + space.isinstance_w(w_result, space.w_long)): + return w_result + typename = space.type(w_result).getname(space) + msg = "__int__ returned non-int (type '%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) + def __spacebind__(self, space): return self @@ -1306,6 +1322,9 @@ def int_w(self, w_obj): return w_obj.int_w(self) + def int(self, w_obj): + return w_obj.int(self) + def uint_w(self, w_obj): return w_obj.uint_w(self) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -808,7 +808,6 @@ # more of the above manually-coded operations as well) for targetname, specialname, checkerspec in [ - ('int', '__int__', ("space.w_int", "space.w_long")), ('index', '__index__', ("space.w_int", "space.w_long")), ('long', '__long__', ("space.w_int", "space.w_long")), ('float', '__float__', ("space.w_float",))]: diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -111,6 +111,9 @@ return w_result + def int(self, space): + raise OperationError(space.w_TypeError, space.wrap("can't convert complex to int; use int(abs(z))")) + registerimplementation(W_ComplexObject) w_one = W_ComplexObject(1, 0) @@ -245,9 +248,6 @@ def float__Complex(space, w_complex): raise OperationError(space.w_TypeError, space.wrap("can't convert complex to float; use abs(z)")) -def int__Complex(space, w_complex): - raise OperationError(space.w_TypeError, space.wrap("can't convert complex to int; use int(abs(z))")) - def complex_conjugate__Complex(space, w_self): #w_real = space.call_function(space.w_float,space.wrap(w_self.realval)) #w_imag = space.call_function(space.w_float,space.wrap(-w_self.imagval)) diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -58,6 +58,14 @@ def float_w(self, space): return self.floatval + def int(self, space): + try: + value = ovfcheck_float_to_int(self.floatval) + except OverflowError: + return space.long(self) + else: + return space.newint(value) + def __repr__(self): return "" % self.floatval @@ -89,14 +97,6 @@ a = w_float1.floatval return W_FloatObject(a) -def int__Float(space, w_value): - try: - value = ovfcheck_float_to_int(w_value.floatval) - except OverflowError: - return space.long(w_value) - else: - return space.newint(value) - def long__Float(space, w_floatobj): try: return W_LongObject.fromfloat(space, w_floatobj.floatval) diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py --- a/pypy/objspace/std/frame.py +++ b/pypy/objspace/std/frame.py @@ -6,7 +6,7 @@ from pypy.interpreter import pyopcode from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.error import OperationError -from pypy.objspace.std import intobject, smallintobject +from pypy.objspace.std import intobject from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.listobject import W_ListObject @@ -23,20 +23,6 @@ raise AssertionError -def small_int_BINARY_ADD(f, oparg, next_instr): - w_2 = f.popvalue() - w_1 = f.popvalue() - if (type(w_1) is smallintobject.W_SmallIntObject and - type(w_2) is smallintobject.W_SmallIntObject): - try: - w_result = smallintobject.add__SmallInt_SmallInt(f.space, w_1, w_2) - except FailedToImplement: - w_result = f.space.add(w_1, w_2) - else: - w_result = f.space.add(w_1, w_2) - f.pushvalue(w_result) - - def int_BINARY_ADD(f, oparg, next_instr): w_2 = f.popvalue() w_1 = f.popvalue() @@ -102,10 +88,7 @@ class StdObjSpaceFrame(BaseFrame): pass if space.config.objspace.std.optimized_int_add: - if space.config.objspace.std.withsmallint: - StdObjSpaceFrame.BINARY_ADD = small_int_BINARY_ADD - else: - StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD + StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD if space.config.objspace.std.optimized_list_getitem: StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR if space.config.objspace.opcodes.CALL_METHOD: 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 @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std import newformat -from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.inttype import wrapint, W_AbstractIntObject from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject @@ -16,25 +16,6 @@ something CPython does not do anymore. """ -class W_AbstractIntObject(W_Object): - __slots__ = () - - def is_w(self, space, w_other): - if not isinstance(w_other, W_AbstractIntObject): - return False - if self.user_overridden_class or w_other.user_overridden_class: - return self is w_other - return space.int_w(self) == space.int_w(w_other) - - def immutable_unique_id(self, space): - if self.user_overridden_class: - return None - from pypy.objspace.std.model import IDTAG_INT as tag - b = space.bigint_w(self) - b = b.lshift(3).or_(rbigint.fromint(tag)) - return space.newlong_from_rbigint(b) - - class W_IntObject(W_AbstractIntObject): __slots__ = 'intval' _immutable_fields_ = ['intval'] @@ -67,6 +48,17 @@ def float_w(self, space): return float(self.intval) + def int(self, space): + # XXX find a better way to do it + if (type(self) != W_IntObject and + space.lookup(self, '__int__') is not + space.lookup_in_type_where(space.w_int, '__int__')[1]): + return W_Object.int(self, space) + if space.is_w(space.type(self), space.w_int): + return self + a = self.intval + return wrapint(space, a) + registerimplementation(W_IntObject) # NB: This code is shared by smallintobject.py, and thus no other Int @@ -104,7 +96,7 @@ # unlike CPython, we don't special-case the value -1 in most of our # hash functions, so there is not much sense special-casing it here either. # Make sure this is consistent with the hash of floats and longs. - return get_integer(space, w_int1) + return w_int1.int(space) # coerce def coerce__Int_Int(space, w_int1, w_int2): @@ -251,7 +243,7 @@ def abs__Int(space, w_int1): if w_int1.intval >= 0: - return get_integer(space, w_int1) + return w_int1.int(space) else: return get_negint(space, w_int1) @@ -278,7 +270,7 @@ space.wrap("negative shift count")) else: #b >= LONG_BIT if a == 0: - return get_integer(space, w_int1) + return w_int1.int(space) raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer left shift")) @@ -291,7 +283,7 @@ space.wrap("negative shift count")) else: # b >= LONG_BIT if a == 0: - return get_integer(space, w_int1) + return w_int1.int(space) if a < 0: a = -1 else: @@ -321,17 +313,13 @@ # int__Int is supposed to do nothing, unless it has # a derived integer object, where it should return # an exact one. -def int__Int(space, w_int1): - if space.is_w(space.type(w_int1), space.w_int): - return w_int1 - a = w_int1.intval - return wrapint(space, a) -get_integer = int__Int -pos__Int = int__Int -trunc__Int = int__Int + +def pos__Int(self, space): + return self.int(space) +trunc__Int = pos__Int def index__Int(space, w_int1): - return get_integer(space, w_int1) + return w_int1.int(space) def float__Int(space, w_int1): a = w_int1.intval diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py --- a/pypy/objspace/std/inttype.py +++ b/pypy/objspace/std/inttype.py @@ -1,5 +1,6 @@ from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault,\ + interpindirect2app from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.buffer import Buffer from pypy.objspace.std.register_all import register_all @@ -7,8 +8,10 @@ from pypy.objspace.std.strutil import (string_to_int, string_to_bigint, ParseStringError, ParseStringOverflowError) +from pypy.objspace.std.model import W_Object from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import instantiate +from rpython.rlib.rbigint import rbigint # ____________________________________________________________ @@ -36,14 +39,7 @@ def wrapint(space, x): - if space.config.objspace.std.withsmallint: - from pypy.objspace.std.smallintobject import W_SmallIntObject - try: - return W_SmallIntObject(x) - except OverflowError: - from pypy.objspace.std.intobject import W_IntObject - return W_IntObject(x) - elif space.config.objspace.std.withprebuiltint: + if space.config.objspace.std.withprebuiltint: from pypy.objspace.std.intobject import W_IntObject lower = space.config.objspace.std.prebuiltintfrom upper = space.config.objspace.std.prebuiltintto @@ -185,6 +181,27 @@ # ____________________________________________________________ +class W_AbstractIntObject(W_Object): + __slots__ = () + + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractIntObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + return space.int_w(self) == space.int_w(w_other) + + def immutable_unique_id(self, space): + if self.user_overridden_class: + return None + from pypy.objspace.std.model import IDTAG_INT as tag + b = space.bigint_w(self) + b = b.lshift(3).or_(rbigint.fromint(tag)) + return space.newlong_from_rbigint(b) + + def int(self, space): + raise NotImplementedError + int_typedef = StdTypeDef("int", __doc__ = '''int(x[, base]) -> integer @@ -201,5 +218,6 @@ denominator = typedef.GetSetProperty(descr_get_denominator), real = typedef.GetSetProperty(descr_get_real), imag = typedef.GetSetProperty(descr_get_imag), + __int__ = interpindirect2app(W_AbstractIntObject.int), ) int_typedef.registermethods(globals()) diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py --- a/pypy/objspace/std/longobject.py +++ b/pypy/objspace/std/longobject.py @@ -87,6 +87,12 @@ def float_w(self, space): return self.num.tofloat() + def int(self, space): + try: + return space.newint(self.num.toint()) + except OverflowError: + return long__Long(space, self) + def __repr__(self): return '' % self.num.tolong() @@ -130,12 +136,6 @@ def long__Int(space, w_intobj): return space.newlong(w_intobj.intval) -def int__Long(space, w_value): - try: - return space.newint(w_value.num.toint()) - except OverflowError: - return long__Long(space, w_value) - def index__Long(space, w_value): return long__Long(space, w_value) 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 @@ -17,7 +17,6 @@ option_to_typename = { "withspecialisedtuple" : ["specialisedtupleobject.W_SpecialisedTupleObject"], "withsmalltuple" : ["smalltupleobject.W_SmallTupleObject"], - "withsmallint" : ["smallintobject.W_SmallIntObject"], "withsmalllong" : ["smalllongobject.W_SmallLongObject"], "withstrbuf" : ["strbufobject.W_StringBufferObject"], } @@ -158,18 +157,6 @@ # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later - if config.objspace.std.withsmallint: - from pypy.objspace.std import smallintobject - self.typeorder[boolobject.W_BoolObject] += [ - (smallintobject.W_SmallIntObject, boolobject.delegate_Bool2SmallInt), - ] - self.typeorder[smallintobject.W_SmallIntObject] += [ - (intobject.W_IntObject, smallintobject.delegate_SmallInt2Int), - (floatobject.W_FloatObject, smallintobject.delegate_SmallInt2Float), - (longobject.W_LongObject, smallintobject.delegate_SmallInt2Long), - (complexobject.W_ComplexObject, smallintobject.delegate_SmallInt2Complex), - ] - if config.objspace.usemodules.micronumpy: from pypy.module.micronumpy.stdobjspace import register_delegates register_delegates(self.typeorder) @@ -424,7 +411,7 @@ ['delattr', 'delete', 'get', 'id', 'inplace_div', 'inplace_floordiv', 'inplace_lshift', 'inplace_mod', 'inplace_pow', 'inplace_rshift', 'inplace_truediv', 'is_', 'set', 'setattr', 'type', 'userdel', - 'isinstance', 'issubtype']) + 'isinstance', 'issubtype', 'int']) # XXX should we just remove those from the method table or we're happy # with just not having multimethods? @@ -442,7 +429,7 @@ # add all regular multimethods here for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if _name not in locals() or _name in NOT_MULTIMETHODS: + if _name not in locals() and _name not in NOT_MULTIMETHODS: mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) locals()[_name] = mm del mm diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -26,7 +26,6 @@ from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject from pypy.objspace.std.sliceobject import W_SliceObject -from pypy.objspace.std.smallintobject import W_SmallIntObject from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std.tupleobject import W_AbstractTupleObject @@ -580,16 +579,8 @@ self.setitem(w_obj, self.wrap(key), w_value) def getindex_w(self, w_obj, w_exception, objdescr=None): - # Performance shortcut for the common case of w_obj being an int. - # If withsmallint is disabled, we check for W_IntObject. - # If withsmallint is enabled, we only check for W_SmallIntObject - it's - # probably not useful to have a shortcut for W_IntObject at all then. - if self.config.objspace.std.withsmallint: - if type(w_obj) is W_SmallIntObject: - return w_obj.intval - else: - if type(w_obj) is W_IntObject: - return w_obj.intval + if type(w_obj) is W_IntObject: + return w_obj.intval return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr) def call_method(self, w_obj, methname, *arg_w): diff --git a/pypy/objspace/std/smallintobject.py b/pypy/objspace/std/smallintobject.py deleted file mode 100644 --- a/pypy/objspace/std/smallintobject.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -Implementation of small ints, stored as odd-valued pointers in the -translated PyPy. To enable them, see inttype.py. -""" -from pypy.objspace.std import intobject -from pypy.objspace.std.model import registerimplementation, W_Object -from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject -from pypy.interpreter.error import OperationError -from rpython.rlib.objectmodel import UnboxedValue -from rpython.rlib.rbigint import rbigint -from rpython.rlib.rarithmetic import r_uint -from rpython.tool.sourcetools import func_with_new_name -from pypy.objspace.std.inttype import wrapint - -class W_SmallIntObject(W_AbstractIntObject, UnboxedValue): - __slots__ = 'intval' - from pypy.objspace.std.inttype import int_typedef as typedef - - def unwrap(w_self, space): - return int(w_self.intval) - int_w = unwrap - - def uint_w(w_self, space): - intval = w_self.intval - if intval < 0: - raise OperationError(space.w_ValueError, - space.wrap("cannot convert negative integer to unsigned")) - else: - return r_uint(intval) - - def bigint_w(w_self, space): - return rbigint.fromint(w_self.intval) - - -registerimplementation(W_SmallIntObject) - - -def delegate_SmallInt2Int(space, w_small): - return W_IntObject(w_small.intval) - -def delegate_SmallInt2Long(space, w_small): - return space.newlong(w_small.intval) - -def delegate_SmallInt2Float(space, w_small): - return space.newfloat(float(w_small.intval)) - -def delegate_SmallInt2Complex(space, w_small): - return space.newcomplex(float(w_small.intval), 0.0) - -def add__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval + w_b.intval) # cannot overflow - -def sub__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval - w_b.intval) # cannot overflow - -def floordiv__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval // w_b.intval) # cannot overflow - -div__SmallInt_SmallInt = floordiv__SmallInt_SmallInt - -def mod__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval % w_b.intval) # cannot overflow - -def divmod__SmallInt_SmallInt(space, w_a, w_b): - w = wrapint(space, w_a.intval // w_b.intval) # cannot overflow - z = wrapint(space, w_a.intval % w_b.intval) - return space.newtuple([w, z]) - -def copy_multimethods(ns): - """Copy integer multimethods for small int.""" - for name, func in intobject.__dict__.iteritems(): - if "__Int" in name: - new_name = name.replace("Int", "SmallInt") - if new_name not in ns: - # Copy the function, so the annotator specializes it for - # W_SmallIntObject. - ns[new_name] = func = func_with_new_name(func, new_name, globals=ns) - else: - ns[name] = func - ns["get_integer"] = ns["pos__SmallInt"] = ns["int__SmallInt"] - ns["get_negint"] = ns["neg__SmallInt"] - -copy_multimethods(globals()) - -register_all(vars()) diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py --- a/pypy/objspace/std/smalllongobject.py +++ b/pypy/objspace/std/smalllongobject.py @@ -69,7 +69,15 @@ def float_w(self, space): return float(self.longlong) + def int(self, space): + a = self.longlong + b = intmask(a) + if b == a: + return space.newint(b) + else: + return self + registerimplementation(W_SmallLongObject) # ____________________________________________________________ @@ -119,14 +127,6 @@ def long__SmallLong(space, w_value): return w_value -def int__SmallLong(space, w_value): - a = w_value.longlong - b = intmask(a) - if b == a: - return space.newint(b) - else: - return w_value - def index__SmallLong(space, w_value): return w_value 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 @@ -268,7 +268,7 @@ def test_int(self): f1 = iobj.W_IntObject(1) - result = iobj.int__Int(self.space, f1) + result = f1.int(self.space) assert result == f1 def test_oct(self): diff --git a/pypy/objspace/std/test/test_smallintobject.py b/pypy/objspace/std/test/test_smallintobject.py deleted file mode 100644 --- a/pypy/objspace/std/test/test_smallintobject.py +++ /dev/null @@ -1,229 +0,0 @@ -import sys, py - -#from pypy.objspace.std.model import WITHSMALLINT -#if not WITHSMALLINT: -# py.test.skip("WITHSMALLINT is not enabled") - -from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.multimethod import FailedToImplement -from rpython.rlib.rarithmetic import r_uint - -from pypy.objspace.std.test.test_intobject import AppTestInt - -class TestW_IntObject: - spaceconfig = {"objspace.std.withsmallint": True} - - def test_int_w(self): - assert self.space.int_w(self.space.wrap(42)) == 42 - - def test_uint_w(self): - space = self.space - assert space.uint_w(space.wrap(42)) == 42 - assert isinstance(space.uint_w(space.wrap(42)), r_uint) - space.raises_w(space.w_ValueError, space.uint_w, space.wrap(-1)) - - def test_repr(self): - x = 1 - f1 = wrapint(self.space, x) - result = self.space.repr(f1) - assert self.space.unwrap(result) == repr(x) - - def test_str(self): - x = 12345 - f1 = wrapint(self.space, x) - result = self.space.str(f1) - assert self.space.unwrap(result) == str(x) - - def test_hash(self): - x = 42 - f1 = wrapint(self.space, x) - result = self.space.hash(f1) - assert result.intval == hash(x) - - def test_compare(self): - import operator - optab = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] - for x in (-10, -1, 0, 1, 2, 1000, sys.maxint): - for y in (-sys.maxint-1, -11, -9, -2, 0, 1, 3, 1111, sys.maxint): - for op in optab: - wx = wrapint(self.space, x) - wy = wrapint(self.space, y) - res = getattr(operator, op)(x, y) - method = getattr(self.space, op) - myres = method(wx, wy) - assert self.space.unwrap(myres) == res - - def test_add(self): - for x in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - for y in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - result = self.space.unwrap(self.space.add(f1, f2)) - assert result == x+y - - def test_sub(self): - for x in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - for y in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - result = self.space.unwrap(self.space.sub(f1, f2)) - assert result == x-y - - def test_mul(self): - for x in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]: - for y in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]: - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - result = self.space.unwrap(self.space.mul(f1, f2)) - assert result == x*y - - - def test_div(self): - for i in range(10): - res = i//3 - f1 = wrapint(self.space, i) - f2 = wrapint(self.space, 3) - result = self.space.div(f1, f2) - assert result.intval == res - - def test_mod(self): - x = 1 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.mod(f1, f2) - assert v.intval == x % y - # not that mod cannot overflow - - def test_divmod(self): - x = 1 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - ret = self.space.divmod(f1, f2) - v, w = self.space.unwrap(ret) - assert (v, w) == divmod(x, y) - - def test_pow_iii(self): - x = 10 - y = 2 - z = 13 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - f3 = wrapint(self.space, z) - v = self.space.pow(f1, f2, f3) - assert v.intval == pow(x, y, z) - f1, f2, f3 = [wrapint(self.space, i) for i in (10, -1, 42)] - self.space.raises_w(self.space.w_TypeError, - self.space.pow, - f1, f2, f3) - f1, f2, f3 = [wrapint(self.space, i) for i in (10, 5, 0)] - self.space.raises_w(self.space.w_ValueError, - self.space.pow, - f1, f2, f3) - - def test_pow_iin(self): - x = 10 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.pow(f1, f2, self.space.w_None) - assert v.intval == x ** y - - def test_neg(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.neg(f1) - assert v.intval == -x - - def test_pos(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.pos(f1) - assert v.intval == +x - x = -42 - f1 = wrapint(self.space, x) - v = self.space.pos(f1) - assert v.intval == +x - - def test_abs(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.abs(f1) - assert v.intval == abs(x) - x = -42 - f1 = wrapint(self.space, x) - v = self.space.abs(f1) - assert v.intval == abs(x) - - def test_invert(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.invert(f1) - assert v.intval == ~x - - def test_lshift(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.lshift(f1, f2) - assert v.intval == x << y - - def test_rshift(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.rshift(f1, f2) - assert v.intval == x >> y - - def test_and(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.and_(f1, f2) - assert v.intval == x & y - - def test_xor(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.xor(f1, f2) - assert v.intval == x ^ y - - def test_or(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.or_(f1, f2) - assert v.intval == x | y - - def test_int(self): - f1 = wrapint(self.space, 1) - result = self.space.int(f1) - assert result == f1 - - def test_oct(self): - x = 012345 - f1 = wrapint(self.space, x) - result = self.space.oct(f1) - assert self.space.unwrap(result) == oct(x) - - def test_hex(self): - x = 0x12345 - f1 = wrapint(self.space, x) - result = self.space.hex(f1) - assert self.space.unwrap(result) == hex(x) - - -class AppTestSmallInt(AppTestInt): - spaceconfig = {"objspace.std.optimized_int_add" : True, - "objspace.std.withsmallint" : True} diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -857,12 +857,6 @@ def _pure_issubtype(w_sub, w_type, version_tag1, version_tag2): return _issubtype(w_sub, w_type) -def issubtype__Type_Type(space, w_type, w_sub): - return space.newbool(w_sub.issubtype(w_type)) - -def isinstance__Type_ANY(space, w_type, w_inst): - return space.newbool(space.type(w_inst).issubtype(w_type)) - def repr__Type(space, w_obj): w_mod = w_obj.get_module() if not space.isinstance_w(w_mod, space.w_str): From noreply at buildbot.pypy.org Sat Mar 23 20:02:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 20:02:10 +0100 (CET) Subject: [pypy-commit] pypy default: merge default Message-ID: <20130323190210.CBF441C016E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62701:8b0ce43d0de4 Date: 2013-03-23 12:01 -0700 http://bitbucket.org/pypy/pypy/changeset/8b0ce43d0de4/ Log: merge default diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1520,9 +1520,9 @@ dummy_lock = DummyLock() -## Table describing the regular part of the interface of object spaces, -## namely all methods which only take w_ arguments and return a w_ result -## (if any). Note: keep in sync with rpython.flowspace.operation.Table. +# Table describing the regular part of the interface of object spaces, +# namely all methods which only take w_ arguments and return a w_ result +# (if any). ObjSpace.MethodTable = [ # method name # symbol # number of arguments # special method name(s) diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -180,7 +180,7 @@ if self.boxes_created_this_iteration is not None: for box in self.inputargs: - self.boxes_created_this_iteration[box] = True + self.boxes_created_this_iteration[box] = None short_boxes = ShortBoxes(self.optimizer, inputargs, self.boxes_created_this_iteration) @@ -241,7 +241,7 @@ for box in self.inputargs: if box in seen: continue - seen[box] = True + seen[box] = None preamble_value = exported_state.exported_values[box] value = self.optimizer.getvalue(box) value.import_from(preamble_value, self.optimizer) @@ -291,7 +291,7 @@ i = 0 while i < len(newoperations): op = newoperations[i] - self.boxes_created_this_iteration[op.result] = True + self.boxes_created_this_iteration[op.result] = None args = op.getarglist() if op.is_guard(): args = args + op.getfailargs() @@ -363,7 +363,7 @@ else: op = newoperations[i] - self.boxes_created_this_iteration[op.result] = True + self.boxes_created_this_iteration[op.result] = None args = op.getarglist() if op.is_guard(): args = args + op.getfailargs() @@ -471,7 +471,7 @@ # self.optimizer.loop.logops.repr_of_resop(op)) optimizer.send_extra_operation(op) - seen[op.result] = True + seen[op.result] = None if op.is_ovf(): guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) optimizer.send_extra_operation(guard) @@ -498,7 +498,7 @@ value_guards = [] self.short.append(op) - self.short_seen[op.result] = True + self.short_seen[op.result] = None if emit and self.short_inliner: newop = self.short_inliner.inline_op(op) self.optimizer.send_extra_operation(newop) 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 @@ -76,32 +76,32 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False assert isinstance(other, AbstractVirtualStructStateInfo) assert len(self.fielddescrs) == len(self.fieldstate) assert len(other.fielddescrs) == len(other.fieldstate) if len(self.fielddescrs) != len(other.fielddescrs): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for i in range(len(self.fielddescrs)): if other.fielddescrs[i] is not self.fielddescrs[i]: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.fieldstate[i].generalization_of(other.fieldstate[i], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -167,23 +167,23 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if len(self.fieldstate) != len(other.fieldstate): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for i in range(len(self.fieldstate)): if not self.fieldstate[i].generalization_of(other.fieldstate[i], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -222,36 +222,36 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not self._generalization_of(other): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False assert isinstance(other, VArrayStructStateInfo) if len(self.fielddescrs) != len(other.fielddescrs): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False p = 0 for i in range(len(self.fielddescrs)): if len(self.fielddescrs[i]) != len(other.fielddescrs[i]): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False for j in range(len(self.fielddescrs[i])): if self.fielddescrs[i][j] is not other.fielddescrs[i][j]: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.fieldstate[p].generalization_of(other.fieldstate[p], renum, bad): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False p += 1 return True @@ -310,42 +310,42 @@ if self.position in renum: if renum[self.position] == other.position: return True - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False renum[self.position] = other.position if not isinstance(other, NotVirtualStateInfo): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if other.level < self.level: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if self.level == LEVEL_CONSTANT: if not self.constbox.same_constant(other.constbox): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False elif self.level == LEVEL_KNOWNCLASS: if not self.known_class.same_constant(other.known_class): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if not self.intbound.contains_bound(other.intbound): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False if self.lenbound and other.lenbound: if self.lenbound.mode != other.lenbound.mode or \ self.lenbound.descr != other.lenbound.descr or \ not self.lenbound.bound.contains_bound(other.lenbound.bound): - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False elif self.lenbound: - bad[self] = True - bad[other] = True + bad[self] = None + bad[other] = None return False return True @@ -663,7 +663,7 @@ raise BoxNotProducable if self.availible_boxes is not None and box not in self.availible_boxes: raise BoxNotProducable - self.short_boxes_in_production[box] = True + self.short_boxes_in_production[box] = None if box in self.potential_ops: ops = self.prioritized_alternatives(box) From noreply at buildbot.pypy.org Sat Mar 23 20:06:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 20:06:04 +0100 (CET) Subject: [pypy-commit] pypy default: move hairy interface on space Message-ID: <20130323190604.556B71C106C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62702:7491137b9517 Date: 2013-03-23 12:05 -0700 http://bitbucket.org/pypy/pypy/changeset/7491137b9517/ Log: move hairy interface on space 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 @@ -49,10 +49,8 @@ return float(self.intval) def int(self, space): - # XXX find a better way to do it - if (type(self) != W_IntObject and - space.lookup(self, '__int__') is not - space.lookup_in_type_where(space.w_int, '__int__')[1]): + if type(self) != W_IntObject and space.is_overloaded(self, space.w_int, + '__int__'): return W_Object.int(self, space) if space.is_w(space.type(self), space.w_int): return self diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -669,3 +669,8 @@ if not hasattr(self, "_interplevel_classes"): return None # before running initialize return self._interplevel_classes.get(w_type, None) + + @specialize.arg(2, 3) + def is_overloaded(self, w_obj, tp, method): + return (self.lookup(w_obj, method) is not + self.lookup_in_type_where(tp, method)[1]) From noreply at buildbot.pypy.org Sat Mar 23 20:22:17 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 20:22:17 +0100 (CET) Subject: [pypy-commit] pypy default: fix translation Message-ID: <20130323192217.D3D3C1C165C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62703:c9e6b6819cbb Date: 2013-03-23 12:22 -0700 http://bitbucket.org/pypy/pypy/changeset/c9e6b6819cbb/ Log: fix translation diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -56,13 +56,13 @@ def nonzero(self): return self.space.wrap(bool(self._cdata)) - def int(self): - w_result = self.ctype.int(self._cdata) + def int(self, space): + w_result = self.ctype.cast_to_int(self._cdata) keepalive_until_here(self) return w_result - def long(self): - w_result = self.int() + def long(self, space): + w_result = self.int(space) space = self.space if space.is_w(space.type(w_result), space.w_int): w_result = space.newlong(space.int_w(w_result)) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -54,7 +54,7 @@ raise operationerrfmt(space.w_TypeError, "cannot cast to '%s'", self.name) - def int(self, cdata): + def cast_to_int(self, cdata): space = self.space raise operationerrfmt(space.w_TypeError, "int() not supported on cdata '%s'", self.name) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -99,7 +99,7 @@ _attrs_ = [] cast_anything = True - def int(self, cdata): + def cast_to_int(self, cdata): return self.space.wrap(ord(cdata[0])) def convert_to_object(self, cdata): @@ -124,7 +124,7 @@ class W_CTypePrimitiveUniChar(W_CTypePrimitiveCharOrUniChar): _attrs_ = [] - def int(self, cdata): + def cast_to_int(self, cdata): unichardata = rffi.cast(rffi.CWCHARP, cdata) return self.space.wrap(ord(unichardata[0])) @@ -168,7 +168,7 @@ self.vmin = r_uint(-1) << (sh - 1) self.vrangemax = (r_uint(1) << sh) - 1 - def int(self, cdata): + def cast_to_int(self, cdata): return self.convert_to_object(cdata) def convert_to_object(self, cdata): @@ -213,7 +213,7 @@ sh = self.size * 8 return (r_uint(1) << sh) - 1 - def int(self, cdata): + def cast_to_int(self, cdata): return self.convert_to_object(cdata) def convert_from_object(self, cdata, w_ob): @@ -288,7 +288,7 @@ keepalive_until_here(w_cdata) return w_cdata - def int(self, cdata): + def cast_to_int(self, cdata): w_value = self.float(cdata) return self.space.int(w_value) 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 @@ -36,6 +36,8 @@ def float_w(self, space): return float(self.boolval) + def int(self, space): + return self registerimplementation(W_BoolObject) 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 @@ -308,10 +308,6 @@ res = a | b return wrapint(space, res) -# int__Int is supposed to do nothing, unless it has -# a derived integer object, where it should return -# an exact one. - def pos__Int(self, space): return self.int(space) trunc__Int = pos__Int From noreply at buildbot.pypy.org Sat Mar 23 20:30:14 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 23 Mar 2013 20:30:14 +0100 (CET) Subject: [pypy-commit] pypy default: kill obsolete cache_building_mode thing Message-ID: <20130323193014.02CDE1C165C@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: Changeset: r62704:2d0b6d00f2f8 Date: 2013-03-23 19:28 +0000 http://bitbucket.org/pypy/pypy/changeset/2d0b6d00f2f8/ Log: kill obsolete cache_building_mode thing diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -277,18 +277,13 @@ def __init__(self, space): Cache.__init__(self) self.space = space + def _build(self, key): - val = self.space.enter_cache_building_mode() - try: - return self.build(key) - finally: - self.space.leave_cache_building_mode(val) + return self.build(key) + def _ready(self, result): - val = self.space.enter_cache_building_mode() - try: - return self.ready(result) - finally: - self.space.leave_cache_building_mode(val) + return self.ready(result) + def ready(self, result): pass @@ -577,11 +572,6 @@ """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" - def enter_cache_building_mode(self): - "hook for the flow object space" - def leave_cache_building_mode(self, val): - "hook for the flow object space" - @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." From noreply at buildbot.pypy.org Sat Mar 23 20:38:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 20:38:40 +0100 (CET) Subject: [pypy-commit] pypy default: fix translation Message-ID: <20130323193840.ADE2B1C165E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62705:97fea5c972a2 Date: 2013-03-23 12:35 -0700 http://bitbucket.org/pypy/pypy/changeset/97fea5c972a2/ Log: fix translation 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 @@ -49,8 +49,8 @@ return float(self.intval) def int(self, space): - if type(self) != W_IntObject and space.is_overloaded(self, space.w_int, - '__int__'): + if (type(self) is not W_IntObject and + space.is_overloaded(self, space.w_int, '__int__')): return W_Object.int(self, space) if space.is_w(space.type(self), space.w_int): return self From noreply at buildbot.pypy.org Sat Mar 23 20:38:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 20:38:42 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130323193842.067321C165E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62706:01dd3f95cc5e Date: 2013-03-23 12:38 -0700 http://bitbucket.org/pypy/pypy/changeset/01dd3f95cc5e/ Log: merge diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -277,18 +277,13 @@ def __init__(self, space): Cache.__init__(self) self.space = space + def _build(self, key): - val = self.space.enter_cache_building_mode() - try: - return self.build(key) - finally: - self.space.leave_cache_building_mode(val) + return self.build(key) + def _ready(self, result): - val = self.space.enter_cache_building_mode() - try: - return self.ready(result) - finally: - self.space.leave_cache_building_mode(val) + return self.ready(result) + def ready(self, result): pass @@ -577,11 +572,6 @@ """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" - def enter_cache_building_mode(self): - "hook for the flow object space" - def leave_cache_building_mode(self, val): - "hook for the flow object space" - @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." From noreply at buildbot.pypy.org Sat Mar 23 21:55:26 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 21:55:26 +0100 (CET) Subject: [pypy-commit] pypy default: revert the smallint changes Message-ID: <20130323205526.419181C1534@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62707:97b734570970 Date: 2013-03-23 13:54 -0700 http://bitbucket.org/pypy/pypy/changeset/97b734570970/ Log: revert the smallint changes diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -189,6 +189,11 @@ BoolOption("withtproxy", "support transparent proxies", default=True), + BoolOption("withsmallint", "use tagged integers", + default=False, + requires=[("objspace.std.withprebuiltint", False), + ("translation.taggedpointers", True)]), + BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -199,7 +204,9 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False), + default=False, + requires=[("objspace.std.withsmallint", False)]), + # ^^^ because of missing delegate_xx2yy BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py --- a/pypy/objspace/std/frame.py +++ b/pypy/objspace/std/frame.py @@ -6,7 +6,7 @@ from pypy.interpreter import pyopcode from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.error import OperationError -from pypy.objspace.std import intobject +from pypy.objspace.std import intobject, smallintobject from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.listobject import W_ListObject @@ -23,6 +23,20 @@ raise AssertionError +def small_int_BINARY_ADD(f, oparg, next_instr): + w_2 = f.popvalue() + w_1 = f.popvalue() + if (type(w_1) is smallintobject.W_SmallIntObject and + type(w_2) is smallintobject.W_SmallIntObject): + try: + w_result = smallintobject.add__SmallInt_SmallInt(f.space, w_1, w_2) + except FailedToImplement: + w_result = f.space.add(w_1, w_2) + else: + w_result = f.space.add(w_1, w_2) + f.pushvalue(w_result) + + def int_BINARY_ADD(f, oparg, next_instr): w_2 = f.popvalue() w_1 = f.popvalue() @@ -88,7 +102,10 @@ class StdObjSpaceFrame(BaseFrame): pass if space.config.objspace.std.optimized_int_add: - StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD + if space.config.objspace.std.withsmallint: + StdObjSpaceFrame.BINARY_ADD = small_int_BINARY_ADD + else: + StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD if space.config.objspace.std.optimized_list_getitem: StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR if space.config.objspace.opcodes.CALL_METHOD: diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py --- a/pypy/objspace/std/inttype.py +++ b/pypy/objspace/std/inttype.py @@ -39,7 +39,14 @@ def wrapint(space, x): - if space.config.objspace.std.withprebuiltint: + if space.config.objspace.std.withsmallint: + from pypy.objspace.std.smallintobject import W_SmallIntObject + try: + return W_SmallIntObject(x) + except OverflowError: + from pypy.objspace.std.intobject import W_IntObject + return W_IntObject(x) + elif space.config.objspace.std.withprebuiltint: from pypy.objspace.std.intobject import W_IntObject lower = space.config.objspace.std.prebuiltintfrom upper = space.config.objspace.std.prebuiltintto 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 @@ -17,6 +17,7 @@ option_to_typename = { "withspecialisedtuple" : ["specialisedtupleobject.W_SpecialisedTupleObject"], "withsmalltuple" : ["smalltupleobject.W_SmallTupleObject"], + "withsmallint" : ["smallintobject.W_SmallIntObject"], "withsmalllong" : ["smalllongobject.W_SmallLongObject"], "withstrbuf" : ["strbufobject.W_StringBufferObject"], } @@ -157,6 +158,18 @@ # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later + if config.objspace.std.withsmallint: + from pypy.objspace.std import smallintobject + self.typeorder[boolobject.W_BoolObject] += [ + (smallintobject.W_SmallIntObject, boolobject.delegate_Bool2SmallInt), + ] + self.typeorder[smallintobject.W_SmallIntObject] += [ + (intobject.W_IntObject, smallintobject.delegate_SmallInt2Int), + (floatobject.W_FloatObject, smallintobject.delegate_SmallInt2Float), + (longobject.W_LongObject, smallintobject.delegate_SmallInt2Long), + (complexobject.W_ComplexObject, smallintobject.delegate_SmallInt2Complex), + ] + if config.objspace.usemodules.micronumpy: from pypy.module.micronumpy.stdobjspace import register_delegates register_delegates(self.typeorder) diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -26,6 +26,7 @@ from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.smallintobject import W_SmallIntObject from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std.tupleobject import W_AbstractTupleObject @@ -579,8 +580,16 @@ self.setitem(w_obj, self.wrap(key), w_value) def getindex_w(self, w_obj, w_exception, objdescr=None): - if type(w_obj) is W_IntObject: - return w_obj.intval + # Performance shortcut for the common case of w_obj being an int. + # If withsmallint is disabled, we check for W_IntObject. + # If withsmallint is enabled, we only check for W_SmallIntObject - it's + # probably not useful to have a shortcut for W_IntObject at all then. + if self.config.objspace.std.withsmallint: + if type(w_obj) is W_SmallIntObject: + return w_obj.intval + else: + if type(w_obj) is W_IntObject: + return w_obj.intval return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr) def call_method(self, w_obj, methname, *arg_w): diff --git a/pypy/objspace/std/smallintobject.py b/pypy/objspace/std/smallintobject.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/std/smallintobject.py @@ -0,0 +1,87 @@ +""" +Implementation of small ints, stored as odd-valued pointers in the +translated PyPy. To enable them, see inttype.py. +""" +from pypy.objspace.std import intobject +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject +from pypy.interpreter.error import OperationError +from rpython.rlib.objectmodel import UnboxedValue +from rpython.rlib.rbigint import rbigint +from rpython.rlib.rarithmetic import r_uint +from rpython.tool.sourcetools import func_with_new_name +from pypy.objspace.std.inttype import wrapint + +class W_SmallIntObject(W_AbstractIntObject, UnboxedValue): + __slots__ = 'intval' + from pypy.objspace.std.inttype import int_typedef as typedef + + def unwrap(w_self, space): + return int(w_self.intval) + int_w = unwrap + + def uint_w(w_self, space): + intval = w_self.intval + if intval < 0: + raise OperationError(space.w_ValueError, + space.wrap("cannot convert negative integer to unsigned")) + else: + return r_uint(intval) + + def bigint_w(w_self, space): + return rbigint.fromint(w_self.intval) + + +registerimplementation(W_SmallIntObject) + + +def delegate_SmallInt2Int(space, w_small): + return W_IntObject(w_small.intval) + +def delegate_SmallInt2Long(space, w_small): + return space.newlong(w_small.intval) + +def delegate_SmallInt2Float(space, w_small): + return space.newfloat(float(w_small.intval)) + +def delegate_SmallInt2Complex(space, w_small): + return space.newcomplex(float(w_small.intval), 0.0) + +def add__SmallInt_SmallInt(space, w_a, w_b): + return wrapint(space, w_a.intval + w_b.intval) # cannot overflow + +def sub__SmallInt_SmallInt(space, w_a, w_b): + return wrapint(space, w_a.intval - w_b.intval) # cannot overflow + +def floordiv__SmallInt_SmallInt(space, w_a, w_b): + return wrapint(space, w_a.intval // w_b.intval) # cannot overflow + +div__SmallInt_SmallInt = floordiv__SmallInt_SmallInt + +def mod__SmallInt_SmallInt(space, w_a, w_b): + return wrapint(space, w_a.intval % w_b.intval) # cannot overflow + +def divmod__SmallInt_SmallInt(space, w_a, w_b): + w = wrapint(space, w_a.intval // w_b.intval) # cannot overflow + z = wrapint(space, w_a.intval % w_b.intval) + return space.newtuple([w, z]) + +def copy_multimethods(ns): + """Copy integer multimethods for small int.""" + for name, func in intobject.__dict__.iteritems(): + if "__Int" in name: + new_name = name.replace("Int", "SmallInt") + if new_name not in ns: + # Copy the function, so the annotator specializes it for + # W_SmallIntObject. + ns[new_name] = func = func_with_new_name(func, new_name, globals=ns) + else: + ns[name] = func + ns["get_integer"] = ns["pos__SmallInt"] = ns["int__SmallInt"] + ns["get_negint"] = ns["neg__SmallInt"] + +copy_multimethods(globals()) + +register_all(vars()) diff --git a/pypy/objspace/std/test/test_smallintobject.py b/pypy/objspace/std/test/test_smallintobject.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/std/test/test_smallintobject.py @@ -0,0 +1,229 @@ +import sys, py + +#from pypy.objspace.std.model import WITHSMALLINT +#if not WITHSMALLINT: +# py.test.skip("WITHSMALLINT is not enabled") + +from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.multimethod import FailedToImplement +from rpython.rlib.rarithmetic import r_uint + +from pypy.objspace.std.test.test_intobject import AppTestInt + +class TestW_IntObject: + spaceconfig = {"objspace.std.withsmallint": True} + + def test_int_w(self): + assert self.space.int_w(self.space.wrap(42)) == 42 + + def test_uint_w(self): + space = self.space + assert space.uint_w(space.wrap(42)) == 42 + assert isinstance(space.uint_w(space.wrap(42)), r_uint) + space.raises_w(space.w_ValueError, space.uint_w, space.wrap(-1)) + + def test_repr(self): + x = 1 + f1 = wrapint(self.space, x) + result = self.space.repr(f1) + assert self.space.unwrap(result) == repr(x) + + def test_str(self): + x = 12345 + f1 = wrapint(self.space, x) + result = self.space.str(f1) + assert self.space.unwrap(result) == str(x) + + def test_hash(self): + x = 42 + f1 = wrapint(self.space, x) + result = self.space.hash(f1) + assert result.intval == hash(x) + + def test_compare(self): + import operator + optab = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] + for x in (-10, -1, 0, 1, 2, 1000, sys.maxint): + for y in (-sys.maxint-1, -11, -9, -2, 0, 1, 3, 1111, sys.maxint): + for op in optab: + wx = wrapint(self.space, x) + wy = wrapint(self.space, y) + res = getattr(operator, op)(x, y) + method = getattr(self.space, op) + myres = method(wx, wy) + assert self.space.unwrap(myres) == res + + def test_add(self): + for x in [1, 100, sys.maxint // 2 - 50, + sys.maxint // 2, sys.maxint - 1000, sys.maxint]: + for y in [1, 100, sys.maxint // 2 - 50, + sys.maxint // 2, sys.maxint - 1000, sys.maxint]: + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + result = self.space.unwrap(self.space.add(f1, f2)) + assert result == x+y + + def test_sub(self): + for x in [1, 100, sys.maxint // 2 - 50, + sys.maxint // 2, sys.maxint - 1000, sys.maxint]: + for y in [1, 100, sys.maxint // 2 - 50, + sys.maxint // 2, sys.maxint - 1000, sys.maxint]: + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + result = self.space.unwrap(self.space.sub(f1, f2)) + assert result == x-y + + def test_mul(self): + for x in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]: + for y in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]: + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + result = self.space.unwrap(self.space.mul(f1, f2)) + assert result == x*y + + + def test_div(self): + for i in range(10): + res = i//3 + f1 = wrapint(self.space, i) + f2 = wrapint(self.space, 3) + result = self.space.div(f1, f2) + assert result.intval == res + + def test_mod(self): + x = 1 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.mod(f1, f2) + assert v.intval == x % y + # not that mod cannot overflow + + def test_divmod(self): + x = 1 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + ret = self.space.divmod(f1, f2) + v, w = self.space.unwrap(ret) + assert (v, w) == divmod(x, y) + + def test_pow_iii(self): + x = 10 + y = 2 + z = 13 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + f3 = wrapint(self.space, z) + v = self.space.pow(f1, f2, f3) + assert v.intval == pow(x, y, z) + f1, f2, f3 = [wrapint(self.space, i) for i in (10, -1, 42)] + self.space.raises_w(self.space.w_TypeError, + self.space.pow, + f1, f2, f3) + f1, f2, f3 = [wrapint(self.space, i) for i in (10, 5, 0)] + self.space.raises_w(self.space.w_ValueError, + self.space.pow, + f1, f2, f3) + + def test_pow_iin(self): + x = 10 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.pow(f1, f2, self.space.w_None) + assert v.intval == x ** y + + def test_neg(self): + x = 42 + f1 = wrapint(self.space, x) + v = self.space.neg(f1) + assert v.intval == -x + + def test_pos(self): + x = 42 + f1 = wrapint(self.space, x) + v = self.space.pos(f1) + assert v.intval == +x + x = -42 + f1 = wrapint(self.space, x) + v = self.space.pos(f1) + assert v.intval == +x + + def test_abs(self): + x = 42 + f1 = wrapint(self.space, x) + v = self.space.abs(f1) + assert v.intval == abs(x) + x = -42 + f1 = wrapint(self.space, x) + v = self.space.abs(f1) + assert v.intval == abs(x) + + def test_invert(self): + x = 42 + f1 = wrapint(self.space, x) + v = self.space.invert(f1) + assert v.intval == ~x + + def test_lshift(self): + x = 12345678 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.lshift(f1, f2) + assert v.intval == x << y + + def test_rshift(self): + x = 12345678 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.rshift(f1, f2) + assert v.intval == x >> y + + def test_and(self): + x = 12345678 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.and_(f1, f2) + assert v.intval == x & y + + def test_xor(self): + x = 12345678 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.xor(f1, f2) + assert v.intval == x ^ y + + def test_or(self): + x = 12345678 + y = 2 + f1 = wrapint(self.space, x) + f2 = wrapint(self.space, y) + v = self.space.or_(f1, f2) + assert v.intval == x | y + + def test_int(self): + f1 = wrapint(self.space, 1) + result = self.space.int(f1) + assert result == f1 + + def test_oct(self): + x = 012345 + f1 = wrapint(self.space, x) + result = self.space.oct(f1) + assert self.space.unwrap(result) == oct(x) + + def test_hex(self): + x = 0x12345 + f1 = wrapint(self.space, x) + result = self.space.hex(f1) + assert self.space.unwrap(result) == hex(x) + + +class AppTestSmallInt(AppTestInt): + spaceconfig = {"objspace.std.optimized_int_add" : True, + "objspace.std.withsmallint" : True} From noreply at buildbot.pypy.org Sat Mar 23 21:55:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 21:55:27 +0100 (CET) Subject: [pypy-commit] pypy default: Remove the smallintobject - it does not work with the JIT and it should Message-ID: <20130323205527.A257E1C15A1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62708:4ceef442528f Date: 2013-03-23 13:55 -0700 http://bitbucket.org/pypy/pypy/changeset/4ceef442528f/ Log: Remove the smallintobject - it does not work with the JIT and it should be reworked for the upcoming multimethod removal anyway. It's also not very useful in the presence of the JIT. diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -189,11 +189,6 @@ BoolOption("withtproxy", "support transparent proxies", default=True), - BoolOption("withsmallint", "use tagged integers", - default=False, - requires=[("objspace.std.withprebuiltint", False), - ("translation.taggedpointers", True)]), - BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -204,9 +199,7 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False, - requires=[("objspace.std.withsmallint", False)]), - # ^^^ because of missing delegate_xx2yy + default=False), BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py --- a/pypy/objspace/std/frame.py +++ b/pypy/objspace/std/frame.py @@ -6,7 +6,7 @@ from pypy.interpreter import pyopcode from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.error import OperationError -from pypy.objspace.std import intobject, smallintobject +from pypy.objspace.std import intobject from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.listobject import W_ListObject @@ -23,20 +23,6 @@ raise AssertionError -def small_int_BINARY_ADD(f, oparg, next_instr): - w_2 = f.popvalue() - w_1 = f.popvalue() - if (type(w_1) is smallintobject.W_SmallIntObject and - type(w_2) is smallintobject.W_SmallIntObject): - try: - w_result = smallintobject.add__SmallInt_SmallInt(f.space, w_1, w_2) - except FailedToImplement: - w_result = f.space.add(w_1, w_2) - else: - w_result = f.space.add(w_1, w_2) - f.pushvalue(w_result) - - def int_BINARY_ADD(f, oparg, next_instr): w_2 = f.popvalue() w_1 = f.popvalue() @@ -102,10 +88,7 @@ class StdObjSpaceFrame(BaseFrame): pass if space.config.objspace.std.optimized_int_add: - if space.config.objspace.std.withsmallint: - StdObjSpaceFrame.BINARY_ADD = small_int_BINARY_ADD - else: - StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD + StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD if space.config.objspace.std.optimized_list_getitem: StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR if space.config.objspace.opcodes.CALL_METHOD: diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py --- a/pypy/objspace/std/inttype.py +++ b/pypy/objspace/std/inttype.py @@ -39,14 +39,7 @@ def wrapint(space, x): - if space.config.objspace.std.withsmallint: - from pypy.objspace.std.smallintobject import W_SmallIntObject - try: - return W_SmallIntObject(x) - except OverflowError: - from pypy.objspace.std.intobject import W_IntObject - return W_IntObject(x) - elif space.config.objspace.std.withprebuiltint: + if space.config.objspace.std.withprebuiltint: from pypy.objspace.std.intobject import W_IntObject lower = space.config.objspace.std.prebuiltintfrom upper = space.config.objspace.std.prebuiltintto 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 @@ -17,7 +17,6 @@ option_to_typename = { "withspecialisedtuple" : ["specialisedtupleobject.W_SpecialisedTupleObject"], "withsmalltuple" : ["smalltupleobject.W_SmallTupleObject"], - "withsmallint" : ["smallintobject.W_SmallIntObject"], "withsmalllong" : ["smalllongobject.W_SmallLongObject"], "withstrbuf" : ["strbufobject.W_StringBufferObject"], } @@ -158,18 +157,6 @@ # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later - if config.objspace.std.withsmallint: - from pypy.objspace.std import smallintobject - self.typeorder[boolobject.W_BoolObject] += [ - (smallintobject.W_SmallIntObject, boolobject.delegate_Bool2SmallInt), - ] - self.typeorder[smallintobject.W_SmallIntObject] += [ - (intobject.W_IntObject, smallintobject.delegate_SmallInt2Int), - (floatobject.W_FloatObject, smallintobject.delegate_SmallInt2Float), - (longobject.W_LongObject, smallintobject.delegate_SmallInt2Long), - (complexobject.W_ComplexObject, smallintobject.delegate_SmallInt2Complex), - ] - if config.objspace.usemodules.micronumpy: from pypy.module.micronumpy.stdobjspace import register_delegates register_delegates(self.typeorder) diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -26,7 +26,6 @@ from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject from pypy.objspace.std.sliceobject import W_SliceObject -from pypy.objspace.std.smallintobject import W_SmallIntObject from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std.tupleobject import W_AbstractTupleObject @@ -580,16 +579,8 @@ self.setitem(w_obj, self.wrap(key), w_value) def getindex_w(self, w_obj, w_exception, objdescr=None): - # Performance shortcut for the common case of w_obj being an int. - # If withsmallint is disabled, we check for W_IntObject. - # If withsmallint is enabled, we only check for W_SmallIntObject - it's - # probably not useful to have a shortcut for W_IntObject at all then. - if self.config.objspace.std.withsmallint: - if type(w_obj) is W_SmallIntObject: - return w_obj.intval - else: - if type(w_obj) is W_IntObject: - return w_obj.intval + if type(w_obj) is W_IntObject: + return w_obj.intval return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr) def call_method(self, w_obj, methname, *arg_w): diff --git a/pypy/objspace/std/smallintobject.py b/pypy/objspace/std/smallintobject.py deleted file mode 100644 --- a/pypy/objspace/std/smallintobject.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -Implementation of small ints, stored as odd-valued pointers in the -translated PyPy. To enable them, see inttype.py. -""" -from pypy.objspace.std import intobject -from pypy.objspace.std.model import registerimplementation, W_Object -from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject -from pypy.interpreter.error import OperationError -from rpython.rlib.objectmodel import UnboxedValue -from rpython.rlib.rbigint import rbigint -from rpython.rlib.rarithmetic import r_uint -from rpython.tool.sourcetools import func_with_new_name -from pypy.objspace.std.inttype import wrapint - -class W_SmallIntObject(W_AbstractIntObject, UnboxedValue): - __slots__ = 'intval' - from pypy.objspace.std.inttype import int_typedef as typedef - - def unwrap(w_self, space): - return int(w_self.intval) - int_w = unwrap - - def uint_w(w_self, space): - intval = w_self.intval - if intval < 0: - raise OperationError(space.w_ValueError, - space.wrap("cannot convert negative integer to unsigned")) - else: - return r_uint(intval) - - def bigint_w(w_self, space): - return rbigint.fromint(w_self.intval) - - -registerimplementation(W_SmallIntObject) - - -def delegate_SmallInt2Int(space, w_small): - return W_IntObject(w_small.intval) - -def delegate_SmallInt2Long(space, w_small): - return space.newlong(w_small.intval) - -def delegate_SmallInt2Float(space, w_small): - return space.newfloat(float(w_small.intval)) - -def delegate_SmallInt2Complex(space, w_small): - return space.newcomplex(float(w_small.intval), 0.0) - -def add__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval + w_b.intval) # cannot overflow - -def sub__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval - w_b.intval) # cannot overflow - -def floordiv__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval // w_b.intval) # cannot overflow - -div__SmallInt_SmallInt = floordiv__SmallInt_SmallInt - -def mod__SmallInt_SmallInt(space, w_a, w_b): - return wrapint(space, w_a.intval % w_b.intval) # cannot overflow - -def divmod__SmallInt_SmallInt(space, w_a, w_b): - w = wrapint(space, w_a.intval // w_b.intval) # cannot overflow - z = wrapint(space, w_a.intval % w_b.intval) - return space.newtuple([w, z]) - -def copy_multimethods(ns): - """Copy integer multimethods for small int.""" - for name, func in intobject.__dict__.iteritems(): - if "__Int" in name: - new_name = name.replace("Int", "SmallInt") - if new_name not in ns: - # Copy the function, so the annotator specializes it for - # W_SmallIntObject. - ns[new_name] = func = func_with_new_name(func, new_name, globals=ns) - else: - ns[name] = func - ns["get_integer"] = ns["pos__SmallInt"] = ns["int__SmallInt"] - ns["get_negint"] = ns["neg__SmallInt"] - -copy_multimethods(globals()) - -register_all(vars()) diff --git a/pypy/objspace/std/test/test_smallintobject.py b/pypy/objspace/std/test/test_smallintobject.py deleted file mode 100644 --- a/pypy/objspace/std/test/test_smallintobject.py +++ /dev/null @@ -1,229 +0,0 @@ -import sys, py - -#from pypy.objspace.std.model import WITHSMALLINT -#if not WITHSMALLINT: -# py.test.skip("WITHSMALLINT is not enabled") - -from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.multimethod import FailedToImplement -from rpython.rlib.rarithmetic import r_uint - -from pypy.objspace.std.test.test_intobject import AppTestInt - -class TestW_IntObject: - spaceconfig = {"objspace.std.withsmallint": True} - - def test_int_w(self): - assert self.space.int_w(self.space.wrap(42)) == 42 - - def test_uint_w(self): - space = self.space - assert space.uint_w(space.wrap(42)) == 42 - assert isinstance(space.uint_w(space.wrap(42)), r_uint) - space.raises_w(space.w_ValueError, space.uint_w, space.wrap(-1)) - - def test_repr(self): - x = 1 - f1 = wrapint(self.space, x) - result = self.space.repr(f1) - assert self.space.unwrap(result) == repr(x) - - def test_str(self): - x = 12345 - f1 = wrapint(self.space, x) - result = self.space.str(f1) - assert self.space.unwrap(result) == str(x) - - def test_hash(self): - x = 42 - f1 = wrapint(self.space, x) - result = self.space.hash(f1) - assert result.intval == hash(x) - - def test_compare(self): - import operator - optab = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] - for x in (-10, -1, 0, 1, 2, 1000, sys.maxint): - for y in (-sys.maxint-1, -11, -9, -2, 0, 1, 3, 1111, sys.maxint): - for op in optab: - wx = wrapint(self.space, x) - wy = wrapint(self.space, y) - res = getattr(operator, op)(x, y) - method = getattr(self.space, op) - myres = method(wx, wy) - assert self.space.unwrap(myres) == res - - def test_add(self): - for x in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - for y in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - result = self.space.unwrap(self.space.add(f1, f2)) - assert result == x+y - - def test_sub(self): - for x in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - for y in [1, 100, sys.maxint // 2 - 50, - sys.maxint // 2, sys.maxint - 1000, sys.maxint]: - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - result = self.space.unwrap(self.space.sub(f1, f2)) - assert result == x-y - - def test_mul(self): - for x in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]: - for y in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]: - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - result = self.space.unwrap(self.space.mul(f1, f2)) - assert result == x*y - - - def test_div(self): - for i in range(10): - res = i//3 - f1 = wrapint(self.space, i) - f2 = wrapint(self.space, 3) - result = self.space.div(f1, f2) - assert result.intval == res - - def test_mod(self): - x = 1 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.mod(f1, f2) - assert v.intval == x % y - # not that mod cannot overflow - - def test_divmod(self): - x = 1 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - ret = self.space.divmod(f1, f2) - v, w = self.space.unwrap(ret) - assert (v, w) == divmod(x, y) - - def test_pow_iii(self): - x = 10 - y = 2 - z = 13 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - f3 = wrapint(self.space, z) - v = self.space.pow(f1, f2, f3) - assert v.intval == pow(x, y, z) - f1, f2, f3 = [wrapint(self.space, i) for i in (10, -1, 42)] - self.space.raises_w(self.space.w_TypeError, - self.space.pow, - f1, f2, f3) - f1, f2, f3 = [wrapint(self.space, i) for i in (10, 5, 0)] - self.space.raises_w(self.space.w_ValueError, - self.space.pow, - f1, f2, f3) - - def test_pow_iin(self): - x = 10 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.pow(f1, f2, self.space.w_None) - assert v.intval == x ** y - - def test_neg(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.neg(f1) - assert v.intval == -x - - def test_pos(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.pos(f1) - assert v.intval == +x - x = -42 - f1 = wrapint(self.space, x) - v = self.space.pos(f1) - assert v.intval == +x - - def test_abs(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.abs(f1) - assert v.intval == abs(x) - x = -42 - f1 = wrapint(self.space, x) - v = self.space.abs(f1) - assert v.intval == abs(x) - - def test_invert(self): - x = 42 - f1 = wrapint(self.space, x) - v = self.space.invert(f1) - assert v.intval == ~x - - def test_lshift(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.lshift(f1, f2) - assert v.intval == x << y - - def test_rshift(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.rshift(f1, f2) - assert v.intval == x >> y - - def test_and(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.and_(f1, f2) - assert v.intval == x & y - - def test_xor(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.xor(f1, f2) - assert v.intval == x ^ y - - def test_or(self): - x = 12345678 - y = 2 - f1 = wrapint(self.space, x) - f2 = wrapint(self.space, y) - v = self.space.or_(f1, f2) - assert v.intval == x | y - - def test_int(self): - f1 = wrapint(self.space, 1) - result = self.space.int(f1) - assert result == f1 - - def test_oct(self): - x = 012345 - f1 = wrapint(self.space, x) - result = self.space.oct(f1) - assert self.space.unwrap(result) == oct(x) - - def test_hex(self): - x = 0x12345 - f1 = wrapint(self.space, x) - result = self.space.hex(f1) - assert self.space.unwrap(result) == hex(x) - - -class AppTestSmallInt(AppTestInt): - spaceconfig = {"objspace.std.optimized_int_add" : True, - "objspace.std.withsmallint" : True} From noreply at buildbot.pypy.org Sat Mar 23 22:16:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Mar 2013 22:16:11 +0100 (CET) Subject: [pypy-commit] pypy default: cleanups in rpython.jit Message-ID: <20130323211611.1F16A1C106C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62709:33ac58384e23 Date: 2013-03-23 06:52 -0400 http://bitbucket.org/pypy/pypy/changeset/33ac58384e23/ Log: cleanups in rpython.jit diff --git a/rpython/jit/backend/conftest.py b/rpython/jit/backend/conftest.py --- a/rpython/jit/backend/conftest.py +++ b/rpython/jit/backend/conftest.py @@ -2,7 +2,7 @@ This conftest adds options used by test/test_random and x86/test/test_zll_random. """ -import py, random +import random def pytest_addoption(parser): group = parser.getgroup('random test options') diff --git a/rpython/jit/codewriter/format.py b/rpython/jit/codewriter/format.py --- a/rpython/jit/codewriter/format.py +++ b/rpython/jit/codewriter/format.py @@ -10,8 +10,7 @@ def format_assembler(ssarepr): """For testing: format a SSARepr as a multiline string.""" from cStringIO import StringIO - seen = {} - # + def repr(x): if isinstance(x, Register): return '%%%s%d' % (x.kind[0], x.index) # e.g. %i1 or %r2 or %f3 @@ -32,7 +31,7 @@ return '%r' % (x,) else: return '' % (x,) - # + seenlabels = {} for asm in ssarepr.insns: for x in asm: @@ -47,7 +46,7 @@ labelcount[0] += 1 seenlabels[lbl.name] = labelcount[0] return 'L%d' % seenlabels[lbl.name] - # + output = StringIO() insns = ssarepr.insns if insns and insns[-1] == ('---',): diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -3,7 +3,7 @@ from rpython.jit.metainterp.compile import ResumeAtPositionDescr from rpython.jit.metainterp.jitexc import JitException, get_llexception, reraise from rpython.rlib import longlong2float -from rpython.rlib.debug import debug_start, debug_stop, ll_assert, make_sure_not_resized +from rpython.rlib.debug import ll_assert, make_sure_not_resized from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck from rpython.rlib.rtimer import read_timestamp diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -9,11 +9,10 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist -from rpython.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken +from rpython.jit.metainterp.history import TreeLoop, Box, JitCellToken, TargetToken from rpython.jit.metainterp.history import AbstractFailDescr, BoxInt -from rpython.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const, ConstInt +from rpython.jit.metainterp.history import BoxPtr, BoxFloat, ConstInt from rpython.jit.metainterp import history, resume -from rpython.jit.metainterp.typesystem import llhelper, oohelper from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.inliner import Inliner from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP @@ -140,7 +139,7 @@ assert isinstance(target_token, TargetToken) all_target_tokens = [target_token] - loop = create_empty_loop(metainterp) + loop = create_empty_loop(metainterp) loop.inputargs = part.inputargs loop.operations = part.operations loop.quasi_immutable_deps = {} @@ -163,7 +162,7 @@ optimize_trace(metainterp_sd, part, enable_opts) except InvalidLoop: return None - + loop.operations = loop.operations[:-1] + part.operations if part.quasi_immutable_deps: loop.quasi_immutable_deps.update(part.quasi_immutable_deps) @@ -224,7 +223,6 @@ try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts, inline_short_preamble=False) - except InvalidLoop: return None assert part.operations[-1].getopnum() != rop.LABEL @@ -249,9 +247,9 @@ for box in loop.inputargs: assert isinstance(box, Box) - target_token = loop.operations[-1].getdescr() + target_token = loop.operations[-1].getdescr() resumekey.compile_and_attach(metainterp, loop) - + target_token = label.getdescr() assert isinstance(target_token, TargetToken) record_loop_or_bridge(metainterp_sd, loop) @@ -486,7 +484,7 @@ _counters = None # they get stored in _counters then. # this class also gets the following attributes stored by resume.py code - + # XXX move all of unused stuff to guard_op, now that we can have # a separate class, so it does not survive that long rd_snapshot = None @@ -803,7 +801,6 @@ # with completely unoptimized arguments, as in the interpreter. metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd - redargs = new_loop.inputargs new_loop.original_jitcell_token = jitcell_token = make_jitcell_token(jitdriver_sd) propagate_original_jitcell_token(new_loop) send_loop_to_backend(self.original_greenkey, metainterp.jitdriver_sd, @@ -819,14 +816,14 @@ to some existing place. """ from rpython.jit.metainterp.optimizeopt import optimize_trace - + # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. # # Attempt to use optimize_bridge(). This may return None in case # it does not work -- i.e. none of the existing old_loop_tokens match. new_trace = create_empty_loop(metainterp) - new_trace.inputargs = inputargs = metainterp.history.inputargs[:] + new_trace.inputargs = metainterp.history.inputargs[:] # clone ops, as optimize_bridge can mutate the ops new_trace.operations = [op.clone() for op in metainterp.history.operations] @@ -856,7 +853,6 @@ else: metainterp.retrace_needed(new_trace) return None - # ____________________________________________________________ diff --git a/rpython/jit/metainterp/greenfield.py b/rpython/jit/metainterp/greenfield.py --- a/rpython/jit/metainterp/greenfield.py +++ b/rpython/jit/metainterp/greenfield.py @@ -1,8 +1,4 @@ -from rpython.jit.metainterp.typesystem import deref - - class GreenFieldInfo(object): - def __init__(self, cpu, jd): self.cpu = cpu self.jitdriver_sd = jd 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 @@ -1,4 +1,3 @@ - from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.ootypesystem import ootype @@ -175,7 +174,7 @@ class BasicFinalDescr(AbstractFailDescr): final_descr = True - + def __init__(self, identifier=None): self.identifier = identifier # for testing diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py --- a/rpython/jit/metainterp/quasiimmut.py +++ b/rpython/jit/metainterp/quasiimmut.py @@ -1,4 +1,3 @@ -import weakref from rpython.rtyper.lltypesystem import lltype, rclass from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance from rpython.jit.metainterp.history import AbstractDescr diff --git a/rpython/jit/metainterp/warmspot.py b/rpython/jit/metainterp/warmspot.py --- a/rpython/jit/metainterp/warmspot.py +++ b/rpython/jit/metainterp/warmspot.py @@ -1,12 +1,11 @@ import sys, py from rpython.tool.sourcetools import func_with_new_name -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator,\ cast_base_ptr_to_instance, hlstr from rpython.annotator import model as annmodel from rpython.rtyper.llinterp import LLException from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache -from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.flowspace.model import checkgraph, Link, copygraph from rpython.rlib.objectmodel import we_are_translated diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py --- a/rpython/jit/metainterp/warmstate.py +++ b/rpython/jit/metainterp/warmstate.py @@ -12,7 +12,6 @@ from rpython.rlib.debug import debug_start, debug_stop, debug_print from rpython.jit.metainterp import history from rpython.jit.codewriter import support, heaptracker, longlong -from rpython.tool.sourcetools import func_with_new_name # ____________________________________________________________ diff --git a/rpython/jit/tool/loopcounter.py b/rpython/jit/tool/loopcounter.py --- a/rpython/jit/tool/loopcounter.py +++ b/rpython/jit/tool/loopcounter.py @@ -3,7 +3,6 @@ Parse and display the traces produced by pypy-c-jit when PYPYLOG is set. """ -import py import sys import optparse import re diff --git a/rpython/jit/tool/loopviewer.py b/rpython/jit/tool/loopviewer.py --- a/rpython/jit/tool/loopviewer.py +++ b/rpython/jit/tool/loopviewer.py @@ -3,14 +3,10 @@ Parse and display the traces produced by pypy-c-jit when PYPYLOG is set. """ -import py import sys import optparse -from pprint import pprint from rpython.tool import logparser from rpython.jit.tool.oparser import parse -from rpython.jit.metainterp.history import ConstInt -from rpython.rtyper.lltypesystem import llmemory, lltype def main(loopfile, options): print 'Loading file:' @@ -19,7 +15,7 @@ if not options.quiet: for loop in loops: loop.show() - + if options.summary: print print 'Summary:' diff --git a/rpython/jit/tool/showstats.py b/rpython/jit/tool/showstats.py --- a/rpython/jit/tool/showstats.py +++ b/rpython/jit/tool/showstats.py @@ -1,11 +1,10 @@ #!/usr/bin/env python from __future__ import division -import sys, py +import sys from rpython.tool import logparser from rpython.jit.tool.oparser import parse from rpython.jit.metainterp.resoperation import rop -from rpython.rtyper.lltypesystem import lltype, llmemory def main(argv): log = logparser.parse_log_file(argv[0]) @@ -26,6 +25,6 @@ print "Loop #%d, length: %d, opcodes: %d, guards: %d" % (i, num_ops, num_dmp, num_guards) else: print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp) - + if __name__ == '__main__': main(sys.argv[1:]) From noreply at buildbot.pypy.org Sat Mar 23 22:16:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 22:16:35 +0100 (CET) Subject: [pypy-commit] jitviewer default: pip is sooooo broken Message-ID: <20130323211635.8D30E1C106C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r220:4485ad26c4b5 Date: 2013-03-23 14:16 -0700 http://bitbucket.org/pypy/jitviewer/changeset/4485ad26c4b5/ Log: pip is sooooo broken diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1,7 +1,13 @@ #!/usr/bin/env pypy-c +import os from setuptools import setup +rest = [] +for dirname, _, filenames in os.walk(os.path.join(os.path.join(os.path.dirname(__file__), '_jitviewer'), 'static')): + for x in filenames: + rest.append(os.path.join(dirname, x)) + setup(name='JitViewer', version='0.1', description="Viewer for pypy's jit traces", @@ -12,5 +18,5 @@ scripts=['bin/jitviewer.py', 'bin/qwebview.py'], install_requires=['flask', 'pygments', 'simplejson', 'Jinja2>=2.6'], include_package_data=True, - package_data={'': ['templates/*.html', 'static/*']}, + package_data={'': ['templates/*.html'] + rest}, zip_safe=False) From noreply at buildbot.pypy.org Sat Mar 23 22:21:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 22:21:49 +0100 (CET) Subject: [pypy-commit] jitviewer default: another try Message-ID: <20130323212149.44AD31C15A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r221:75336230aadc Date: 2013-03-23 14:21 -0700 http://bitbucket.org/pypy/jitviewer/changeset/75336230aadc/ Log: another try diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -4,9 +4,12 @@ from setuptools import setup rest = [] -for dirname, _, filenames in os.walk(os.path.join(os.path.join(os.path.dirname(__file__), '_jitviewer'), 'static')): +base = os.path.join(os.path.dirname(__file__), '_jitviewer') +for dirname, _, filenames in os.walk(os.path.join(base, 'static')): + dirname = os.path.relpath(dirname, base) for x in filenames: rest.append(os.path.join(dirname, x)) +print rest setup(name='JitViewer', version='0.1', From noreply at buildbot.pypy.org Sat Mar 23 22:21:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Mar 2013 22:21:59 +0100 (CET) Subject: [pypy-commit] jitviewer default: remove print Message-ID: <20130323212159.3C5D31C15A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r222:3eb8d545520a Date: 2013-03-23 14:21 -0700 http://bitbucket.org/pypy/jitviewer/changeset/3eb8d545520a/ Log: remove print diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -9,7 +9,6 @@ dirname = os.path.relpath(dirname, base) for x in filenames: rest.append(os.path.join(dirname, x)) -print rest setup(name='JitViewer', version='0.1', From noreply at buildbot.pypy.org Sat Mar 23 23:36:37 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 23:36:37 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: (alex, fijal): a branch to kill gen_store_back_in_virtualizable Message-ID: <20130323223637.A3E3C1C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-gen-store-back-in Changeset: r62710:7f4ad2662a3c Date: 2013-03-23 14:05 -0700 http://bitbucket.org/pypy/pypy/changeset/7f4ad2662a3c/ Log: (alex, fijal): a branch to kill gen_store_back_in_virtualizable From noreply at buildbot.pypy.org Sat Mar 23 23:36:39 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 23:36:39 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, fijal): removed pointless boxing/unboxing of bools Message-ID: <20130323223639.091011C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62711:cfea548f0f8c Date: 2013-03-23 15:35 -0700 http://bitbucket.org/pypy/pypy/changeset/cfea548f0f8c/ Log: (alex, fijal): removed pointless boxing/unboxing of bools diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -913,7 +913,7 @@ if self.is_w(w_exc_type, w_check_class): return True # fast path (also here to handle string exceptions) try: - if self.is_true(self.isinstance(w_check_class, self.w_tuple)): + if self.isinstance_w(w_check_class, self.w_tuple): for w_t in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_t): return True @@ -1052,11 +1052,11 @@ def abstract_isinstance_w(self, w_obj, w_cls): # Equivalent to 'isinstance(obj, cls)'. - return self.is_true(self.isinstance(w_obj, w_cls)) + return self.isinstance_w(w_obj, w_cls) def abstract_isclass_w(self, w_obj): # Equivalent to 'isinstance(obj, type)'. - return self.is_true(self.isinstance(w_obj, self.w_type)) + return self.isinstance_w(w_obj, self.w_type) def abstract_getclass(self, w_obj): # Equivalent to 'obj.__class__'. @@ -1164,7 +1164,7 @@ -> (index, 0, 0) or (start, stop, step) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) @@ -1184,7 +1184,7 @@ -> (index, 0, 0, 1) or (start, stop, step, slice_length) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step, length = w_index_or_slice.indices4(self, @@ -1326,7 +1326,7 @@ def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. - if not self.is_true(self.isinstance(w_obj, self.w_str)): + if not self.isinstance_w(w_obj, self.w_str): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) return self.str_w(w_obj) @@ -1346,7 +1346,7 @@ def realunicode_w(self, w_obj): # Like unicode_w, but only works if w_obj is really of type # 'unicode'. - if not self.is_true(self.isinstance(w_obj, self.w_unicode)): + if not self.isinstance_w(w_obj, self.w_unicode): raise OperationError(self.w_TypeError, self.wrap('argument must be a unicode')) return self.unicode_w(w_obj) @@ -1367,19 +1367,19 @@ return self.float_w(self.float(w_obj)) def gateway_r_longlong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_longlong_w(self.int(w_obj)) def gateway_r_uint_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.uint_w(self.int(w_obj)) def gateway_r_ulonglong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_ulonglong_w(self.int(w_obj)) From noreply at buildbot.pypy.org Sat Mar 23 23:36:40 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Mar 2013 23:36:40 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130323223640.74DE81C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62712:8e44a515d378 Date: 2013-03-23 15:36 -0700 http://bitbucket.org/pypy/pypy/changeset/8e44a515d378/ Log: merged upstream diff --git a/rpython/jit/backend/conftest.py b/rpython/jit/backend/conftest.py --- a/rpython/jit/backend/conftest.py +++ b/rpython/jit/backend/conftest.py @@ -2,7 +2,7 @@ This conftest adds options used by test/test_random and x86/test/test_zll_random. """ -import py, random +import random def pytest_addoption(parser): group = parser.getgroup('random test options') diff --git a/rpython/jit/codewriter/format.py b/rpython/jit/codewriter/format.py --- a/rpython/jit/codewriter/format.py +++ b/rpython/jit/codewriter/format.py @@ -10,8 +10,7 @@ def format_assembler(ssarepr): """For testing: format a SSARepr as a multiline string.""" from cStringIO import StringIO - seen = {} - # + def repr(x): if isinstance(x, Register): return '%%%s%d' % (x.kind[0], x.index) # e.g. %i1 or %r2 or %f3 @@ -32,7 +31,7 @@ return '%r' % (x,) else: return '' % (x,) - # + seenlabels = {} for asm in ssarepr.insns: for x in asm: @@ -47,7 +46,7 @@ labelcount[0] += 1 seenlabels[lbl.name] = labelcount[0] return 'L%d' % seenlabels[lbl.name] - # + output = StringIO() insns = ssarepr.insns if insns and insns[-1] == ('---',): diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -3,7 +3,7 @@ from rpython.jit.metainterp.compile import ResumeAtPositionDescr from rpython.jit.metainterp.jitexc import JitException, get_llexception, reraise from rpython.rlib import longlong2float -from rpython.rlib.debug import debug_start, debug_stop, ll_assert, make_sure_not_resized +from rpython.rlib.debug import ll_assert, make_sure_not_resized from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck from rpython.rlib.rtimer import read_timestamp diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -9,11 +9,10 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist -from rpython.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken +from rpython.jit.metainterp.history import TreeLoop, Box, JitCellToken, TargetToken from rpython.jit.metainterp.history import AbstractFailDescr, BoxInt -from rpython.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const, ConstInt +from rpython.jit.metainterp.history import BoxPtr, BoxFloat, ConstInt from rpython.jit.metainterp import history, resume -from rpython.jit.metainterp.typesystem import llhelper, oohelper from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.inliner import Inliner from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP @@ -140,7 +139,7 @@ assert isinstance(target_token, TargetToken) all_target_tokens = [target_token] - loop = create_empty_loop(metainterp) + loop = create_empty_loop(metainterp) loop.inputargs = part.inputargs loop.operations = part.operations loop.quasi_immutable_deps = {} @@ -163,7 +162,7 @@ optimize_trace(metainterp_sd, part, enable_opts) except InvalidLoop: return None - + loop.operations = loop.operations[:-1] + part.operations if part.quasi_immutable_deps: loop.quasi_immutable_deps.update(part.quasi_immutable_deps) @@ -224,7 +223,6 @@ try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts, inline_short_preamble=False) - except InvalidLoop: return None assert part.operations[-1].getopnum() != rop.LABEL @@ -249,9 +247,9 @@ for box in loop.inputargs: assert isinstance(box, Box) - target_token = loop.operations[-1].getdescr() + target_token = loop.operations[-1].getdescr() resumekey.compile_and_attach(metainterp, loop) - + target_token = label.getdescr() assert isinstance(target_token, TargetToken) record_loop_or_bridge(metainterp_sd, loop) @@ -486,7 +484,7 @@ _counters = None # they get stored in _counters then. # this class also gets the following attributes stored by resume.py code - + # XXX move all of unused stuff to guard_op, now that we can have # a separate class, so it does not survive that long rd_snapshot = None @@ -803,7 +801,6 @@ # with completely unoptimized arguments, as in the interpreter. metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd - redargs = new_loop.inputargs new_loop.original_jitcell_token = jitcell_token = make_jitcell_token(jitdriver_sd) propagate_original_jitcell_token(new_loop) send_loop_to_backend(self.original_greenkey, metainterp.jitdriver_sd, @@ -819,14 +816,14 @@ to some existing place. """ from rpython.jit.metainterp.optimizeopt import optimize_trace - + # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. # # Attempt to use optimize_bridge(). This may return None in case # it does not work -- i.e. none of the existing old_loop_tokens match. new_trace = create_empty_loop(metainterp) - new_trace.inputargs = inputargs = metainterp.history.inputargs[:] + new_trace.inputargs = metainterp.history.inputargs[:] # clone ops, as optimize_bridge can mutate the ops new_trace.operations = [op.clone() for op in metainterp.history.operations] @@ -856,7 +853,6 @@ else: metainterp.retrace_needed(new_trace) return None - # ____________________________________________________________ diff --git a/rpython/jit/metainterp/greenfield.py b/rpython/jit/metainterp/greenfield.py --- a/rpython/jit/metainterp/greenfield.py +++ b/rpython/jit/metainterp/greenfield.py @@ -1,8 +1,4 @@ -from rpython.jit.metainterp.typesystem import deref - - class GreenFieldInfo(object): - def __init__(self, cpu, jd): self.cpu = cpu self.jitdriver_sd = jd 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 @@ -1,4 +1,3 @@ - from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.ootypesystem import ootype @@ -175,7 +174,7 @@ class BasicFinalDescr(AbstractFailDescr): final_descr = True - + def __init__(self, identifier=None): self.identifier = identifier # for testing diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py --- a/rpython/jit/metainterp/quasiimmut.py +++ b/rpython/jit/metainterp/quasiimmut.py @@ -1,4 +1,3 @@ -import weakref from rpython.rtyper.lltypesystem import lltype, rclass from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance from rpython.jit.metainterp.history import AbstractDescr diff --git a/rpython/jit/metainterp/warmspot.py b/rpython/jit/metainterp/warmspot.py --- a/rpython/jit/metainterp/warmspot.py +++ b/rpython/jit/metainterp/warmspot.py @@ -1,12 +1,11 @@ import sys, py from rpython.tool.sourcetools import func_with_new_name -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator,\ cast_base_ptr_to_instance, hlstr from rpython.annotator import model as annmodel from rpython.rtyper.llinterp import LLException from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache -from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.flowspace.model import checkgraph, Link, copygraph from rpython.rlib.objectmodel import we_are_translated diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py --- a/rpython/jit/metainterp/warmstate.py +++ b/rpython/jit/metainterp/warmstate.py @@ -12,7 +12,6 @@ from rpython.rlib.debug import debug_start, debug_stop, debug_print from rpython.jit.metainterp import history from rpython.jit.codewriter import support, heaptracker, longlong -from rpython.tool.sourcetools import func_with_new_name # ____________________________________________________________ diff --git a/rpython/jit/tool/loopcounter.py b/rpython/jit/tool/loopcounter.py --- a/rpython/jit/tool/loopcounter.py +++ b/rpython/jit/tool/loopcounter.py @@ -3,7 +3,6 @@ Parse and display the traces produced by pypy-c-jit when PYPYLOG is set. """ -import py import sys import optparse import re diff --git a/rpython/jit/tool/loopviewer.py b/rpython/jit/tool/loopviewer.py --- a/rpython/jit/tool/loopviewer.py +++ b/rpython/jit/tool/loopviewer.py @@ -3,14 +3,10 @@ Parse and display the traces produced by pypy-c-jit when PYPYLOG is set. """ -import py import sys import optparse -from pprint import pprint from rpython.tool import logparser from rpython.jit.tool.oparser import parse -from rpython.jit.metainterp.history import ConstInt -from rpython.rtyper.lltypesystem import llmemory, lltype def main(loopfile, options): print 'Loading file:' @@ -19,7 +15,7 @@ if not options.quiet: for loop in loops: loop.show() - + if options.summary: print print 'Summary:' diff --git a/rpython/jit/tool/showstats.py b/rpython/jit/tool/showstats.py --- a/rpython/jit/tool/showstats.py +++ b/rpython/jit/tool/showstats.py @@ -1,11 +1,10 @@ #!/usr/bin/env python from __future__ import division -import sys, py +import sys from rpython.tool import logparser from rpython.jit.tool.oparser import parse from rpython.jit.metainterp.resoperation import rop -from rpython.rtyper.lltypesystem import lltype, llmemory def main(argv): log = logparser.parse_log_file(argv[0]) @@ -26,6 +25,6 @@ print "Loop #%d, length: %d, opcodes: %d, guards: %d" % (i, num_ops, num_dmp, num_guards) else: print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp) - + if __name__ == '__main__': main(sys.argv[1:]) From noreply at buildbot.pypy.org Sun Mar 24 00:02:01 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 24 Mar 2013 00:02:01 +0100 (CET) Subject: [pypy-commit] pypy default: bad fijal, fix total nonsense Message-ID: <20130323230201.EFC891C016E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62713:f0ee5d5278eb Date: 2013-03-23 16:01 -0700 http://bitbucket.org/pypy/pypy/changeset/f0ee5d5278eb/ Log: bad fijal, fix total nonsense 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 @@ -6,6 +6,7 @@ from pypy.objspace.std.register_all import register_all from pypy.objspace.std.intobject import W_IntObject + class W_BoolObject(W_Object): from pypy.objspace.std.booltype import bool_typedef as typedef _immutable_fields_ = ['boolval'] @@ -37,7 +38,7 @@ return float(self.boolval) def int(self, space): - return self + return space.newint(int(self.boolval)) registerimplementation(W_BoolObject) From noreply at buildbot.pypy.org Sun Mar 24 00:18:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 24 Mar 2013 00:18:50 +0100 (CET) Subject: [pypy-commit] pypy default: improve boolobject tests to cover recent fix Message-ID: <20130323231850.4E6571C106C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62714:dd8367979d8d Date: 2013-03-23 19:17 -0400 http://bitbucket.org/pypy/pypy/changeset/dd8367979d8d/ Log: improve boolobject tests to cover recent fix 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 @@ -11,19 +11,24 @@ 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")) - + def test_true(self): assert self.space.is_true(self.true) - + def test_false(self): assert not self.space.is_true(self.false) + def test_int_w(self): + assert self.space.int_w(self.true) is 1 + assert self.space.int_w(self.false) is 0 + def test_uint_w(self): assert self.space.uint_w(self.true) == 1 + assert self.space.uint_w(self.false) == 0 def test_rbigint_w(self): assert self.space.bigint_w(self.true)._digits == [1] - + class AppTestAppBoolTest: def test_bool_callable(self): assert True == bool(1) @@ -36,6 +41,10 @@ assert "True" == repr(True) assert "False" == repr(False) + def test_bool_int(self): + assert int(True) is 1 + assert int(False) is 0 + def test_bool_ops(self): assert True + True == 2 assert False | False is False From noreply at buildbot.pypy.org Sun Mar 24 00:35:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Mar 2013 00:35:31 +0100 (CET) Subject: [pypy-commit] buildbot default: try to disable keepalive for xerxes Message-ID: <20130323233531.BA97E1C106C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r759:be7989c3eb77 Date: 2013-03-23 16:29 -0700 http://bitbucket.org/pypy/buildbot/changeset/be7989c3eb77/ Log: try to disable keepalive for xerxes diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -268,6 +268,8 @@ BUILDLINUXARM = "build-pypy-c-linux-armel" BUILDJITLINUXARM = "build-pypy-c-jit-linux-armel" +extra_opts= {'xerxes': {'keepalive-interval': None}} + BuildmasterConfig = { 'slavePortnum': slavePortnum, @@ -328,7 +330,7 @@ 'status': [status, ircbot], - 'slaves': [BuildSlave(name, password) + 'slaves': [BuildSlave(name, password, **extra_opts.get(name, {})) for (name, password) in passwords.iteritems()], From noreply at buildbot.pypy.org Sun Mar 24 00:35:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Mar 2013 00:35:32 +0100 (CET) Subject: [pypy-commit] buildbot default: actually make it really low Message-ID: <20130323233532.E69E61C106C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r760:bebfcbeeef3b Date: 2013-03-23 16:35 -0700 http://bitbucket.org/pypy/buildbot/changeset/bebfcbeeef3b/ Log: actually make it really low diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -268,7 +268,7 @@ BUILDLINUXARM = "build-pypy-c-linux-armel" BUILDJITLINUXARM = "build-pypy-c-jit-linux-armel" -extra_opts= {'xerxes': {'keepalive-interval': None}} +extra_opts= {'xerxes': {'keepalive-interval': 15}} BuildmasterConfig = { 'slavePortnum': slavePortnum, From noreply at buildbot.pypy.org Sun Mar 24 00:35:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Mar 2013 00:35:33 +0100 (CET) Subject: [pypy-commit] buildbot default: merge Message-ID: <20130323233533.EDBF11C106C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r761:908ad98d9252 Date: 2013-03-23 16:35 -0700 http://bitbucket.org/pypy/buildbot/changeset/908ad98d9252/ Log: merge diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -248,7 +248,6 @@ JITLINUX64 = "pypy-c-jit-linux-x86-64" JITLINUXARM = "pypy-c-jit-linux-armel" JITLINUXPPC64 = "pypy-c-jit-linux-ppc-64" -OJITLINUX32 = "pypy-c-Ojit-no-jit-linux-x86-32" JITMACOSX64 = "pypy-c-jit-macosx-x86-64" JITWIN32 = "pypy-c-jit-win-x86-32" JITWIN64 = "pypy-c-jit-win-x86-64" @@ -289,13 +288,12 @@ JITLINUX64, # on allegro64, uses 1 core APPLVLLINUX32, # on tannit32, uses 1 core APPLVLLINUX64, # on allegro64, uses 1 core - OJITLINUX32, # on tannit32, uses 1 core # other platforms MACOSX32, # on minime JITWIN32, # on aurora JITFREEBSD64, # on headless JITFREEBSD964, # on exarkun's freebsd - JITMACOSX64, # on mvt's machine + #JITMACOSX64, # no currently working machine ], branch=None, hour=0, minute=0), Nightly("nightly-2-00", [ @@ -379,13 +377,6 @@ "category": "linux64", #"locks": [TannitCPU.access('counting')], }, - {"name": OJITLINUX32, - "slavenames": ["allegro32"], - "builddir": OJITLINUX32, - "factory": pypy_OjitTranslatedTestFactory, - "category": 'linux32', - #"locks": [TannitCPU.access('counting')], - }, {"name" : JITLINUX32, #"slavenames": ["allegro32"], "slavenames": ["tannit32"], From noreply at buildbot.pypy.org Sun Mar 24 00:36:19 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 24 Mar 2013 00:36:19 +0100 (CET) Subject: [pypy-commit] pypy default: random cleanups Message-ID: <20130323233619.536251C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62715:5e99e3e7cac5 Date: 2013-03-23 16:34 -0700 http://bitbucket.org/pypy/pypy/changeset/5e99e3e7cac5/ Log: random cleanups diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1094,7 +1094,7 @@ expression = compiler.compile(expression, '?', 'eval', 0, hidden_applevel=hidden_applevel) else: - raise TypeError, 'space.eval(): expected a string, code or PyCode object' + raise TypeError('space.eval(): expected a string, code or PyCode object') return expression.exec_code(self, w_globals, w_locals) def exec_(self, statement, w_globals, w_locals, hidden_applevel=False, @@ -1108,7 +1108,7 @@ statement = compiler.compile(statement, filename, 'exec', 0, hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): - raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') if not self.is_true(self.contains(w_globals, w_key)): self.setitem(w_globals, w_key, self.wrap(self.builtin)) @@ -1496,15 +1496,20 @@ space.exec_(str(source), w_glob, w_glob) return space.getitem(w_glob, space.wrap('anonymous')) + class DummyLock(object): def acquire(self, flag): return True + def release(self): pass + def _freeze_(self): return True + def __enter__(self): pass + def __exit__(self, *args): pass @@ -1539,7 +1544,7 @@ ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), - ('abs' , 'abs', 1, ['__abs__']), + ('abs', 'abs', 1, ['__abs__']), ('hex', 'hex', 1, ['__hex__']), ('oct', 'oct', 1, ['__oct__']), ('ord', 'ord', 1, []), @@ -1592,12 +1597,12 @@ ('delete', 'delete', 2, ['__delete__']), ('userdel', 'del', 1, ['__del__']), ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py - ] +] ObjSpace.BuiltinModuleTable = [ '__builtin__', 'sys', - ] +] ObjSpace.ConstantTable = [ 'None', @@ -1605,7 +1610,7 @@ 'True', 'Ellipsis', 'NotImplemented', - ] +] ObjSpace.ExceptionTable = [ 'ArithmeticError', @@ -1648,7 +1653,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', - ] +] if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] From noreply at buildbot.pypy.org Sun Mar 24 00:36:20 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 24 Mar 2013 00:36:20 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130323233620.9C5FD1C106C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r62716:8ed0b78304fa Date: 2013-03-23 16:36 -0700 http://bitbucket.org/pypy/pypy/changeset/8ed0b78304fa/ Log: merged upstream 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 @@ -11,19 +11,24 @@ 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")) - + def test_true(self): assert self.space.is_true(self.true) - + def test_false(self): assert not self.space.is_true(self.false) + def test_int_w(self): + assert self.space.int_w(self.true) is 1 + assert self.space.int_w(self.false) is 0 + def test_uint_w(self): assert self.space.uint_w(self.true) == 1 + assert self.space.uint_w(self.false) == 0 def test_rbigint_w(self): assert self.space.bigint_w(self.true)._digits == [1] - + class AppTestAppBoolTest: def test_bool_callable(self): assert True == bool(1) @@ -36,6 +41,10 @@ assert "True" == repr(True) assert "False" == repr(False) + def test_bool_int(self): + assert int(True) is 1 + assert int(False) is 0 + def test_bool_ops(self): assert True + True == 2 assert False | False is False From noreply at buildbot.pypy.org Sun Mar 24 00:50:22 2013 From: noreply at buildbot.pypy.org (aljosa) Date: Sun, 24 Mar 2013 00:50:22 +0100 (CET) Subject: [pypy-commit] jitviewer default: fixed new js code to use "path" Message-ID: <20130323235022.F27F41C1456@cobra.cs.uni-duesseldorf.de> Author: Aljosa Mohorovic Branch: Changeset: r223:bcbd40d3ef0c Date: 2013-03-23 16:48 -0700 http://bitbucket.org/pypy/jitviewer/changeset/bcbd40d3ef0c/ Log: fixed new js code to use "path" diff --git a/_jitviewer/static/app.js b/_jitviewer/static/app.js --- a/_jitviewer/static/app.js +++ b/_jitviewer/static/app.js @@ -5,22 +5,33 @@ "a[data-name] click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); + var path = el.data('path'); if(name) { - can.route.attr('name', name); + can.route.attr({'name': name, 'path': path}); + } + }, + ".operations a.inlined_call click": function(el, ev) { + ev.preventDefault(); + var name = el.data('name'); + var path = el.data('path'); + if(name) { + can.route.attr({'name': name, 'path': path}); } }, ".operations a.bridgelink click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); + var path = el.data('path'); if(name) { - can.route.attr('name', name); + can.route.attr({'name': name, 'path': path}); } }, ".operations .single-operation a click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); + var path = el.data('path'); if(name) { - can.route.attr('name', name); + can.route.attr({'name': name, 'path': path}); } }, ".operations .single-operation span mouseenter": function(el, ev) { @@ -53,7 +64,7 @@ //console.log('route index'); }, 'items/:name route': function(data) { - this.show_loop(data.name); + this.show_loop(data.name, data.path); }, "#inp-bar focusin": function(el, ev){ this.filter_active = true; @@ -135,14 +146,18 @@ "#loops .loopitem a click": function(el, ev){ ev.preventDefault(); var name = el.data('name'); - can.route.attr('name', name); - //this.show_loop(name); + var path = el.data('path'); + if(name) { + can.route.attr({'name': name, 'path': path}); + } }, "#callstack a click": function(el, ev){ ev.preventDefault(); var name = el.data('name'); - can.route.attr('name', name); - //this.show_loop(name); + var path = el.data('path'); + if(name) { + can.route.attr({'name': name, 'path': path}); + } }, check_selfreferencing: function(){ var self = this; @@ -181,20 +196,6 @@ } }, show_loop: function(name, path){ - /* - if(this.current_line) { - $("#loop-" + this.current_line).removeClass("selected"); - } - $("#loop-" + name).addClass("selected"); - $("#title-text").html($("#loop-" + name).attr('name')); - $("#title").show(); - glob_bridge_state.name = name; - if (path) { - glob_bridge_state.path = path; - } else { - delete glob_bridge_state.path; - } - */ var self = this; var data = { 'asm': this.state_asm, From noreply at buildbot.pypy.org Sun Mar 24 03:48:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Mar 2013 03:48:02 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_abstractinstance in a way that got lost Message-ID: <20130324024802.0F38C1C016E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62717:92f0ae34555c Date: 2013-03-23 19:43 -0700 http://bitbucket.org/pypy/pypy/changeset/92f0ae34555c/ Log: fix test_abstractinstance in a way that got lost diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -49,7 +49,6 @@ @jit.unroll_safe def abstract_isinstance_w(space, w_obj, w_klass_or_tuple, allow_override=False): """Implementation for the full 'isinstance(obj, klass_or_tuple)'.""" - # -- case (anything, tuple) # XXX it might be risky that the JIT sees this if space.isinstance_w(w_klass_or_tuple, space.w_tuple): 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 @@ -46,7 +46,7 @@ from pypy.objspace.std.basestringtype import basestring_typedef from pypy.objspace.std.stringtype import str_typedef from pypy.objspace.std.bytearraytype import bytearray_typedef - from pypy.objspace.std.typetype import type_typedef + from pypy.objspace.std.typeobject import type_typedef from pypy.objspace.std.slicetype import slice_typedef from pypy.objspace.std.longtype import long_typedef from pypy.objspace.std.unicodetype import unicode_typedef diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -1,15 +1,10 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import GetSetProperty, default_identity_hash from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments -from pypy.interpreter.baseobjspace import ObjSpace from pypy.objspace.descroperation import Object from pypy.objspace.std.stdtypedef import StdTypeDef -from pypy.objspace.std.register_all import register_all -from pypy.objspace.std import identitydict def descr__repr__(space, w_obj): - w = space.wrap w_type = space.type(w_obj) classname = w_type.getname(space) w_module = w_type.lookup("__module__") @@ -64,7 +59,7 @@ def descr__new__(space, w_type, __args__): from pypy.objspace.std.objectobject import W_ObjectObject - from pypy.objspace.std.typetype import _precheck_for_new + from pypy.objspace.std.typeobject import _precheck_for_new # don't allow arguments if the default object.__init__() is about # to be called w_type = _precheck_for_new(space, w_type) diff --git a/pypy/objspace/std/register_all.py b/pypy/objspace/std/register_all.py --- a/pypy/objspace/std/register_all.py +++ b/pypy/objspace/std/register_all.py @@ -18,7 +18,7 @@ for name, obj in module_dict.items(): if name.startswith('app_'): print "%s: direct app definitions deprecated" % name - if name.find('__')<1 or name.startswith('app_'): + if name.find('__')<1 or name.startswith('app_') or name.startswith('descr_'): continue funcname, sig = name.split('__') l = [] diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -2,10 +2,12 @@ from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter.typedef import weakref_descr +from pypy.interpreter.typedef import weakref_descr, GetSetProperty,\ + descr_get_dict from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member +from pypy.objspace.std.stdtypedef import StdTypeDef from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, promote_string, elidable, dont_look_inside, unroll_safe) @@ -83,8 +85,6 @@ OVERRIDES_EQ_CMP_OR_HASH = 2 class W_TypeObject(W_Object): - from pypy.objspace.std.typetype import type_typedef as typedef - lazyloaders = {} # can be overridden by specific instances # the version_tag changes if the dict or the inheritance hierarchy changes @@ -572,6 +572,285 @@ def delweakref(self): self._lifeline_ = None +def descr__new__(space, w_typetype, w_name, w_bases=None, w_dict=None): + "This is used to create user-defined classes only." + # XXX check types + + w_typetype = _precheck_for_new(space, w_typetype) + + # special case for type(x) + if (space.is_w(space.type(w_typetype), space.w_type) and w_bases is None and + w_dict is None): + return space.type(w_name) + else: + return _create_new_type(space, w_typetype, w_name, w_bases, w_dict) + + +def _create_new_type(space, w_typetype, w_name, w_bases, w_dict): + # this is in its own function because we want the special case 'type(x)' + # above to be seen by the jit. + from pypy.objspace.std.typeobject import W_TypeObject + + if w_bases is None or w_dict is None: + raise OperationError(space.w_TypeError, space.wrap("type() takes 1 or 3 arguments")) + + bases_w = space.fixedview(w_bases) + + w_winner = w_typetype + for base in bases_w: + w_typ = space.type(base) + if space.is_w(w_typ, space.w_classobj): + continue # special-case old-style classes + if space.is_true(space.issubtype(w_winner, w_typ)): + continue + if space.is_true(space.issubtype(w_typ, w_winner)): + w_winner = w_typ + continue + raise OperationError(space.w_TypeError, + space.wrap("metaclass conflict: " + "the metaclass of a derived class " + "must be a (non-strict) subclass " + "of the metaclasses of all its bases")) + + if not space.is_w(w_winner, w_typetype): + newfunc = space.getattr(w_winner, space.wrap('__new__')) + if not space.is_w(newfunc, space.getattr(space.w_type, space.wrap('__new__'))): + return space.call_function(newfunc, w_winner, w_name, w_bases, w_dict) + w_typetype = w_winner + + name = space.str_w(w_name) + assert isinstance(name, str) + dict_w = {} + dictkeys_w = space.listview(w_dict) + for w_key in dictkeys_w: + key = space.str_w(w_key) + dict_w[key] = space.getitem(w_dict, w_key) + w_type = space.allocate_instance(W_TypeObject, w_typetype) + W_TypeObject.__init__(w_type, space, name, bases_w or [space.w_object], + dict_w) + w_type.ready() + return w_type + +def _precheck_for_new(space, w_type): + from pypy.objspace.std.typeobject import W_TypeObject + if not isinstance(w_type, W_TypeObject): + raise operationerrfmt(space.w_TypeError, + "X is not a type object (%s)", + space.type(w_type).getname(space)) + return w_type + +# ____________________________________________________________ + +def _check(space, w_type, w_msg=None): + from pypy.objspace.std.typeobject import W_TypeObject + if not isinstance(w_type, W_TypeObject): + if w_msg is None: + w_msg = space.wrap("descriptor is for 'type'") + raise OperationError(space.w_TypeError, w_msg) + return w_type + + +def descr_get__name__(space, w_type): + w_type = _check(space, w_type) + return space.wrap(w_type.name) + +def descr_set__name__(space, w_type, w_value): + w_type = _check(space, w_type) + if not w_type.is_heaptype(): + raise operationerrfmt(space.w_TypeError, + "can't set %s.__name__", w_type.name) + w_type.name = space.str_w(w_value) + +def descr_get__mro__(space, w_type): + w_type = _check(space, w_type) + return space.newtuple(w_type.mro_w) + +def descr_mro(space, w_type): + """Return a type's method resolution order.""" + w_type = _check(space, w_type, space.wrap("expected type")) + return space.newlist(w_type.compute_default_mro()) + +def descr_get__bases__(space, w_type): + w_type = _check(space, w_type) + return space.newtuple(w_type.bases_w) + +def mro_subclasses(space, w_type, temp): + from pypy.objspace.std.typeobject import W_TypeObject, compute_mro + temp.append((w_type, w_type.mro_w)) + compute_mro(w_type) + for w_sc in w_type.get_subclasses(): + assert isinstance(w_sc, W_TypeObject) + mro_subclasses(space, w_sc, temp) + +def descr_set__bases__(space, w_type, w_value): + # this assumes all app-level type objects are W_TypeObject + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + + w_type = _check(space, w_type) + if not w_type.is_heaptype(): + raise operationerrfmt(space.w_TypeError, + "can't set %s.__bases__", w_type.name) + if not space.isinstance_w(w_value, space.w_tuple): + raise operationerrfmt(space.w_TypeError, + "can only assign tuple to %s.__bases__, not %s", + w_type.name, + space.type(w_value).getname(space)) + newbases_w = space.fixedview(w_value) + if len(newbases_w) == 0: + raise operationerrfmt(space.w_TypeError, + "can only assign non-empty tuple to %s.__bases__, not ()", + w_type.name) + + for w_newbase in newbases_w: + if isinstance(w_newbase, W_TypeObject): + if w_type in w_newbase.compute_default_mro(): + raise OperationError(space.w_TypeError, + space.wrap("a __bases__ item causes" + " an inheritance cycle")) + + w_oldbestbase = check_and_find_best_base(space, w_type.bases_w) + w_newbestbase = check_and_find_best_base(space, newbases_w) + oldlayout = w_oldbestbase.get_full_instance_layout() + newlayout = w_newbestbase.get_full_instance_layout() + + if oldlayout != newlayout: + raise operationerrfmt(space.w_TypeError, + "__bases__ assignment: '%s' object layout" + " differs from '%s'", + w_newbestbase.getname(space), + w_oldbestbase.getname(space)) + + # invalidate the version_tag of all the current subclasses + w_type.mutated(None) + + # now we can go ahead and change 'w_type.bases_w' + saved_bases_w = w_type.bases_w + temp = [] + try: + for w_oldbase in saved_bases_w: + if isinstance(w_oldbase, W_TypeObject): + w_oldbase.remove_subclass(w_type) + w_type.bases_w = newbases_w + for w_newbase in newbases_w: + if isinstance(w_newbase, W_TypeObject): + w_newbase.add_subclass(w_type) + # try to recompute all MROs + mro_subclasses(space, w_type, temp) + except: + for cls, old_mro in temp: + cls.mro_w = old_mro + w_type.bases_w = saved_bases_w + raise + if (space.config.objspace.std.withtypeversion and + w_type.version_tag() is not None and + not is_mro_purely_of_types(w_type.mro_w)): + # Disable method cache if the hierarchy isn't pure. + w_type._version_tag = None + for w_subclass in w_type.get_subclasses(): + if isinstance(w_subclass, W_TypeObject): + w_subclass._version_tag = None + assert w_type.w_same_layout_as is get_parent_layout(w_type) # invariant + +def descr__base(space, w_type): + from pypy.objspace.std.typeobject import find_best_base + w_type = _check(space, w_type) + return find_best_base(space, w_type.bases_w) + +def descr__doc(space, w_type): + if space.is_w(w_type, space.w_type): + return space.wrap("""type(object) -> the object's type +type(name, bases, dict) -> a new type""") + w_type = _check(space, w_type) + if not w_type.is_heaptype(): + return w_type.w_doc + w_result = w_type.getdictvalue(space, '__doc__') + if w_result is None: + return space.w_None + else: + return space.get(w_result, space.w_None, w_type) + +def descr__flags(space, w_type): + from copy_reg import _HEAPTYPE + _CPYTYPE = 1 # used for non-heap types defined in C + _ABSTRACT = 1 << 20 + # + w_type = _check(space, w_type) + flags = 0 + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT + return space.wrap(flags) + +def descr_get__module(space, w_type): + w_type = _check(space, w_type) + return w_type.get_module() + +def descr_set__module(space, w_type, w_value): + w_type = _check(space, w_type) + w_type.setdictvalue(space, '__module__', w_value) + +def descr_get___abstractmethods__(space, w_type): + w_type = _check(space, w_type) + # type itself has an __abstractmethods__ descriptor (this). Don't return it + if not space.is_w(w_type, space.w_type): + w_result = w_type.getdictvalue(space, "__abstractmethods__") + if w_result is not None: + return w_result + raise OperationError(space.w_AttributeError, + space.wrap("__abstractmethods__")) + +def descr_set___abstractmethods__(space, w_type, w_new): + w_type = _check(space, w_type) + w_type.setdictvalue(space, "__abstractmethods__", w_new) + w_type.set_abstract(space.is_true(w_new)) + +def descr_del___abstractmethods__(space, w_type): + w_type = _check(space, w_type) + if not w_type.deldictvalue(space, "__abstractmethods__"): + raise OperationError(space.w_AttributeError, + space.wrap("__abstractmethods__")) + w_type.set_abstract(False) + +def descr___subclasses__(space, w_type): + """Return the list of immediate subclasses.""" + w_type = _check(space, w_type) + return space.newlist(w_type.get_subclasses()) + +# ____________________________________________________________ + + at gateway.unwrap_spec(w_obj=W_TypeObject, w_sub=W_TypeObject) +def type_issubtype(w_obj, space, w_sub): + return space.newbool(w_sub.issubtype(w_obj)) + + at gateway.unwrap_spec(w_obj=W_TypeObject) +def type_isinstance(w_obj, space, w_inst): + return space.newbool(space.type(w_inst).issubtype(w_obj)) + +type_typedef = StdTypeDef("type", + __new__ = gateway.interp2app(descr__new__), + __name__ = GetSetProperty(descr_get__name__, descr_set__name__), + __bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__), + __base__ = GetSetProperty(descr__base), + __mro__ = GetSetProperty(descr_get__mro__), + __dict__ = GetSetProperty(descr_get_dict), + __doc__ = GetSetProperty(descr__doc), + mro = gateway.interp2app(descr_mro), + __flags__ = GetSetProperty(descr__flags), + __module__ = GetSetProperty(descr_get__module, descr_set__module), + __abstractmethods__ = GetSetProperty(descr_get___abstractmethods__, + descr_set___abstractmethods__, + descr_del___abstractmethods__), + __subclasses__ = gateway.interp2app(descr___subclasses__), + __weakref__ = weakref_descr, + __instancecheck__ = gateway.interp2app(type_isinstance), + __subclasscheck__ = gateway.interp2app(type_issubtype), + ) +W_TypeObject.typedef = type_typedef + # ____________________________________________________________ # Initialization of type objects @@ -894,6 +1173,7 @@ def eq__Type_Type(space, w_self, w_other): return space.is_(w_self, w_other) + # ____________________________________________________________ diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py deleted file mode 100644 --- a/pypy/objspace/std/typetype.py +++ /dev/null @@ -1,275 +0,0 @@ -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, - weakref_descr) -from pypy.objspace.std.stdtypedef import StdTypeDef - - -def descr__new__(space, w_typetype, w_name, w_bases=None, w_dict=None): - - "This is used to create user-defined classes only." - # XXX check types - - w_typetype = _precheck_for_new(space, w_typetype) - - # special case for type(x) - if (space.is_w(space.type(w_typetype), space.w_type) and w_bases is None and - w_dict is None): - return space.type(w_name) - else: - return _create_new_type(space, w_typetype, w_name, w_bases, w_dict) - - -def _create_new_type(space, w_typetype, w_name, w_bases, w_dict): - # this is in its own function because we want the special case 'type(x)' - # above to be seen by the jit. - from pypy.objspace.std.typeobject import W_TypeObject - - if w_bases is None or w_dict is None: - raise OperationError(space.w_TypeError, space.wrap("type() takes 1 or 3 arguments")) - - bases_w = space.fixedview(w_bases) - - w_winner = w_typetype - for base in bases_w: - w_typ = space.type(base) - if space.is_w(w_typ, space.w_classobj): - continue # special-case old-style classes - if space.is_true(space.issubtype(w_winner, w_typ)): - continue - if space.is_true(space.issubtype(w_typ, w_winner)): - w_winner = w_typ - continue - raise OperationError(space.w_TypeError, - space.wrap("metaclass conflict: " - "the metaclass of a derived class " - "must be a (non-strict) subclass " - "of the metaclasses of all its bases")) - - if not space.is_w(w_winner, w_typetype): - newfunc = space.getattr(w_winner, space.wrap('__new__')) - if not space.is_w(newfunc, space.getattr(space.w_type, space.wrap('__new__'))): - return space.call_function(newfunc, w_winner, w_name, w_bases, w_dict) - w_typetype = w_winner - - name = space.str_w(w_name) - assert isinstance(name, str) - dict_w = {} - dictkeys_w = space.listview(w_dict) - for w_key in dictkeys_w: - key = space.str_w(w_key) - dict_w[key] = space.getitem(w_dict, w_key) - w_type = space.allocate_instance(W_TypeObject, w_typetype) - W_TypeObject.__init__(w_type, space, name, bases_w or [space.w_object], - dict_w) - w_type.ready() - return w_type - -def _precheck_for_new(space, w_type): - from pypy.objspace.std.typeobject import W_TypeObject - if not isinstance(w_type, W_TypeObject): - raise operationerrfmt(space.w_TypeError, - "X is not a type object (%s)", - space.type(w_type).getname(space)) - return w_type - -# ____________________________________________________________ - -def _check(space, w_type, w_msg=None): - from pypy.objspace.std.typeobject import W_TypeObject - if not isinstance(w_type, W_TypeObject): - if w_msg is None: - w_msg = space.wrap("descriptor is for 'type'") - raise OperationError(space.w_TypeError, w_msg) - return w_type - - -def descr_get__name__(space, w_type): - w_type = _check(space, w_type) - return space.wrap(w_type.name) - -def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) - if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, - "can't set %s.__name__", w_type.name) - w_type.name = space.str_w(w_value) - -def descr_get__mro__(space, w_type): - w_type = _check(space, w_type) - return space.newtuple(w_type.mro_w) - -def descr_mro(space, w_type): - """Return a type's method resolution order.""" - w_type = _check(space, w_type, space.wrap("expected type")) - return space.newlist(w_type.compute_default_mro()) - -def descr_get__bases__(space, w_type): - w_type = _check(space, w_type) - return space.newtuple(w_type.bases_w) - -def mro_subclasses(space, w_type, temp): - from pypy.objspace.std.typeobject import W_TypeObject, compute_mro - temp.append((w_type, w_type.mro_w)) - compute_mro(w_type) - for w_sc in w_type.get_subclasses(): - assert isinstance(w_sc, W_TypeObject) - mro_subclasses(space, w_sc, temp) - -def descr_set__bases__(space, w_type, w_value): - # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, - check_and_find_best_base, is_mro_purely_of_types) - - w_type = _check(space, w_type) - if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, - "can't set %s.__bases__", w_type.name) - if not space.isinstance_w(w_value, space.w_tuple): - raise operationerrfmt(space.w_TypeError, - "can only assign tuple to %s.__bases__, not %s", - w_type.name, - space.type(w_value).getname(space)) - newbases_w = space.fixedview(w_value) - if len(newbases_w) == 0: - raise operationerrfmt(space.w_TypeError, - "can only assign non-empty tuple to %s.__bases__, not ()", - w_type.name) - - for w_newbase in newbases_w: - if isinstance(w_newbase, W_TypeObject): - if w_type in w_newbase.compute_default_mro(): - raise OperationError(space.w_TypeError, - space.wrap("a __bases__ item causes" - " an inheritance cycle")) - - w_oldbestbase = check_and_find_best_base(space, w_type.bases_w) - w_newbestbase = check_and_find_best_base(space, newbases_w) - oldlayout = w_oldbestbase.get_full_instance_layout() - newlayout = w_newbestbase.get_full_instance_layout() - - if oldlayout != newlayout: - raise operationerrfmt(space.w_TypeError, - "__bases__ assignment: '%s' object layout" - " differs from '%s'", - w_newbestbase.getname(space), - w_oldbestbase.getname(space)) - - # invalidate the version_tag of all the current subclasses - w_type.mutated(None) - - # now we can go ahead and change 'w_type.bases_w' - saved_bases_w = w_type.bases_w - temp = [] - try: - for w_oldbase in saved_bases_w: - if isinstance(w_oldbase, W_TypeObject): - w_oldbase.remove_subclass(w_type) - w_type.bases_w = newbases_w - for w_newbase in newbases_w: - if isinstance(w_newbase, W_TypeObject): - w_newbase.add_subclass(w_type) - # try to recompute all MROs - mro_subclasses(space, w_type, temp) - except: - for cls, old_mro in temp: - cls.mro_w = old_mro - w_type.bases_w = saved_bases_w - raise - if (space.config.objspace.std.withtypeversion and - w_type.version_tag() is not None and - not is_mro_purely_of_types(w_type.mro_w)): - # Disable method cache if the hierarchy isn't pure. - w_type._version_tag = None - for w_subclass in w_type.get_subclasses(): - if isinstance(w_subclass, W_TypeObject): - w_subclass._version_tag = None - assert w_type.w_same_layout_as is get_parent_layout(w_type) # invariant - -def descr__base(space, w_type): - from pypy.objspace.std.typeobject import find_best_base - w_type = _check(space, w_type) - return find_best_base(space, w_type.bases_w) - -def descr__doc(space, w_type): - if space.is_w(w_type, space.w_type): - return space.wrap("""type(object) -> the object's type -type(name, bases, dict) -> a new type""") - w_type = _check(space, w_type) - if not w_type.is_heaptype(): - return w_type.w_doc - w_result = w_type.getdictvalue(space, '__doc__') - if w_result is None: - return space.w_None - else: - return space.get(w_result, space.w_None, w_type) - -def descr__flags(space, w_type): - from copy_reg import _HEAPTYPE - _CPYTYPE = 1 # used for non-heap types defined in C - _ABSTRACT = 1 << 20 - # - w_type = _check(space, w_type) - flags = 0 - if w_type.flag_heaptype: - flags |= _HEAPTYPE - if w_type.flag_cpytype: - flags |= _CPYTYPE - if w_type.flag_abstract: - flags |= _ABSTRACT - return space.wrap(flags) - -def descr_get__module(space, w_type): - w_type = _check(space, w_type) - return w_type.get_module() - -def descr_set__module(space, w_type, w_value): - w_type = _check(space, w_type) - w_type.setdictvalue(space, '__module__', w_value) - -def descr_get___abstractmethods__(space, w_type): - w_type = _check(space, w_type) - # type itself has an __abstractmethods__ descriptor (this). Don't return it - if not space.is_w(w_type, space.w_type): - w_result = w_type.getdictvalue(space, "__abstractmethods__") - if w_result is not None: - return w_result - raise OperationError(space.w_AttributeError, - space.wrap("__abstractmethods__")) - -def descr_set___abstractmethods__(space, w_type, w_new): - w_type = _check(space, w_type) - w_type.setdictvalue(space, "__abstractmethods__", w_new) - w_type.set_abstract(space.is_true(w_new)) - -def descr_del___abstractmethods__(space, w_type): - w_type = _check(space, w_type) - if not w_type.deldictvalue(space, "__abstractmethods__"): - raise OperationError(space.w_AttributeError, - space.wrap("__abstractmethods__")) - w_type.set_abstract(False) - -def descr___subclasses__(space, w_type): - """Return the list of immediate subclasses.""" - w_type = _check(space, w_type) - return space.newlist(w_type.get_subclasses()) - -# ____________________________________________________________ - -type_typedef = StdTypeDef("type", - __new__ = gateway.interp2app(descr__new__), - __name__ = GetSetProperty(descr_get__name__, descr_set__name__), - __bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__), - __base__ = GetSetProperty(descr__base), - __mro__ = GetSetProperty(descr_get__mro__), - __dict__ = GetSetProperty(descr_get_dict), - __doc__ = GetSetProperty(descr__doc), - mro = gateway.interp2app(descr_mro), - __flags__ = GetSetProperty(descr__flags), - __module__ = GetSetProperty(descr_get__module, descr_set__module), - __abstractmethods__ = GetSetProperty(descr_get___abstractmethods__, - descr_set___abstractmethods__, - descr_del___abstractmethods__), - __subclasses__ = gateway.interp2app(descr___subclasses__), - __weakref__ = weakref_descr, - ) From noreply at buildbot.pypy.org Sun Mar 24 03:48:03 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Mar 2013 03:48:03 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130324024803.6B3931C016E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62718:f99fd433cd40 Date: 2013-03-23 19:47 -0700 http://bitbucket.org/pypy/pypy/changeset/f99fd433cd40/ Log: merge diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -913,7 +913,7 @@ if self.is_w(w_exc_type, w_check_class): return True # fast path (also here to handle string exceptions) try: - if self.is_true(self.isinstance(w_check_class, self.w_tuple)): + if self.isinstance_w(w_check_class, self.w_tuple): for w_t in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_t): return True @@ -1052,11 +1052,11 @@ def abstract_isinstance_w(self, w_obj, w_cls): # Equivalent to 'isinstance(obj, cls)'. - return self.is_true(self.isinstance(w_obj, w_cls)) + return self.isinstance_w(w_obj, w_cls) def abstract_isclass_w(self, w_obj): # Equivalent to 'isinstance(obj, type)'. - return self.is_true(self.isinstance(w_obj, self.w_type)) + return self.isinstance_w(w_obj, self.w_type) def abstract_getclass(self, w_obj): # Equivalent to 'obj.__class__'. @@ -1094,7 +1094,7 @@ expression = compiler.compile(expression, '?', 'eval', 0, hidden_applevel=hidden_applevel) else: - raise TypeError, 'space.eval(): expected a string, code or PyCode object' + raise TypeError('space.eval(): expected a string, code or PyCode object') return expression.exec_code(self, w_globals, w_locals) def exec_(self, statement, w_globals, w_locals, hidden_applevel=False, @@ -1108,7 +1108,7 @@ statement = compiler.compile(statement, filename, 'exec', 0, hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): - raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') if not self.is_true(self.contains(w_globals, w_key)): self.setitem(w_globals, w_key, self.wrap(self.builtin)) @@ -1164,7 +1164,7 @@ -> (index, 0, 0) or (start, stop, step) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) @@ -1184,7 +1184,7 @@ -> (index, 0, 0, 1) or (start, stop, step, slice_length) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step, length = w_index_or_slice.indices4(self, @@ -1326,7 +1326,7 @@ def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. - if not self.is_true(self.isinstance(w_obj, self.w_str)): + if not self.isinstance_w(w_obj, self.w_str): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) return self.str_w(w_obj) @@ -1346,7 +1346,7 @@ def realunicode_w(self, w_obj): # Like unicode_w, but only works if w_obj is really of type # 'unicode'. - if not self.is_true(self.isinstance(w_obj, self.w_unicode)): + if not self.isinstance_w(w_obj, self.w_unicode): raise OperationError(self.w_TypeError, self.wrap('argument must be a unicode')) return self.unicode_w(w_obj) @@ -1367,19 +1367,19 @@ return self.float_w(self.float(w_obj)) def gateway_r_longlong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_longlong_w(self.int(w_obj)) def gateway_r_uint_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.uint_w(self.int(w_obj)) def gateway_r_ulonglong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_ulonglong_w(self.int(w_obj)) @@ -1496,15 +1496,20 @@ space.exec_(str(source), w_glob, w_glob) return space.getitem(w_glob, space.wrap('anonymous')) + class DummyLock(object): def acquire(self, flag): return True + def release(self): pass + def _freeze_(self): return True + def __enter__(self): pass + def __exit__(self, *args): pass @@ -1539,7 +1544,7 @@ ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), - ('abs' , 'abs', 1, ['__abs__']), + ('abs', 'abs', 1, ['__abs__']), ('hex', 'hex', 1, ['__hex__']), ('oct', 'oct', 1, ['__oct__']), ('ord', 'ord', 1, []), @@ -1592,12 +1597,12 @@ ('delete', 'delete', 2, ['__delete__']), ('userdel', 'del', 1, ['__del__']), ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py - ] +] ObjSpace.BuiltinModuleTable = [ '__builtin__', 'sys', - ] +] ObjSpace.ConstantTable = [ 'None', @@ -1605,7 +1610,7 @@ 'True', 'Ellipsis', 'NotImplemented', - ] +] ObjSpace.ExceptionTable = [ 'ArithmeticError', @@ -1648,7 +1653,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', - ] +] if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] 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 @@ -6,6 +6,7 @@ from pypy.objspace.std.register_all import register_all from pypy.objspace.std.intobject import W_IntObject + class W_BoolObject(W_Object): from pypy.objspace.std.booltype import bool_typedef as typedef _immutable_fields_ = ['boolval'] @@ -37,7 +38,7 @@ return float(self.boolval) def int(self, space): - return self + return space.newint(int(self.boolval)) registerimplementation(W_BoolObject) 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 @@ -11,19 +11,24 @@ 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")) - + def test_true(self): assert self.space.is_true(self.true) - + def test_false(self): assert not self.space.is_true(self.false) + def test_int_w(self): + assert self.space.int_w(self.true) is 1 + assert self.space.int_w(self.false) is 0 + def test_uint_w(self): assert self.space.uint_w(self.true) == 1 + assert self.space.uint_w(self.false) == 0 def test_rbigint_w(self): assert self.space.bigint_w(self.true)._digits == [1] - + class AppTestAppBoolTest: def test_bool_callable(self): assert True == bool(1) @@ -36,6 +41,10 @@ assert "True" == repr(True) assert "False" == repr(False) + def test_bool_int(self): + assert int(True) is 1 + assert int(False) is 0 + def test_bool_ops(self): assert True + True == 2 assert False | False is False diff --git a/rpython/jit/backend/conftest.py b/rpython/jit/backend/conftest.py --- a/rpython/jit/backend/conftest.py +++ b/rpython/jit/backend/conftest.py @@ -2,7 +2,7 @@ This conftest adds options used by test/test_random and x86/test/test_zll_random. """ -import py, random +import random def pytest_addoption(parser): group = parser.getgroup('random test options') diff --git a/rpython/jit/codewriter/format.py b/rpython/jit/codewriter/format.py --- a/rpython/jit/codewriter/format.py +++ b/rpython/jit/codewriter/format.py @@ -10,8 +10,7 @@ def format_assembler(ssarepr): """For testing: format a SSARepr as a multiline string.""" from cStringIO import StringIO - seen = {} - # + def repr(x): if isinstance(x, Register): return '%%%s%d' % (x.kind[0], x.index) # e.g. %i1 or %r2 or %f3 @@ -32,7 +31,7 @@ return '%r' % (x,) else: return '' % (x,) - # + seenlabels = {} for asm in ssarepr.insns: for x in asm: @@ -47,7 +46,7 @@ labelcount[0] += 1 seenlabels[lbl.name] = labelcount[0] return 'L%d' % seenlabels[lbl.name] - # + output = StringIO() insns = ssarepr.insns if insns and insns[-1] == ('---',): diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -3,7 +3,7 @@ from rpython.jit.metainterp.compile import ResumeAtPositionDescr from rpython.jit.metainterp.jitexc import JitException, get_llexception, reraise from rpython.rlib import longlong2float -from rpython.rlib.debug import debug_start, debug_stop, ll_assert, make_sure_not_resized +from rpython.rlib.debug import ll_assert, make_sure_not_resized from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck from rpython.rlib.rtimer import read_timestamp diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -9,11 +9,10 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist -from rpython.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken +from rpython.jit.metainterp.history import TreeLoop, Box, JitCellToken, TargetToken from rpython.jit.metainterp.history import AbstractFailDescr, BoxInt -from rpython.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const, ConstInt +from rpython.jit.metainterp.history import BoxPtr, BoxFloat, ConstInt from rpython.jit.metainterp import history, resume -from rpython.jit.metainterp.typesystem import llhelper, oohelper from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.inliner import Inliner from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP @@ -140,7 +139,7 @@ assert isinstance(target_token, TargetToken) all_target_tokens = [target_token] - loop = create_empty_loop(metainterp) + loop = create_empty_loop(metainterp) loop.inputargs = part.inputargs loop.operations = part.operations loop.quasi_immutable_deps = {} @@ -163,7 +162,7 @@ optimize_trace(metainterp_sd, part, enable_opts) except InvalidLoop: return None - + loop.operations = loop.operations[:-1] + part.operations if part.quasi_immutable_deps: loop.quasi_immutable_deps.update(part.quasi_immutable_deps) @@ -224,7 +223,6 @@ try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts, inline_short_preamble=False) - except InvalidLoop: return None assert part.operations[-1].getopnum() != rop.LABEL @@ -249,9 +247,9 @@ for box in loop.inputargs: assert isinstance(box, Box) - target_token = loop.operations[-1].getdescr() + target_token = loop.operations[-1].getdescr() resumekey.compile_and_attach(metainterp, loop) - + target_token = label.getdescr() assert isinstance(target_token, TargetToken) record_loop_or_bridge(metainterp_sd, loop) @@ -486,7 +484,7 @@ _counters = None # they get stored in _counters then. # this class also gets the following attributes stored by resume.py code - + # XXX move all of unused stuff to guard_op, now that we can have # a separate class, so it does not survive that long rd_snapshot = None @@ -803,7 +801,6 @@ # with completely unoptimized arguments, as in the interpreter. metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd - redargs = new_loop.inputargs new_loop.original_jitcell_token = jitcell_token = make_jitcell_token(jitdriver_sd) propagate_original_jitcell_token(new_loop) send_loop_to_backend(self.original_greenkey, metainterp.jitdriver_sd, @@ -819,14 +816,14 @@ to some existing place. """ from rpython.jit.metainterp.optimizeopt import optimize_trace - + # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. # # Attempt to use optimize_bridge(). This may return None in case # it does not work -- i.e. none of the existing old_loop_tokens match. new_trace = create_empty_loop(metainterp) - new_trace.inputargs = inputargs = metainterp.history.inputargs[:] + new_trace.inputargs = metainterp.history.inputargs[:] # clone ops, as optimize_bridge can mutate the ops new_trace.operations = [op.clone() for op in metainterp.history.operations] @@ -856,7 +853,6 @@ else: metainterp.retrace_needed(new_trace) return None - # ____________________________________________________________ diff --git a/rpython/jit/metainterp/greenfield.py b/rpython/jit/metainterp/greenfield.py --- a/rpython/jit/metainterp/greenfield.py +++ b/rpython/jit/metainterp/greenfield.py @@ -1,8 +1,4 @@ -from rpython.jit.metainterp.typesystem import deref - - class GreenFieldInfo(object): - def __init__(self, cpu, jd): self.cpu = cpu self.jitdriver_sd = jd 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 @@ -1,4 +1,3 @@ - from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.ootypesystem import ootype @@ -175,7 +174,7 @@ class BasicFinalDescr(AbstractFailDescr): final_descr = True - + def __init__(self, identifier=None): self.identifier = identifier # for testing diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py --- a/rpython/jit/metainterp/quasiimmut.py +++ b/rpython/jit/metainterp/quasiimmut.py @@ -1,4 +1,3 @@ -import weakref from rpython.rtyper.lltypesystem import lltype, rclass from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance from rpython.jit.metainterp.history import AbstractDescr diff --git a/rpython/jit/metainterp/warmspot.py b/rpython/jit/metainterp/warmspot.py --- a/rpython/jit/metainterp/warmspot.py +++ b/rpython/jit/metainterp/warmspot.py @@ -1,12 +1,11 @@ import sys, py from rpython.tool.sourcetools import func_with_new_name -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator,\ cast_base_ptr_to_instance, hlstr from rpython.annotator import model as annmodel from rpython.rtyper.llinterp import LLException from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache -from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.flowspace.model import checkgraph, Link, copygraph from rpython.rlib.objectmodel import we_are_translated diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py --- a/rpython/jit/metainterp/warmstate.py +++ b/rpython/jit/metainterp/warmstate.py @@ -12,7 +12,6 @@ from rpython.rlib.debug import debug_start, debug_stop, debug_print from rpython.jit.metainterp import history from rpython.jit.codewriter import support, heaptracker, longlong -from rpython.tool.sourcetools import func_with_new_name # ____________________________________________________________ diff --git a/rpython/jit/tool/loopcounter.py b/rpython/jit/tool/loopcounter.py --- a/rpython/jit/tool/loopcounter.py +++ b/rpython/jit/tool/loopcounter.py @@ -3,7 +3,6 @@ Parse and display the traces produced by pypy-c-jit when PYPYLOG is set. """ -import py import sys import optparse import re diff --git a/rpython/jit/tool/loopviewer.py b/rpython/jit/tool/loopviewer.py --- a/rpython/jit/tool/loopviewer.py +++ b/rpython/jit/tool/loopviewer.py @@ -3,14 +3,10 @@ Parse and display the traces produced by pypy-c-jit when PYPYLOG is set. """ -import py import sys import optparse -from pprint import pprint from rpython.tool import logparser from rpython.jit.tool.oparser import parse -from rpython.jit.metainterp.history import ConstInt -from rpython.rtyper.lltypesystem import llmemory, lltype def main(loopfile, options): print 'Loading file:' @@ -19,7 +15,7 @@ if not options.quiet: for loop in loops: loop.show() - + if options.summary: print print 'Summary:' diff --git a/rpython/jit/tool/showstats.py b/rpython/jit/tool/showstats.py --- a/rpython/jit/tool/showstats.py +++ b/rpython/jit/tool/showstats.py @@ -1,11 +1,10 @@ #!/usr/bin/env python from __future__ import division -import sys, py +import sys from rpython.tool import logparser from rpython.jit.tool.oparser import parse from rpython.jit.metainterp.resoperation import rop -from rpython.rtyper.lltypesystem import lltype, llmemory def main(argv): log = logparser.parse_log_file(argv[0]) @@ -26,6 +25,6 @@ print "Loop #%d, length: %d, opcodes: %d, guards: %d" % (i, num_ops, num_dmp, num_guards) else: print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp) - + if __name__ == '__main__': main(sys.argv[1:]) From noreply at buildbot.pypy.org Sun Mar 24 11:26:49 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 24 Mar 2013 11:26:49 +0100 (CET) Subject: [pypy-commit] pypy default: cpyext: implement PyLong_FromSize_t Message-ID: <20130324102649.C31921C1456@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r62719:cd5ce30edd5a Date: 2013-03-24 11:25 +0100 http://bitbucket.org/pypy/pypy/changeset/cd5ce30edd5a/ Log: cpyext: implement PyLong_FromSize_t diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -23,6 +23,13 @@ """ return space.newlong(val) + at cpython_api([rffi.SIZE_T], PyObject) +def PyLong_FromSize_t(space, val): + """Return a new PyLongObject object from a C size_t, or NULL on + failure. + """ + return space.wrap(val) + @cpython_api([rffi.LONGLONG], PyObject) def PyLong_FromLongLong(space, val): """Return a new PyLongObject object from a C long long, or NULL diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1395,13 +1395,6 @@ """ raise NotImplementedError - at cpython_api([rffi.SIZE_T], PyObject) -def PyLong_FromSize_t(space, v): - """Return a new PyLongObject object from a C size_t, or - NULL on failure. - """ - raise NotImplementedError - @cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.INT_real], PyObject) def PyLong_FromUnicode(space, u, length, base): """Convert a sequence of Unicode digits to a Python long integer value. The first diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -146,6 +146,15 @@ assert module.from_longlong() == -1 assert module.from_unsignedlonglong() == (1<<64) - 1 + def test_from_size_t(self): + module = self.import_extension('foo', [ + ("from_unsignedlong", "METH_NOARGS", + """ + return PyLong_FromSize_t((size_t)-1); + """)]) + import sys + assert module.from_unsignedlong() == 2 * sys.maxint + 1 + def test_fromstring(self): module = self.import_extension('foo', [ ("from_string", "METH_NOARGS", From noreply at buildbot.pypy.org Sun Mar 24 12:03:42 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:03:42 +0100 (CET) Subject: [pypy-commit] pypy default: fix test Message-ID: <20130324110342.253B21C0AD6@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62721:5653a9fd7594 Date: 2013-03-24 11:33 +0200 http://bitbucket.org/pypy/pypy/changeset/5653a9fd7594/ Log: fix test diff --git a/rpython/jit/backend/arm/test/test_trace_operations.py b/rpython/jit/backend/arm/test/test_trace_operations.py --- a/rpython/jit/backend/arm/test/test_trace_operations.py +++ b/rpython/jit/backend/arm/test/test_trace_operations.py @@ -26,12 +26,11 @@ ops = ''' [i0] i1 = int_add(i0, 1) - finish(i1, ConstPtr(ptr0)) + finish(ConstPtr(ptr0)) ''' - self.interpret(ops, [99]) - assert self.getint(0) == 100 - ptr = self.cpu.get_latest_value_ref(1) - assert self.ptr0 == ptr + loop = self.interpret(ops, [99]) + ptr = self.getptr(0, lltype.Ptr(self.S)) + assert self.struct_ptr == ptr def test_getfield_with_offset_gt_one_byte(self): self.struct_ptr.int1049 = 666 From noreply at buildbot.pypy.org Sun Mar 24 12:03:40 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:03:40 +0100 (CET) Subject: [pypy-commit] pypy default: add build_regalloc test helper Message-ID: <20130324110340.A38C41C00E4@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62720:37563d43267c Date: 2013-03-24 11:14 +0200 http://bitbucket.org/pypy/pypy/changeset/37563d43267c/ Log: add build_regalloc test helper 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 @@ -105,6 +105,12 @@ l[i].counter = ll_s.i return l + def build_regalloc(self): + ''' for tests''' + from rpython.jit.backend.arm.regalloc import Regalloc + assert self.assembler is not None + return Regalloc(self.assembler) + class CPU_ARM(AbstractARMCPU): """ARM v7 uses softfp ABI, requires vfp""" backend_name = "arm" From noreply at buildbot.pypy.org Sun Mar 24 12:03:43 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:03:43 +0100 (CET) Subject: [pypy-commit] pypy default: fix tests Message-ID: <20130324110343.5E9F61C00E4@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62722:9c3bfca89540 Date: 2013-03-24 12:03 +0200 http://bitbucket.org/pypy/pypy/changeset/9c3bfca89540/ Log: fix tests diff --git a/rpython/jit/backend/arm/test/test_regalloc2.py b/rpython/jit/backend/arm/test/test_regalloc2.py --- a/rpython/jit/backend/arm/test/test_regalloc2.py +++ b/rpython/jit/backend/arm/test/test_regalloc2.py @@ -1,6 +1,6 @@ import py from rpython.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\ - BoxPtr, ConstPtr, BasicFailDescr + BoxPtr, ConstPtr, BasicFailDescr, BasicFinalDescr from rpython.jit.metainterp.history import JitCellToken from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.detect_cpu import getcpuclass @@ -17,15 +17,17 @@ ResOperation(rop.INT_ADD, [v1, v1], v2), ResOperation(rop.INT_INVERT, [v2], v3), ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4), - ResOperation(rop.FINISH, [v4, v3], None, descr=BasicFailDescr()), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), + ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(1)), ] + operations[-2].setfailargs([v4, v3]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) - cpu.execute_token(looptoken, 9) - assert cpu.get_latest_value_int(0) == (9 >> 3) - assert cpu.get_latest_value_int(1) == (~18) + deadframe = cpu.execute_token(looptoken, 9) + assert cpu.get_int_value(deadframe, 0) == (9 >> 3) + assert cpu.get_int_value(deadframe, 1) == (~18) def test_bug_int_is_true_1(): v1 = BoxInt() @@ -39,16 +41,18 @@ ResOperation(rop.INT_MUL, [v2, v1], v3), ResOperation(rop.INT_IS_TRUE, [v2], tmp5), ResOperation(rop.INT_IS_ZERO, [tmp5], v4), - ResOperation(rop.FINISH, [v4, v3, tmp5], None, descr=BasicFailDescr()), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), + ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr()), ] + operations[-2].setfailargs([v4, v3, tmp5]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) - cpu.execute_token(looptoken, -10) - assert cpu.get_latest_value_int(0) == 0 - assert cpu.get_latest_value_int(1) == -1000 - assert cpu.get_latest_value_int(2) == 1 + deadframe = cpu.execute_token(looptoken, -10) + assert cpu.get_int_value(deadframe, 0) == 0 + assert cpu.get_int_value(deadframe, 1) == -1000 + assert cpu.get_int_value(deadframe, 2) == 1 def test_bug_0(): v1 = BoxInt() @@ -135,28 +139,29 @@ ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38), ResOperation(rop.INT_NEG, [v7], v39), ResOperation(rop.INT_GT, [v24, v32], v40), - ResOperation(rop.FINISH, [v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38], None, descr=BasicFailDescr()), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), ] + operations[-1].setfailargs([v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] - cpu.execute_token(looptoken, *args) - assert cpu.get_latest_value_int(0) == 0 - assert cpu.get_latest_value_int(1) == 0 - assert cpu.get_latest_value_int(2) == 0 - assert cpu.get_latest_value_int(3) == 0 - assert cpu.get_latest_value_int(4) == 1 - assert cpu.get_latest_value_int(5) == -7 - assert cpu.get_latest_value_int(6) == 1 - assert cpu.get_latest_value_int(7) == 0 - assert cpu.get_latest_value_int(8) == -2 - assert cpu.get_latest_value_int(9) == 18 - assert cpu.get_latest_value_int(10) == 1 - assert cpu.get_latest_value_int(11) == 18 - assert cpu.get_latest_value_int(12) == -1 - assert cpu.get_latest_value_int(13) == 0 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_int_value(deadframe, 0) == 0 + assert cpu.get_int_value(deadframe, 1) == 0 + assert cpu.get_int_value(deadframe, 2) == 0 + assert cpu.get_int_value(deadframe, 3) == 0 + assert cpu.get_int_value(deadframe, 4) == 1 + assert cpu.get_int_value(deadframe, 5) == -7 + assert cpu.get_int_value(deadframe, 6) == 1 + assert cpu.get_int_value(deadframe, 7) == 0 + assert cpu.get_int_value(deadframe, 8) == -2 + assert cpu.get_int_value(deadframe, 9) == 18 + assert cpu.get_int_value(deadframe, 10) == 1 + assert cpu.get_int_value(deadframe, 11) == 18 + assert cpu.get_int_value(deadframe, 12) == -1 + assert cpu.get_int_value(deadframe, 13) == 0 def test_bug_1(): v1 = BoxInt() @@ -241,35 +246,36 @@ ResOperation(rop.INT_GT, [v4, v11], v38), ResOperation(rop.INT_LT, [v27, v22], v39), ResOperation(rop.INT_NEG, [v27], v40), - ResOperation(rop.FINISH, [v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37], None, descr=BasicFailDescr()), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), ] + operations[-1].setfailargs([v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8] - cpu.execute_token(looptoken, *args) - assert cpu.get_latest_value_int(0) == 0 - assert cpu.get_latest_value_int(1) == 8 - assert cpu.get_latest_value_int(2) == 1 - assert cpu.get_latest_value_int(3) == 131072 - assert cpu.get_latest_value_int(4) == 20 - assert cpu.get_latest_value_int(5) == -1 - assert cpu.get_latest_value_int(6) == 0 - assert cpu.get_latest_value_int(7) == -19 - assert cpu.get_latest_value_int(8) == 6 - assert cpu.get_latest_value_int(9) == 26 - assert cpu.get_latest_value_int(10) == 12 - assert cpu.get_latest_value_int(11) == 0 - assert cpu.get_latest_value_int(12) == 0 - assert cpu.get_latest_value_int(13) == 2 - assert cpu.get_latest_value_int(14) == 2 - assert cpu.get_latest_value_int(15) == 1 - assert cpu.get_latest_value_int(16) == -57344 - assert cpu.get_latest_value_int(17) == 1 - assert cpu.get_latest_value_int(18) == -1 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_int_value(deadframe, 0) == 0 + assert cpu.get_int_value(deadframe, 1) == 8 + assert cpu.get_int_value(deadframe, 2) == 1 + assert cpu.get_int_value(deadframe, 3) == 131072 + assert cpu.get_int_value(deadframe, 4) == 20 + assert cpu.get_int_value(deadframe, 5) == -1 + assert cpu.get_int_value(deadframe, 6) == 0 + assert cpu.get_int_value(deadframe, 7) == -19 + assert cpu.get_int_value(deadframe, 8) == 6 + assert cpu.get_int_value(deadframe, 9) == 26 + assert cpu.get_int_value(deadframe, 10) == 12 + assert cpu.get_int_value(deadframe, 11) == 0 + assert cpu.get_int_value(deadframe, 12) == 0 + assert cpu.get_int_value(deadframe, 13) == 2 + assert cpu.get_int_value(deadframe, 14) == 2 + assert cpu.get_int_value(deadframe, 15) == 1 + assert cpu.get_int_value(deadframe, 16) == -57344 + assert cpu.get_int_value(deadframe, 17) == 1 + assert cpu.get_int_value(deadframe, 18) == -1 if WORD == 4: - assert cpu.get_latest_value_int(19) == -2147483648 + assert cpu.get_int_value(deadframe, 19) == -2147483648 elif WORD == 8: - assert cpu.get_latest_value_int(19) == 19327352832 - assert cpu.get_latest_value_int(20) == -49 + assert cpu.get_int_value(deadframe, 19) == 19327352832 + assert cpu.get_int_value(deadframe, 20) == -49 From noreply at buildbot.pypy.org Sun Mar 24 12:03:44 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:03:44 +0100 (CET) Subject: [pypy-commit] pypy default: fix more tests Message-ID: <20130324110344.A28A51C00E4@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62723:c16334951ba0 Date: 2013-03-24 13:00 +0200 http://bitbucket.org/pypy/pypy/changeset/c16334951ba0/ Log: fix more tests diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -3,9 +3,10 @@ """ import py -from rpython.jit.metainterp.history import BasicFailDescr, \ - JitCellToken, \ - TargetToken +from rpython.jit.metainterp.history import (BasicFailDescr, + BasicFinalDescr, + JitCellToken, + TargetToken) from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.llsupport.descr import GcCache from rpython.jit.backend.detect_cpu import getcpuclass @@ -17,6 +18,7 @@ from rpython.rtyper.lltypesystem import rclass, rstr from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.codewriter import longlong +from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc def test_is_comparison_or_ovf_op(): @@ -88,7 +90,7 @@ return zer_vtable, zer_inst -class BaseTestRegalloc(object): +class CustomBaseTestRegalloc(BaseTestRegalloc): cpu = CPU(None, None) cpu.setup_once() @@ -147,77 +149,10 @@ EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) + typesystem = 'lltype' + namespace = locals().copy() - namespace = locals().copy() - type_system = 'lltype' - - def parse(self, s, boxkinds=None): - return parse(s, self.cpu, self.namespace, - type_system=self.type_system, - boxkinds=boxkinds) - - def interpret(self, ops, args, run=True): - loop = self.parse(ops) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) - arguments = [] - for arg in args: - if isinstance(arg, int): - arguments.append(arg) - elif isinstance(arg, float): - arg = longlong.getfloatstorage(arg) - arguments.append(arg) - else: - assert isinstance(lltype.typeOf(arg), lltype.Ptr) - llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) - arguments.append(llgcref) - loop._jitcelltoken = looptoken - if run: - self.cpu.execute_token(looptoken, *arguments) - return loop - - def prepare_loop(self, ops): - loop = self.parse(ops) - regalloc = Regalloc(assembler=self.cpu.assembler, - frame_manager=ARMFrameManager()) - regalloc.prepare_loop(loop.inputargs, loop.operations) - return regalloc - - def getint(self, index): - return self.cpu.get_latest_value_int(index) - - def getfloat(self, index): - v = self.cpu.get_latest_value_float(index) - return longlong.getrealfloat(v) - - def getints(self, end): - return [self.cpu.get_latest_value_int(index) for - index in range(0, end)] - - def getfloats(self, end): - return [self.getfloat(index) for - index in range(0, end)] - - def getptr(self, index, T): - gcref = self.cpu.get_latest_value_ref(index) - return lltype.cast_opaque_ptr(T, gcref) - - def attach_bridge(self, ops, loop, guard_op_index, **kwds): - guard_op = loop.operations[guard_op_index] - assert guard_op.is_guard() - bridge = self.parse(ops, **kwds) - assert ([box.type for box in bridge.inputargs] == - [box.type for box in guard_op.getfailargs()]) - faildescr = guard_op.getdescr() - self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, - loop._jitcelltoken) - return bridge - - def run(self, loop, *args): - return self.cpu.execute_token(loop._jitcelltoken, *args) - - -class TestRegallocSimple(BaseTestRegalloc): +class TestRegallocSimple(CustomBaseTestRegalloc): def test_simple_loop(self): ops = ''' [i0] @@ -273,7 +208,6 @@ ''' S = lltype.GcStruct('S') ptr = lltype.malloc(S) - self.cpu.clear_latest_values(2) self.interpret(ops, [0, ptr]) assert self.getptr(0, lltype.Ptr(S)) == ptr @@ -334,7 +268,8 @@ assert self.getint(0) == 0 bridge_ops = ''' [i0, i1] - finish(1, 2) + guard_true(i0) [i0] + finish(1) ''' self.attach_bridge(bridge_ops, loop, 0) self.run(loop, 0, 1) @@ -435,7 +370,7 @@ ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7] guard_value(i6, i1) [i0, i2, i3, i4, i5, i6] - finish(i0, i2, i3, i4, i5, i6) + finish(i0) ''' self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0]) assert self.getint(0) == 0 @@ -445,14 +380,15 @@ [i0, i1, i2, i3, i4, i5, i6, i7, i8] i9 = same_as(0) guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8] - finish(1, i0, i1, i2, i3, i4, i5, i6, i7, i8) + finish(1) ''' loop = self.interpret(ops, [0, 1, 2, 3, 4, 5, 6, 7, 8]) assert self.getint(0) == 0 bridge_ops = ''' [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8] call(ConstClass(raising_fptr), 0, descr=raising_calldescr) - finish(i0, i1, i2, i3, i4, i5, i6, i7, i8) + guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8] + finish(1) ''' self.attach_bridge(bridge_ops, loop, 1) self.run(loop, 0, 1, 2, 3, 4, 5, 6, 7, 8) @@ -465,17 +401,17 @@ jump(i4, i1, i2, i3) """ regalloc = self.prepare_loop(ops) - assert len(regalloc.rm.reg_bindings) == 4 - assert len(regalloc.frame_manager.bindings) == 0 + assert len(regalloc.rm.reg_bindings) == 0 + assert len(regalloc.frame_manager.bindings) == 4 def test_loopargs_2(self): ops = """ [i0, i1, i2, i3] i4 = int_add(i0, i1) - finish(i4, i1, i2, i3) + guard_false(i0) [i4, i1, i2, i3] """ regalloc = self.prepare_loop(ops) - assert len(regalloc.rm.reg_bindings) == 4 + assert len(regalloc.frame_manager.bindings) == 4 def test_loopargs_3(self): ops = """ @@ -485,10 +421,10 @@ jump(i4, i1, i2, i3) """ regalloc = self.prepare_loop(ops) - assert len(regalloc.rm.reg_bindings) == 4 + assert len(regalloc.frame_manager.bindings) == 4 -class TestRegallocCompOps(BaseTestRegalloc): +class TestRegallocCompOps(CustomBaseTestRegalloc): def test_cmp_op_0(self): ops = ''' @@ -496,15 +432,15 @@ i1 = same_as(1) i2 = int_lt(i0, 100) guard_true(i3) [i1, i2] - finish(0, i2) + finish(i2) ''' self.interpret(ops, [0, 1]) - assert self.getint(0) == 0 + assert self.getint(0) == 1 -class TestRegallocMoreRegisters(BaseTestRegalloc): +class TestRegallocMoreRegisters(CustomBaseTestRegalloc): - cpu = BaseTestRegalloc.cpu + cpu = CustomBaseTestRegalloc.cpu targettoken = TargetToken() S = lltype.GcStruct('S', ('field', lltype.Char)) @@ -528,7 +464,7 @@ i15 = int_is_true(i5) i16 = int_is_true(i6) i17 = int_is_true(i7) - finish(i10, i11, i12, i13, i14, i15, i16, i17) + guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17] ''' self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333]) assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1] @@ -542,7 +478,8 @@ i13 = int_eq(i5, i6) i14 = int_gt(i6, i2) i15 = int_ne(i2, i6) - finish(i10, i11, i12, i13, i14, i15) + guard_true(i15) [i10, i11, i12, i13, i14, i15] + ''' self.interpret(ops, [0, 1, 2, 3, 4, 5, 6]) assert self.getints(6) == [1, 1, 0, 0, 1, 1] @@ -625,14 +562,14 @@ # FIXME: Verify that i19 - i23 are removed -class TestRegallocFloats(BaseTestRegalloc): +class TestRegallocFloats(CustomBaseTestRegalloc): def test_float_add(self): if not self.cpu.supports_floats: py.test.skip("requires floats") ops = ''' [f0, f1] f2 = float_add(f0, f1) - finish(f2, f0, f1) + guard_value(f0, f1) [f2, f0, f1] ''' self.interpret(ops, [3.0, 1.5]) assert self.getfloats(3) == [4.5, 3.0, 1.5] @@ -644,7 +581,7 @@ [f0, f1, f2, f3, f4, f5, f6, f7, f8] f9 = float_add(f0, f1) f10 = float_add(f8, 3.5) - finish(f9, f10, f2, f3, f4, f5, f6, f7, f8) + guard_value(f0, f1) [f9, f10, f2, f3, f4, f5, f6, f7, f8] ''' self.interpret(ops, [0.1, .2, .3, .4, .5, .6, .7, .8, .9]) assert self.getfloats(9) == [.1 + .2, .9 + 3.5, .3, @@ -678,13 +615,13 @@ i7 = float_ne(f7, 0.0) i8 = float_ne(f8, 0.0) i9 = float_ne(f9, 0.0) - finish(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) + guard_true(i9), [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] ''' self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9]) assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1] -class TestRegAllocCallAndStackDepth(BaseTestRegalloc): +class TestRegAllocCallAndStackDepth(CustomBaseTestRegalloc): def expected_param_depth(self, num_args): # Assumes the arguments are all non-float return num_args @@ -693,7 +630,7 @@ ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) - finish(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9) + guard_true(i10), [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9] ''' self.interpret(ops, [4, 7, 9, 9, 9, 9, 9, 9, 9, 9]) assert self.getints(10) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9] @@ -703,7 +640,7 @@ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr) - finish(i11, i1, i2, i3, i4, i5, i6, i7, i8, i9) + guard_true(i11) [i11, i1, i2, i3, i4, i5, i6, i7, i8, i9] ''' self.interpret(ops, [4, 7, 9, 9, 9, 9, 9, 9, 9, 9]) assert self.getints(10) == [5 * 7, 7, 9, 9, 9, 9, 9, 9, 9, 9] @@ -729,7 +666,7 @@ ops = ''' [i2, i1] i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr) - finish(i3, descr=fdescr2) + finish(i3) ''' self.attach_bridge(ops, loop, -2) @@ -748,7 +685,7 @@ ops = ''' [i2] i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr) - finish(i3, descr=fdescr2) + finish(i3) ''' self.attach_bridge(ops, loop, -2) @@ -756,7 +693,7 @@ assert self.getint(0) == 29 -class TestJumps(BaseTestRegalloc): +class TestJumps(TestRegallocSimple): def test_jump_with_consts(self): loop = """ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] @@ -783,10 +720,11 @@ FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)), \ [lltype.Signed], lltype.Signed, EffectInfo.MOST_GENERAL) + self.cpu.done_with_this_frame_descr_int = BasicFinalDescr() loop1 = """ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] i11 = int_add(i0, i1) - finish(i11, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10) + guard_false(i0) [i11, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] """ large = self.interpret(loop1, range(11), run=False) large._jitcelltoken.outermost_jitdriver_sd = FakeJitDriverSD() @@ -797,7 +735,7 @@ i1 = force_token() i2 = call_assembler(1,2,3,4,5,6,7,8,9,10,11, descr=looptoken) guard_not_forced() [i0] - finish(i0, i2) + guard_false(i0) [i0, i2] """ self.interpret(loop2, [110]) @@ -834,7 +772,7 @@ assert self.getint(0) == 2 # and not segfault() -class TestStrOps(BaseTestRegalloc): +class TestStrOps(CustomBaseTestRegalloc): def test_newstr(self): ops = """ [i0] From noreply at buildbot.pypy.org Sun Mar 24 12:03:46 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:03:46 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130324110346.03A3C1C00E4@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62724:9dd54c5f962d Date: 2013-03-24 13:02 +0200 http://bitbucket.org/pypy/pypy/changeset/9dd54c5f962d/ Log: merge heads diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -23,6 +23,13 @@ """ return space.newlong(val) + at cpython_api([rffi.SIZE_T], PyObject) +def PyLong_FromSize_t(space, val): + """Return a new PyLongObject object from a C size_t, or NULL on + failure. + """ + return space.wrap(val) + @cpython_api([rffi.LONGLONG], PyObject) def PyLong_FromLongLong(space, val): """Return a new PyLongObject object from a C long long, or NULL diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1395,13 +1395,6 @@ """ raise NotImplementedError - at cpython_api([rffi.SIZE_T], PyObject) -def PyLong_FromSize_t(space, v): - """Return a new PyLongObject object from a C size_t, or - NULL on failure. - """ - raise NotImplementedError - @cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.INT_real], PyObject) def PyLong_FromUnicode(space, u, length, base): """Convert a sequence of Unicode digits to a Python long integer value. The first diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -146,6 +146,15 @@ assert module.from_longlong() == -1 assert module.from_unsignedlonglong() == (1<<64) - 1 + def test_from_size_t(self): + module = self.import_extension('foo', [ + ("from_unsignedlong", "METH_NOARGS", + """ + return PyLong_FromSize_t((size_t)-1); + """)]) + import sys + assert module.from_unsignedlong() == 2 * sys.maxint + 1 + def test_fromstring(self): module = self.import_extension('foo', [ ("from_string", "METH_NOARGS", From noreply at buildbot.pypy.org Sun Mar 24 12:12:35 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:12:35 +0100 (CET) Subject: [pypy-commit] pypy default: move duplicate tests to llsupport Message-ID: <20130324111235.D35661C2F70@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62725:fb9fa47d3ffa Date: 2013-03-24 13:12 +0200 http://bitbucket.org/pypy/pypy/changeset/fb9fa47d3ffa/ Log: move duplicate tests to llsupport diff --git a/rpython/jit/backend/arm/test/test_recompilation.py b/rpython/jit/backend/arm/test/test_recompilation.py deleted file mode 100644 --- a/rpython/jit/backend/arm/test/test_recompilation.py +++ /dev/null @@ -1,150 +0,0 @@ -from rpython.jit.backend.arm.test.test_regalloc import BaseTestRegalloc - - -class TestRecompilation(BaseTestRegalloc): - def test_compile_bridge_not_deeper(self): - ops = ''' - [i0] - label(i0, descr=targettoken) - i1 = int_add(i0, 1) - i2 = int_lt(i1, 20) - guard_true(i2, descr=fdescr1) [i1] - jump(i1, descr=targettoken) - ''' - loop = self.interpret(ops, [0]) - assert self.getint(0) == 20 - ops = ''' - [i1] - i3 = int_add(i1, 1) - finish(i3, descr=fdescr2) - ''' - bridge = self.attach_bridge(ops, loop, -2) - fail = self.run(loop, 0) - assert fail.identifier == 2 - assert self.getint(0) == 21 - - def test_compile_bridge_deeper(self): - ops = ''' - [i0] - label(i0, descr=targettoken) - i1 = int_add(i0, 1) - i2 = int_lt(i1, 20) - guard_true(i2, descr=fdescr1) [i1] - jump(i1, descr=targettoken) - ''' - loop = self.interpret(ops, [0]) - previous = loop._jitcelltoken.compiled_loop_token.frame_depth - #assert loop._jitcelltoken.compiled_loop_token.param_depth == 0 - assert self.getint(0) == 20 - ops = ''' - [i1] - i3 = int_add(i1, 1) - i4 = int_add(i3, 1) - i5 = int_add(i4, 1) - i6 = int_add(i5, 1) - i7 = int_add(i5, i4) - force_spill(i5) - i8 = int_add(i7, 1) - i9 = int_add(i8, 1) - finish(i3, i4, i5, i6, i7, i8, i9, descr=fdescr2) - ''' - bridge = self.attach_bridge(ops, loop, -2) - descr = loop.operations[3].getdescr() - new = descr._arm_bridge_frame_depth - #assert descr._x86_bridge_param_depth == 0 - # the force_spill() forces the stack to grow - assert new > previous - fail = self.run(loop, 0) - assert fail.identifier == 2 - assert self.getint(0) == 21 - assert self.getint(1) == 22 - assert self.getint(2) == 23 - assert self.getint(3) == 24 - - def test_bridge_jump_to_other_loop(self): - loop = self.interpret(''' - [i0, i10, i11, i12, i13, i14, i15, i16] - label(i0, i10, i11, i12, i13, i14, i15, i16, descr=targettoken) - i1 = int_add(i0, 1) - i2 = int_lt(i1, 20) - guard_true(i2, descr=fdescr1) [i1] - jump(i1, i10, i11, i12, i13, i14, i15, i16, descr=targettoken) - ''', [0, 0, 0, 0, 0, 0, 0, 0]) - other_loop = self.interpret(''' - [i3, i10, i11, i12, i13, i14, i15, i16] - label(i3, descr=targettoken2) - guard_false(i3, descr=fdescr2) [i3] - jump(i3, descr=targettoken2) - ''', [1, 0, 0, 0, 0, 0, 0, 0]) - ops = ''' - [i3] - jump(i3, 1, 2, 3, 4, 5, 6, 7, descr=targettoken) - ''' - bridge = self.attach_bridge(ops, other_loop, 1) - fail = self.run(other_loop, 1, 0, 0, 0, 0, 0, 0, 0) - assert fail.identifier == 1 - - def test_bridge_jumps_to_self_deeper(self): - loop = self.interpret(''' - [i0, i1, i2, i31, i32, i33] - label(i0, i1, i2, i31, i32, i33, descr=targettoken) - i98 = same_as(0) - i99 = same_as(1) - i30 = int_add(i1, i2) - i3 = int_add(i0, 1) - i4 = int_and(i3, 1) - guard_false(i4) [i98, i3] - i5 = int_lt(i3, 20) - guard_true(i5) [i99, i3] - jump(i3, i30, 1, i30, i30, i30, descr=targettoken) - ''', [0, 0, 0, 0, 0, 0]) - assert self.getint(0) == 0 - assert self.getint(1) == 1 - ops = ''' - [i97, i3] - i10 = int_mul(i3, 2) - i8 = int_add(i3, 1) - i6 = int_add(i8, i10) - i7 = int_add(i3, i6) - force_spill(i6) - force_spill(i7) - force_spill(i8) - i12 = int_add(i7, i8) - i11 = int_add(i12, i6) - jump(i3, i12, i11, i10, i6, i7, descr=targettoken) - ''' - loop_frame_depth = loop._jitcelltoken.compiled_loop_token.frame_depth - bridge = self.attach_bridge(ops, loop, 6) - guard_op = loop.operations[6] - #assert loop._jitcelltoken.compiled_loop_token.param_depth == 0 - # the force_spill() forces the stack to grow - #assert guard_op.getdescr()._x86_bridge_frame_depth > loop_frame_depth - #assert guard_op.getdescr()._x86_bridge_param_depth == 0 - self.run(loop, 0, 0, 0, 0, 0, 0) - assert self.getint(0) == 1 - assert self.getint(1) == 20 - - def test_bridge_jumps_to_self_shallower(self): - loop = self.interpret(''' - [i0, i1, i2] - label(i0, i1, i2, descr=targettoken) - i98 = same_as(0) - i99 = same_as(1) - i3 = int_add(i0, 1) - i4 = int_and(i3, 1) - guard_false(i4) [i98, i3] - i5 = int_lt(i3, 20) - guard_true(i5) [i99, i3] - jump(i3, i1, i2, descr=targettoken) - ''', [0, 0, 0]) - assert self.getint(0) == 0 - assert self.getint(1) == 1 - ops = ''' - [i97, i3] - jump(i3, 0, 1, descr=targettoken) - ''' - bridge = self.attach_bridge(ops, loop, 5) - self.run(loop, 0, 0, 0) - assert self.getint(0) == 1 - assert self.getint(1) == 20 - diff --git a/rpython/jit/backend/x86/test/test_recompilation.py b/rpython/jit/backend/llsupport/test/test_recompilation.py rename from rpython/jit/backend/x86/test/test_recompilation.py rename to rpython/jit/backend/llsupport/test/test_recompilation.py --- a/rpython/jit/backend/x86/test/test_recompilation.py +++ b/rpython/jit/backend/llsupport/test/test_recompilation.py @@ -1,5 +1,4 @@ from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc -from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 class TestRecompilation(BaseTestRegalloc): def test_compile_bridge_not_deeper(self): From noreply at buildbot.pypy.org Sun Mar 24 12:32:27 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 24 Mar 2013 12:32:27 +0100 (CET) Subject: [pypy-commit] pypy default: fix even more tests Message-ID: <20130324113227.7CDA71C2F7C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62726:6a0ae7b3637f Date: 2013-03-24 13:32 +0200 http://bitbucket.org/pypy/pypy/changeset/6a0ae7b3637f/ Log: fix even more tests diff --git a/rpython/jit/backend/arm/test/test_generated.py b/rpython/jit/backend/arm/test/test_generated.py --- a/rpython/jit/backend/arm/test/test_generated.py +++ b/rpython/jit/backend/arm/test/test_generated.py @@ -36,19 +36,20 @@ ResOperation(rop.INT_SUB, [ConstInt(-1073741824), v7], v11), ResOperation(rop.INT_GE, [v3, ConstInt(23)], v12), ResOperation(rop.GUARD_TRUE, [v12], None, descr=faildescr1), - ResOperation(rop.FINISH, [v9, v6, v10, v2, v8, v5, v1, v4], None, descr=faildescr2), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] looptoken = JitCellToken() operations[2].setfailargs([v12, v8, v3, v2, v1, v11]) + operations[3].setfailargs([v9, v6, v10, v2, v8, v5, v1, v4]) cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] - op = cpu.execute_token(looptoken, *args) - assert cpu.get_latest_value_int(0) == 0 - assert cpu.get_latest_value_int(1) == 62 - assert cpu.get_latest_value_int(2) == -19 - assert cpu.get_latest_value_int(3) == -26 - assert cpu.get_latest_value_int(4) == -12 - assert cpu.get_latest_value_int(5) == -1073741787 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_int_value(deadframe, 0) == 0 + assert cpu.get_int_value(deadframe, 1) == 62 + assert cpu.get_int_value(deadframe, 2) == -19 + assert cpu.get_int_value(deadframe, 3) == -26 + assert cpu.get_int_value(deadframe, 4) == -12 + assert cpu.get_int_value(deadframe, 5) == -1073741787 def test_overflow(self): faildescr1 = BasicFailDescr(1) @@ -86,21 +87,22 @@ ResOperation(rop.UINT_GT, [v15, v5], v17), ResOperation(rop.UINT_LE, [ConstInt(-9), v13], v18), ResOperation(rop.GUARD_FALSE, [v13], None, descr=faildescr2), - ResOperation(rop.FINISH, [v7, v1, v2], None, descr=faildescr3), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3), ] operations[2].setfailargs([v10, v6]) operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) + operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] - op = cpu.execute_token(looptoken, *args) - assert cpu.get_latest_value_int(0) == 105 - assert cpu.get_latest_value_int(1) == 63 - assert cpu.get_latest_value_int(2) == 0 - assert cpu.get_latest_value_int(3) == 0 - assert cpu.get_latest_value_int(4) == 16 - assert cpu.get_latest_value_int(5) == 1 - assert cpu.get_latest_value_int(6) == 16 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_int_value(deadframe, 0) == 105 + assert cpu.get_int_value(deadframe, 1) == 63 + assert cpu.get_int_value(deadframe, 2) == 0 + assert cpu.get_int_value(deadframe, 3) == 0 + assert cpu.get_int_value(deadframe, 4) == 16 + assert cpu.get_int_value(deadframe, 5) == 1 + assert cpu.get_int_value(deadframe, 6) == 16 def test_sub_with_neg_const_first_arg(self): faildescr1 = BasicFailDescr(1) @@ -128,20 +130,22 @@ ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.INT_IS_ZERO, [v12], tmp13), ResOperation(rop.GUARD_TRUE, [tmp13], None, descr=faildescr2), - ResOperation(rop.FINISH, [v5, v2, v1, v10, v3, v8, v4, v6], None, descr=faildescr3) + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3) ] operations[2].setfailargs([v8, v3]) operations[4].setfailargs([v2, v12, v1, v3, v4]) + operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) + looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 2 - assert cpu.get_latest_value_int(0) == 24 - assert cpu.get_latest_value_int(1) == -32 - assert cpu.get_latest_value_int(2) == -5 - assert cpu.get_latest_value_int(3) == 46 - assert cpu.get_latest_value_int(4) == -15 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 2 + assert cpu.get_int_value(deadframe, 0) == 24 + assert cpu.get_int_value(deadframe, 1) == -32 + assert cpu.get_int_value(deadframe, 2) == -5 + assert cpu.get_int_value(deadframe, 3) == 46 + assert cpu.get_int_value(deadframe, 4) == -15 def test_tempbox_spilling_in_sub(self): faildescr1 = BasicFailDescr(1) @@ -171,20 +175,21 @@ ResOperation(rop.INT_IS_TRUE, [v3], v14), ResOperation(rop.INT_SUB_OVF, [v3, ConstInt(-95)], v15), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), - ResOperation(rop.FINISH, [v8, v2, v6, v5, v7, v1, v10], None, descr=faildescr2), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[5].setfailargs([]) + operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] - op = cpu.execute_token(looptoken, *args) - assert cpu.get_latest_value_int(0) == -29 - assert cpu.get_latest_value_int(1) == -3 - assert cpu.get_latest_value_int(2) == 22 - assert cpu.get_latest_value_int(3) == 12 - assert cpu.get_latest_value_int(4) == -54 - assert cpu.get_latest_value_int(5) == 19 - assert cpu.get_latest_value_int(6) == -64 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_int_value(deadframe, 0) == -29 + assert cpu.get_int_value(deadframe, 1) == -3 + assert cpu.get_int_value(deadframe, 2) == 22 + assert cpu.get_int_value(deadframe, 3) == 12 + assert cpu.get_int_value(deadframe, 4) == -54 + assert cpu.get_int_value(deadframe, 5) == 19 + assert cpu.get_int_value(deadframe, 6) == -64 def test_tempbox2(self): faildescr1 = BasicFailDescr(1) @@ -214,19 +219,20 @@ ResOperation(rop.INT_SUB, [ConstInt(99), v6], v14), ResOperation(rop.INT_MUL_OVF, [v6, v9], v15), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), - ResOperation(rop.FINISH, [v1, v4, v10, v8, v7, v3], None, descr=faildescr2), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] looptoken = JitCellToken() operations[5].setfailargs([]) + operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] - op = cpu.execute_token(looptoken, *args) - assert cpu.get_latest_value_int(0) == 1073741824 - assert cpu.get_latest_value_int(1) == 5 - assert cpu.get_latest_value_int(2) == -63 - assert cpu.get_latest_value_int(3) == 17 - assert cpu.get_latest_value_int(4) == 32 - assert cpu.get_latest_value_int(5) == -16 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_int_value(deadframe, 0) == 1073741824 + assert cpu.get_int_value(deadframe, 1) == 5 + assert cpu.get_int_value(deadframe, 2) == -63 + assert cpu.get_int_value(deadframe, 3) == 17 + assert cpu.get_int_value(deadframe, 4) == 32 + assert cpu.get_int_value(deadframe, 5) == -16 def test_wrong_guard(self): # generated by: @@ -267,18 +273,19 @@ ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr2), ResOperation(rop.INT_IS_TRUE, [v12], tmp17), ResOperation(rop.GUARD_FALSE, [tmp17], None, descr=faildescr3), - ResOperation(rop.FINISH, [v8, v10, v6, v3, v2, v9], None, descr=faildescr4), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr4), ] looptoken = JitCellToken() operations[1].setfailargs([v8, v6, v1]) operations[7].setfailargs([v4]) operations[9].setfailargs([v10, v13]) + operations[-1].setfailargs([v8, v10, v6, v3, v2, v9]) args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12] cpu.compile_loop(inputargs, operations, looptoken) - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 3 - assert cpu.get_latest_value_int(0) == 12 - assert cpu.get_latest_value_int(1) == 23 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 3 + assert cpu.get_int_value(deadframe, 0) == 12 + assert cpu.get_int_value(deadframe, 1) == 23 def test_wrong_guard2(self): # random seed: 8029 @@ -316,17 +323,18 @@ ResOperation(rop.INT_NE, [ConstInt(1), v11], v15), ResOperation(rop.INT_NE, [ConstInt(23), v15], v16), ResOperation(rop.GUARD_FALSE, [v15], None, descr=faildescr2), - ResOperation(rop.FINISH, [v4, v10, v6, v5, v9, v7], None, descr=faildescr3), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3), ] operations[1].setfailargs([v6, v8, v1, v4]) operations[8].setfailargs([v5, v9]) + operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 2 - assert cpu.get_latest_value_int(0) == 16 - assert cpu.get_latest_value_int(1) == -1 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 2 + assert cpu.get_int_value(deadframe, 0) == 16 + assert cpu.get_int_value(deadframe, 1) == -1 def test_wrong_guard3(self): # random seed: 8029 @@ -364,21 +372,22 @@ ResOperation(rop.GUARD_VALUE, [v15, ConstInt(-32)], None, descr=faildescr4), ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(805306366)], v16), ResOperation(rop.GUARD_VALUE, [v15, ConstInt(0)], None, descr=faildescr1), - ResOperation(rop.FINISH, [v10, v8, v1, v6, v4], None, descr=faildescr2), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[3].setfailargs([]) operations[-4].setfailargs([v15]) operations[-2].setfailargs([v9, v4, v10, v11, v14]) + operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 1 - assert cpu.get_latest_value_int(0) == -15 - assert cpu.get_latest_value_int(1) == -9 - assert cpu.get_latest_value_int(2) == 536870912 - assert cpu.get_latest_value_int(3) == 0 - assert cpu.get_latest_value_int(4) == 0 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 1 + assert cpu.get_int_value(deadframe, 0) == -15 + assert cpu.get_int_value(deadframe, 1) == -9 + assert cpu.get_int_value(deadframe, 2) == 536870912 + assert cpu.get_int_value(deadframe, 3) == 0 + assert cpu.get_int_value(deadframe, 4) == 0 def test_wrong_result(self): # generated by: @@ -418,23 +427,24 @@ ResOperation(rop.INT_IS_TRUE, [v4], v14), ResOperation(rop.INT_XOR, [v14, v3], v15), ResOperation(rop.GUARD_VALUE, [v8, ConstInt(-8)], None, descr=faildescr3), - ResOperation(rop.FINISH, [v1, v2, v9], None, descr=faildescr4), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr4), ] operations[1].setfailargs([v9, v1]) operations[5].setfailargs([v10, v2, v11, v3]) operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) + operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44] - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 3 - assert cpu.get_latest_value_int(0) == -4 - assert cpu.get_latest_value_int(1) == -95 - assert cpu.get_latest_value_int(2) == 45 - assert cpu.get_latest_value_int(3) == 1 - assert cpu.get_latest_value_int(4) == -2 - assert cpu.get_latest_value_int(5) == 0 - assert cpu.get_latest_value_int(6) == 33 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 3 + assert cpu.get_int_value(deadframe, 0) == -4 + assert cpu.get_int_value(deadframe, 1) == -95 + assert cpu.get_int_value(deadframe, 2) == 45 + assert cpu.get_int_value(deadframe, 3) == 1 + assert cpu.get_int_value(deadframe, 4) == -2 + assert cpu.get_int_value(deadframe, 5) == 0 + assert cpu.get_int_value(deadframe, 6) == 33 def test_int_add(self): # random seed: 1202 @@ -461,20 +471,21 @@ ResOperation(rop.INT_ADD, [ConstInt(-1073741825), v3], v11), ResOperation(rop.INT_IS_TRUE, [v1], tmp12), ResOperation(rop.GUARD_FALSE, [tmp12], None, descr=faildescr1), - ResOperation(rop.FINISH, [v8, v2, v10, v6, v7, v9, v5, v4], None, descr=faildescr2), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[2].setfailargs([v10, v3, v6, v11, v9, v2]) + operations[-1].setfailargs([v8, v2, v10, v6, v7, v9, v5, v4]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 1 - assert cpu.get_latest_value_int(0) == -43 - assert cpu.get_latest_value_int(1) == 1431655765 - assert cpu.get_latest_value_int(2) == 1789569706 - assert cpu.get_latest_value_int(3) == 357913940 - assert cpu.get_latest_value_int(4) == 16 - assert cpu.get_latest_value_int(5) == -5 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 1 + assert cpu.get_int_value(deadframe, 0) == -43 + assert cpu.get_int_value(deadframe, 1) == 1431655765 + assert cpu.get_int_value(deadframe, 2) == 1789569706 + assert cpu.get_int_value(deadframe, 3) == 357913940 + assert cpu.get_int_value(deadframe, 4) == 16 + assert cpu.get_int_value(deadframe, 5) == -5 def test_wrong_result2(self): # block length 10 @@ -508,18 +519,19 @@ ResOperation(rop.GUARD_VALUE, [v14, ConstInt(1)], None, descr=f3), ResOperation(rop.INT_MUL, [v13, ConstInt(12)], v15), ResOperation(rop.GUARD_FALSE, [v11], None, descr=f1), - ResOperation(rop.FINISH, [v2, v3, v5, v7, v10, v8, v9], None, descr=f2), + ResOperation(rop.GUARD_FALSE, [v1], None, descr=f2), ] operations[-2].setfailargs([v4, v10, v3, v9, v14, v2]) + operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] - op = cpu.execute_token(looptoken, *args) - assert op.identifier == 1 - assert cpu.get_latest_value_int(0) == -2058005163 - assert cpu.get_latest_value_int(1) == 19 - assert cpu.get_latest_value_int(2) == 18 - assert cpu.get_latest_value_int(3) == 0 - assert cpu.get_latest_value_int(4) == 1 - assert cpu.get_latest_value_int(5) == -20 + deadframe = cpu.execute_token(looptoken, *args) + assert cpu.get_latest_descr(deadframe).identifier == 1 + assert cpu.get_int_value(deadframe, 0) == -2058005163 + assert cpu.get_int_value(deadframe, 1) == 19 + assert cpu.get_int_value(deadframe, 2) == 18 + assert cpu.get_int_value(deadframe, 3) == 0 + assert cpu.get_int_value(deadframe, 4) == 1 + assert cpu.get_int_value(deadframe, 5) == -20 From noreply at buildbot.pypy.org Mon Mar 25 00:23:13 2013 From: noreply at buildbot.pypy.org (aljosa) Date: Mon, 25 Mar 2013 00:23:13 +0100 (CET) Subject: [pypy-commit] jitviewer default: fixed an issue in javascript when "path" doesn't exist Message-ID: <20130324232313.C73EC1C00E4@cobra.cs.uni-duesseldorf.de> Author: Aljosa Mohorovic Branch: Changeset: r224:854441a34049 Date: 2013-03-24 16:20 -0700 http://bitbucket.org/pypy/jitviewer/changeset/854441a34049/ Log: fixed an issue in javascript when "path" doesn't exist diff --git a/_jitviewer/static/app.js b/_jitviewer/static/app.js --- a/_jitviewer/static/app.js +++ b/_jitviewer/static/app.js @@ -5,7 +5,7 @@ "a[data-name] click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); - var path = el.data('path'); + var path = el.data('path') || ""; if(name) { can.route.attr({'name': name, 'path': path}); } @@ -13,7 +13,7 @@ ".operations a.inlined_call click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); - var path = el.data('path'); + var path = el.data('path') || ""; if(name) { can.route.attr({'name': name, 'path': path}); } @@ -21,7 +21,7 @@ ".operations a.bridgelink click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); - var path = el.data('path'); + var path = el.data('path') || ""; if(name) { can.route.attr({'name': name, 'path': path}); } @@ -29,7 +29,7 @@ ".operations .single-operation a click": function(el, ev) { ev.preventDefault(); var name = el.data('name'); - var path = el.data('path'); + var path = el.data('path') || ""; if(name) { can.route.attr({'name': name, 'path': path}); } @@ -146,7 +146,8 @@ "#loops .loopitem a click": function(el, ev){ ev.preventDefault(); var name = el.data('name'); - var path = el.data('path'); + var path = el.data('path') || ""; + console.log("loop:", name, path); if(name) { can.route.attr({'name': name, 'path': path}); } @@ -154,7 +155,7 @@ "#callstack a click": function(el, ev){ ev.preventDefault(); var name = el.data('name'); - var path = el.data('path'); + var path = el.data('path') || ""; if(name) { can.route.attr({'name': name, 'path': path}); } From noreply at buildbot.pypy.org Mon Mar 25 03:03:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 03:03:31 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for time.accept2dyear behavior (thanks chrish42) Message-ID: <20130325020331.AEB141C2F7D@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62727:74d32ef99de4 Date: 2013-03-24 22:02 -0400 http://bitbucket.org/pypy/pypy/changeset/74d32ef99de4/ Log: test and fix for time.accept2dyear behavior (thanks chrish42) diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -432,10 +432,10 @@ glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO) rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0) - w_accept2dyear = _get_module_object(space, "accept2dyear") - accept2dyear = space.int_w(w_accept2dyear) + if y < 1900: + w_accept2dyear = _get_module_object(space, "accept2dyear") + accept2dyear = space.int_w(w_accept2dyear) - if y < 1900: if not accept2dyear: raise OperationError(space.w_ValueError, space.wrap("year >= 1900 required")) diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -139,6 +139,16 @@ ltime = rctime.localtime() assert rctime.asctime(tuple(ltime)) == rctime.asctime(ltime) + def test_accept2dyear_access(self): + import time as rctime + + accept2dyear = rctime.accept2dyear + del rctime.accept2dyear + try: + assert rctime.asctime((12345,) + (0,) * 8).split()[-1] == '12345' + finally: + rctime.accept2dyear = accept2dyear + def test_struct_time(self): import time as rctime raises(TypeError, rctime.struct_time) From noreply at buildbot.pypy.org Mon Mar 25 03:08:20 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 03:08:20 +0100 (CET) Subject: [pypy-commit] jitviewer default: fix the hex conversion Message-ID: <20130325020820.3F0941C2F7D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r225:96164884291c Date: 2013-03-24 19:08 -0700 http://bitbucket.org/pypy/jitviewer/changeset/96164884291c/ Log: fix the hex conversion diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -69,7 +69,7 @@ if descr.startswith('TargetToken('): return descr[len('TargetToken('):-1] if descr.startswith(' Author: Maciej Fijalkowski Branch: Changeset: r226:dc0e1f65f38b Date: 2013-03-24 21:03 -0700 http://bitbucket.org/pypy/jitviewer/changeset/dc0e1f65f38b/ Log: oops diff --git a/_jitviewer/templates/loop.html b/_jitviewer/templates/loop.html --- a/_jitviewer/templates/loop.html +++ b/_jitviewer/templates/loop.html @@ -13,7 +13,7 @@ {% for op in chunk.operations %} {% if op.name != "debug_merge_point" %} {% if op.bridge %} - {{op.html_repr()}} show bridge  (run {{op.count}} times, ~{{op.percentage}}%)
+ {{op.html_repr()}} show bridge  (run {{op.count}} times, ~{{op.percentage}}%)
{% if op.asm %}

{{op.asm}}

{% endif %} From noreply at buildbot.pypy.org Mon Mar 25 07:37:43 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Mon, 25 Mar 2013 07:37:43 +0100 (CET) Subject: [pypy-commit] pypy default: (price, fijal) signature: stubs and failing tests for class signatures Message-ID: <20130325063743.261DB1C0694@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62728:896726ddd842 Date: 2013-03-24 22:36 -0700 http://bitbucket.org/pypy/pypy/changeset/896726ddd842/ Log: (price, fijal) signature: stubs and failing tests for class signatures diff --git a/rpython/rlib/signature.py b/rpython/rlib/signature.py --- a/rpython/rlib/signature.py +++ b/rpython/rlib/signature.py @@ -38,3 +38,13 @@ paramtypes, returntype = attr._signature_ attr._signature_ = (tuple(fix(t) for t in paramtypes), fix(returntype)) return cls + + +class FieldSpec(object): + def __init__(self, tp): + pass + + +class ClassSpec(object): + def __init__(self, fields, inherit=False): + pass diff --git a/rpython/rlib/test/test_signature.py b/rpython/rlib/test/test_signature.py --- a/rpython/rlib/test/test_signature.py +++ b/rpython/rlib/test/test_signature.py @@ -1,5 +1,5 @@ import py -from rpython.rlib.signature import signature, finishsigs +from rpython.rlib.signature import signature, finishsigs, FieldSpec, ClassSpec from rpython.rlib import types from rpython.annotator import model from rpython.translator.translator import TranslationContext, graphof @@ -284,3 +284,64 @@ exc = py.test.raises(Exception, annotate_at, cannot_add_string).value assert 'Blocked block' in repr(exc.args) assert 'cannot_add_string' in repr(exc.args) + + + + at py.test.mark.xfail +def test_class_basic(): + class C(object): + _fields_ = ClassSpec({'x': FieldSpec(types.int)}) + + def wrong_type(): + c = C() + c.x = 'a' + check_annotator_fails(wrong_type) + + def bad_field(): + c = C() + c.y = 3 + check_annotator_fails(bad_field) + + + at py.test.mark.xfail +def test_class_shorthand(): + class C1(object): + _fields_ = {'x': FieldSpec(types.int)} + def wrong_type_1(): + c = C1() + c.x = 'a' + check_annotator_fails(wrong_type_1) + + class C2(object): + _fields_ = ClassSpec({'x': types.int}) + def wrong_type_2(): + c = C2() + c.x = 'a' + check_annotator_fails(wrong_type_1) + + + at py.test.mark.xfail +def test_class_inherit(): + class C(object): + _fields_ = ClassSpec({'x': FieldSpec(types.int)}) + + class C1(object): + _fields_ = ClassSpec({'y': FieldSpec(types.int)}) + + class C2(object): + _fields_ = ClassSpec({'y': FieldSpec(types.int)}, inherit=True) + + def no_inherit(): + c = C1() + c.x = 3 + check_annotator_fails(no_inherit) + + def good(): + c = C2() + c.x = 3 + annotate_at(good) + + def wrong_type(): + c = C2() + c.x = 'a' + check_annotator_fails(wrong_type) From noreply at buildbot.pypy.org Mon Mar 25 07:54:51 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 07:54:51 +0100 (CET) Subject: [pypy-commit] pypy default: write a passing test Message-ID: <20130325065451.D262F1C1534@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62729:0fe403f2aae2 Date: 2013-03-24 23:52 -0700 http://bitbucket.org/pypy/pypy/changeset/0fe403f2aae2/ Log: write a passing test 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 @@ -3922,6 +3922,28 @@ a = self.RPythonAnnotator() assert a.build_types(f, []).const is True + def test_specific_attributes(self): + class A(object): + pass + + class B(A): + def __init__(self, x): + assert x >= 0 + self.x = x + + def fn(i): + if i % 2: + a = A() + else: + a = B(3) + if i % 3: + a.x = -3 + if isinstance(a, B): + return a.x + return 0 + + a = self.RPythonAnnotator() + assert not a.build_types(fn, [int]).nonneg def g(n): return [0, 1, 2, n] From noreply at buildbot.pypy.org Mon Mar 25 07:54:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 07:54:53 +0100 (CET) Subject: [pypy-commit] pypy default: update the comment Message-ID: <20130325065453.2BD621C1534@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62730:35425577893a Date: 2013-03-24 23:54 -0700 http://bitbucket.org/pypy/pypy/changeset/35425577893a/ Log: update the comment diff --git a/rpython/annotator/classdef.py b/rpython/annotator/classdef.py --- a/rpython/annotator/classdef.py +++ b/rpython/annotator/classdef.py @@ -39,6 +39,9 @@ # B C # attr=s2 attr=s3 # +# XXX this does not seem to be correct, but I don't know how to phrase +# it correctly. See test_specific_attributes in test_annrpython +# # In this case, as long as 'attr' is only read/written from B or C, the # Attribute on B says that it can be 's1 or s2', and the Attribute on C says # it can be 's1 or s3'. Merging them into a single Attribute on A would give @@ -97,7 +100,7 @@ s_newvalue = self.getvalue() for position in self.read_locations: - self.bookkeeper.annotator.reflowfromposition(position) + self.bookkeeper.annotator.reflowfromposition(position) # check for method demotion and after-the-fact method additions if isinstance(s_newvalue, SomePBC): @@ -116,7 +119,7 @@ (self.name, homedef) ) #self.bookkeeper.warning("demoting method %s " - # "to base class %s" % + # "to base class %s" % # (self.name, homedef)) break @@ -147,7 +150,7 @@ self.attrs = {} # {name: Attribute} self.classdesc = classdesc self.name = self.classdesc.name - self.shortname = self.name.split('.')[-1] + self.shortname = self.name.split('.')[-1] self.subdefs = [] self.attr_sources = {} # {name: list-of-sources} self.read_locations_of__class__ = {} @@ -401,7 +404,7 @@ def __init__(self, bookkeeper, obj): self.bookkeeper = bookkeeper self.obj = obj - + def s_get_value(self, classdef, name): try: v = getattr(self.obj, name) From noreply at buildbot.pypy.org Mon Mar 25 07:54:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 07:54:54 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130325065454.594491C1534@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62731:1f13a64d358d Date: 2013-03-24 23:54 -0700 http://bitbucket.org/pypy/pypy/changeset/1f13a64d358d/ Log: merge diff --git a/rpython/rlib/signature.py b/rpython/rlib/signature.py --- a/rpython/rlib/signature.py +++ b/rpython/rlib/signature.py @@ -38,3 +38,13 @@ paramtypes, returntype = attr._signature_ attr._signature_ = (tuple(fix(t) for t in paramtypes), fix(returntype)) return cls + + +class FieldSpec(object): + def __init__(self, tp): + pass + + +class ClassSpec(object): + def __init__(self, fields, inherit=False): + pass diff --git a/rpython/rlib/test/test_signature.py b/rpython/rlib/test/test_signature.py --- a/rpython/rlib/test/test_signature.py +++ b/rpython/rlib/test/test_signature.py @@ -1,5 +1,5 @@ import py -from rpython.rlib.signature import signature, finishsigs +from rpython.rlib.signature import signature, finishsigs, FieldSpec, ClassSpec from rpython.rlib import types from rpython.annotator import model from rpython.translator.translator import TranslationContext, graphof @@ -284,3 +284,64 @@ exc = py.test.raises(Exception, annotate_at, cannot_add_string).value assert 'Blocked block' in repr(exc.args) assert 'cannot_add_string' in repr(exc.args) + + + + at py.test.mark.xfail +def test_class_basic(): + class C(object): + _fields_ = ClassSpec({'x': FieldSpec(types.int)}) + + def wrong_type(): + c = C() + c.x = 'a' + check_annotator_fails(wrong_type) + + def bad_field(): + c = C() + c.y = 3 + check_annotator_fails(bad_field) + + + at py.test.mark.xfail +def test_class_shorthand(): + class C1(object): + _fields_ = {'x': FieldSpec(types.int)} + def wrong_type_1(): + c = C1() + c.x = 'a' + check_annotator_fails(wrong_type_1) + + class C2(object): + _fields_ = ClassSpec({'x': types.int}) + def wrong_type_2(): + c = C2() + c.x = 'a' + check_annotator_fails(wrong_type_1) + + + at py.test.mark.xfail +def test_class_inherit(): + class C(object): + _fields_ = ClassSpec({'x': FieldSpec(types.int)}) + + class C1(object): + _fields_ = ClassSpec({'y': FieldSpec(types.int)}) + + class C2(object): + _fields_ = ClassSpec({'y': FieldSpec(types.int)}, inherit=True) + + def no_inherit(): + c = C1() + c.x = 3 + check_annotator_fails(no_inherit) + + def good(): + c = C2() + c.x = 3 + annotate_at(good) + + def wrong_type(): + c = C2() + c.x = 'a' + check_annotator_fails(wrong_type) From noreply at buildbot.pypy.org Mon Mar 25 09:05:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 09:05:05 +0100 (CET) Subject: [pypy-commit] pypy default: start working on raspberry pi support Message-ID: <20130325080505.BCB0D1C0694@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62732:eb947a354a22 Date: 2013-03-25 01:00 -0700 http://bitbucket.org/pypy/pypy/changeset/eb947a354a22/ Log: start working on raspberry pi support diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -65,6 +65,8 @@ allblocks = self.get_asmmemmgr_blocks(looptoken) self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) + self.mc.datablockwrapper = self.datablockwrapper + self.mc.is_armv6 = self.cpu.backend_name == 'armv6' self.target_tokens_currently_compiling = {} def teardown(self): diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -248,6 +248,10 @@ def gen_load_int(self, r, value, cond=cond.AL): """r is the register number, value is the value to be loaded to the register""" + if value > 0xFF and self.is_armv6: + val = self.datablockwrapper.malloc_aligned(WORD) + import pdb + pdb.set_trace() bottom = value & 0xFFFF top = value >> 16 self.MOVW_ri(r, bottom, cond) 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 @@ -122,3 +122,11 @@ backend_name = "armhf" supports_floats = False supports_singlefloats = False + +class CPU_ARMv6(AbstractARMCPU): + """ ARM v6, uses hardfp ABI, requires vfp""" + use_hf_abi = True + backend_name = "armv6" + supports_floats = False + supports_singlefloats = False + 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 @@ -34,6 +34,7 @@ 'amd64': 'x86', # freebsd 'AMD64': 'x86', # win64 'armv7l': 'arm', + 'armv6l': 'armv6', }[mach] except KeyError: return mach @@ -59,12 +60,13 @@ if not detect_sse2(): model = 'x86-without-sse2' if model == 'arm': - from rpython.jit.backend.arm.detect import detect_hardfloat, detect_float - if detect_hardfloat(): - model = 'armhf' - assert detect_float(), 'the JIT-compiler requires a vfp unit' + from rpython.jit.backend.arm.detect import detect_hardfloat, detect_float + if detect_hardfloat(): + model = 'armhf' + if model.startswith('arm'): + assert detect_float(), 'the JIT-compiler requires a vfp unit' return model - + def getcpuclassname(backend_name="auto"): if backend_name == "auto": backend_name = autodetect() @@ -76,6 +78,8 @@ return "rpython.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "rpython.jit.backend.cli.runner", "CliCPU" + elif backend_name == 'armv6': + return "rpython.jit.backend.arm.runner", "CPU_ARMv6" elif backend_name == 'arm': return "rpython.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': From noreply at buildbot.pypy.org Mon Mar 25 10:22:16 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 25 Mar 2013 10:22:16 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fix translation on windows Message-ID: <20130325092216.7C2911C1591@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r232:16ee8976d762 Date: 2013-03-22 13:24 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/16ee8976d762/ Log: fix translation on windows diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -87,7 +87,7 @@ path = "Squeak.image" try: - f = open_file_as_stream(path) + f = open_file_as_stream(path, buffering=0) except OSError as e: os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path)) return 1 @@ -98,7 +98,7 @@ image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata)) image = create_image(space, image_reader) - interp = interpreter.Interpreter(space, image, image_name=os.path.abspath(path)) + interp = interpreter.Interpreter(space, image, image_name=path) if benchmark is not None: return _run_benchmark(interp, number, benchmark) else: From noreply at buildbot.pypy.org Mon Mar 25 10:22:25 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 25 Mar 2013 10:22:25 +0100 (CET) Subject: [pypy-commit] pypy default: fix detect_cpu for armv6 and armv7 Message-ID: <20130325092225.1FA581C1591@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62733:55a5e932519e Date: 2013-03-25 10:19 +0100 http://bitbucket.org/pypy/pypy/changeset/55a5e932519e/ Log: fix detect_cpu for armv6 and armv7 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 @@ -33,7 +33,7 @@ 'x86_64': 'x86', 'amd64': 'x86', # freebsd 'AMD64': 'x86', # win64 - 'armv7l': 'arm', + 'armv7l': 'armv7', 'armv6l': 'armv6', }[mach] except KeyError: @@ -59,11 +59,10 @@ from rpython.jit.backend.x86.detect_sse2 import detect_sse2 if not detect_sse2(): model = 'x86-without-sse2' - if model == 'arm': + if model.startswith('arm'): from rpython.jit.backend.arm.detect import detect_hardfloat, detect_float if detect_hardfloat(): - model = 'armhf' - if model.startswith('arm'): + model += 'hf' assert detect_float(), 'the JIT-compiler requires a vfp unit' return model @@ -78,11 +77,11 @@ return "rpython.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "rpython.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'armv6': + elif backend_name == 'armv6hf': return "rpython.jit.backend.arm.runner", "CPU_ARMv6" - elif backend_name == 'arm': + elif backend_name == 'armv7': return "rpython.jit.backend.arm.runner", "CPU_ARM" - elif backend_name == 'armhf': + elif backend_name == 'armv7hf': return "rpython.jit.backend.arm.runner", "CPU_ARMHF" else: raise ProcessorAutodetectError, ( From noreply at buildbot.pypy.org Mon Mar 25 10:22:26 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 25 Mar 2013 10:22:26 +0100 (CET) Subject: [pypy-commit] pypy default: recover armv6 compatible gen_load_int for hg history Message-ID: <20130325092226.61D041C1591@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62734:38a8292de86c Date: 2013-03-25 10:21 +0100 http://bitbucket.org/pypy/pypy/changeset/38a8292de86c/ Log: recover armv6 compatible gen_load_int for hg history diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -733,8 +733,8 @@ mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) stack_check_cmp_ofs = mc.currpos() if expected_size == -1: - mc.NOP() - mc.NOP() + for _ in range(mc.max_size_of_gen_load_int): + mc.NOP() else: mc.gen_load_int(r.lr.value, expected_size) mc.CMP_rr(r.ip.value, r.lr.value) diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -248,16 +248,33 @@ def gen_load_int(self, r, value, cond=cond.AL): """r is the register number, value is the value to be loaded to the register""" - if value > 0xFF and self.is_armv6: - val = self.datablockwrapper.malloc_aligned(WORD) - import pdb - pdb.set_trace() - bottom = value & 0xFFFF - top = value >> 16 - self.MOVW_ri(r, bottom, cond) - if top: - self.MOVT_ri(r, top, cond) - size_of_gen_load_int = 2 * WORD + if self.is_armv6: + from pypy.jit.backend.arm.conditions import AL + if cond != AL or 0 <= value <= 0xFFFF: + self._load_by_shifting(r, value, cond) + else: + self.LDR_ri(r, reg.pc.value) + self.MOV_rr(reg.pc.value, reg.pc.value) + self.write32(value) + else: + bottom = value & 0xFFFF + top = value >> 16 + self.MOVW_ri(r, bottom, cond) + if top: + self.MOVT_ri(r, top, cond) + + max_size_of_gen_load_int = 2 * WORD + ofs_shift = zip(range(8, 25, 8), range(12, 0, -4)) + def _load_by_shifting(self, r, value, c=cond.AL): + # to be sure it is only called for the correct cases + assert c != cond.AL or 0 <= value <= 0xFFFF + self.MOV_ri(r, (value & 0xFF), cond=c) + for offset, shift in self.ofs_shift: + b = (value >> offset) & 0xFF + if b == 0: + continue + t = b | (shift << 8) + self.ORR_ri(r, r, imm=t, cond=c) class OverwritingBuilder(AbstractARMv7Builder): From noreply at buildbot.pypy.org Mon Mar 25 10:42:39 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 10:42:39 +0100 (CET) Subject: [pypy-commit] pypy default: use jit.loop_unrolling_heuristic where possible Message-ID: <20130325094239.C28781C00E4@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62735:1f7ca87c6780 Date: 2013-03-25 05:37 -0400 http://bitbucket.org/pypy/pypy/changeset/1f7ca87c6780/ Log: use jit.loop_unrolling_heuristic where possible diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -202,8 +202,8 @@ @specialize.arg(2) def min_max(space, args, implementation_of): - if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2): + if not jit.we_are_jitted() or jit.loop_unrolling_heuristic( + args.arguments_w, len(args.arguments_w)): return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -10,8 +10,7 @@ from rpython.rlib.debug import mark_dict_non_null from rpython.tool.sourcetools import func_with_new_name -from rpython.rlib import rerased -from rpython.rlib import jit +from rpython.rlib import rerased, jit def _is_str(space, w_key): return space.is_w(space.type(w_key), space.w_str) @@ -29,9 +28,6 @@ space.is_w(w_lookup_type, space.w_float) ) - -DICT_CUTOFF = 5 - @specialize.call_location() def w_dict_unrolling_heuristic(w_dct): """ In which cases iterating over dict items can be unrolled. @@ -39,7 +35,8 @@ an actual dict """ return jit.isvirtual(w_dct) or (jit.isconstant(w_dct) and - w_dct.length() <= DICT_CUTOFF) + w_dct.length() <= jit.UNROLL_CUTOFF) + class W_DictMultiObject(W_Object): from pypy.objspace.std.dicttype import dict_typedef as typedef @@ -761,7 +758,8 @@ update1_keys(space, w_dict, w_data) - at jit.look_inside_iff(lambda space, w_dict, w_data: w_dict_unrolling_heuristic(w_data)) + at jit.look_inside_iff(lambda space, w_dict, w_data: + w_dict_unrolling_heuristic(w_data)) def update1_dict_dict(space, w_dict, w_data): iterator = w_data.iteritems() while 1: 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 @@ -183,7 +183,8 @@ # helper for pow() - at jit.look_inside_iff(lambda space, iv, iw, iz: jit.isconstant(iw) and jit.isconstant(iz)) + at jit.look_inside_iff(lambda space, iv, iw, iz: + jit.isconstant(iw) and jit.isconstant(iz)) def _impl_int_int_pow(space, iv, iw, iz): if iw < 0: if iz != 0: diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py --- a/pypy/objspace/std/kwargsdict.py +++ b/pypy/objspace/std/kwargsdict.py @@ -95,7 +95,8 @@ def getitem_str(self, w_dict, key): return self._getitem_str_indirection(w_dict, key) - @jit.look_inside_iff(lambda self, w_dict, key: jit.isconstant(self.length(w_dict)) and jit.isconstant(key)) + @jit.look_inside_iff(lambda self, w_dict, key: + jit.isconstant(self.length(w_dict)) and jit.isconstant(key)) def _getitem_str_indirection(self, w_dict, key): keys, values_w = self.unerase(w_dict.dstorage) result = [] 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 @@ -18,7 +18,6 @@ from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from sys import maxint -UNROLL_CUTOFF = 5 class W_AbstractListObject(W_Object): __slots__ = () @@ -43,7 +42,7 @@ return W_ListObject.from_storage_and_strategy(space, storage, strategy) @jit.look_inside_iff(lambda space, list_w, sizehint: - jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF) + jit.loop_unrolling_heuristic(list_w, len(list_w))) def get_strategy_from_list_objects(space, list_w, sizehint): if not list_w: if sizehint != -1: @@ -950,7 +949,7 @@ raise NotImplementedError("abstract base class") @jit.look_inside_iff(lambda space, w_list, list_w: - jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF) + jit.loop_unrolling_heuristic(list_w, len(list_w))) def init_from_list_w(self, w_list, list_w): l = [self.unwrap(w_item) for w_item in list_w] w_list.lstorage = self.erase(l) @@ -999,7 +998,7 @@ return self.wrap(r) @jit.look_inside_iff(lambda self, w_list: - jit.isconstant(w_list.length()) and w_list.length() < UNROLL_CUTOFF) + jit.loop_unrolling_heuristic(w_list, w_list.length())) def getitems_copy(self, w_list): return [self.wrap(item) for item in self.unerase(w_list.lstorage)] @@ -1008,7 +1007,7 @@ return [self.wrap(item) for item in self.unerase(w_list.lstorage)] @jit.look_inside_iff(lambda self, w_list: - jit.isconstant(w_list.length()) and w_list.length() < UNROLL_CUTOFF) + jit.loop_unrolling_heuristic(w_list, w_list.length())) def getitems_fixedsize(self, w_list): return self.getitems_unroll(w_list) diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -10,8 +10,6 @@ from rpython.rlib import jit from rpython.tool.sourcetools import func_with_new_name -# Tuples of known length up to UNROLL_TUPLE_LIMIT have unrolled certain methods -UNROLL_TUPLE_LIMIT = 10 class W_AbstractTupleObject(W_Object): __slots__ = () @@ -85,15 +83,8 @@ start, stop = normalize_simple_slice(space, length, w_start, w_stop) return space.newtuple(w_tuple.wrappeditems[start:stop]) -THRESHOLD = 7 - -def unroll_tuple_contains(space, w_tuple, w_obj): - if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and - len(w_tuple.wrappeditems) < THRESHOLD): - return True - return False - - at jit.look_inside_iff(unroll_tuple_contains) + at jit.look_inside_iff(lambda space, w_tuple, w_obj: + jit.loop_unrolling_heuristic(w_tuple, len(w_tuple.wrappeditems))) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): @@ -128,10 +119,8 @@ return mul_tuple_times(space, w_tuple, w_times) def tuple_unroll_condition(space, w_tuple1, w_tuple2): - lgt1 = len(w_tuple1.wrappeditems) - lgt2 = len(w_tuple2.wrappeditems) - return ((jit.isconstant(lgt1) and lgt1 <= UNROLL_TUPLE_LIMIT) or - (jit.isconstant(lgt2) and lgt2 <= UNROLL_TUPLE_LIMIT)) + return jit.loop_unrolling_heuristic(w_tuple1, len(w_tuple1.wrappeditems)) or \ + jit.loop_unrolling_heuristic(w_tuple2, len(w_tuple2.wrappeditems)) @jit.look_inside_iff(tuple_unroll_condition) def eq__Tuple_Tuple(space, w_tuple1, w_tuple2): @@ -151,7 +140,7 @@ def _make_tuple_comparison(name): import operator op = getattr(operator, name) - # + @jit.look_inside_iff(tuple_unroll_condition) def compare_tuples(space, w_tuple1, w_tuple2): items1 = w_tuple1.wrappeditems @@ -184,8 +173,7 @@ return space.wrap(hash_tuple(space, w_tuple.wrappeditems)) @jit.look_inside_iff(lambda space, wrappeditems: - jit.isconstant(len(wrappeditems)) and - len(wrappeditems) < UNROLL_TUPLE_LIMIT) + jit.loop_unrolling_heuristic(wrappeditems, len(wrappeditems))) def hash_tuple(space, wrappeditems): # this is the CPython 2.4 algorithm (changed from 2.3) mult = 1000003 diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -206,13 +206,13 @@ return NonConstant(False) isvirtual._annspecialcase_ = "specialize:call_location" -LIST_CUTOFF = 2 +UNROLL_CUTOFF = 5 @specialize.call_location() def loop_unrolling_heuristic(lst, size): """ In which cases iterating over items of lst can be unrolled """ - return isvirtual(lst) or (isconstant(size) and size <= LIST_CUTOFF) + return isvirtual(lst) or (isconstant(size) and size <= UNROLL_CUTOFF) class Entry(ExtRegistryEntry): _about_ = hint From noreply at buildbot.pypy.org Mon Mar 25 10:42:41 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 10:42:41 +0100 (CET) Subject: [pypy-commit] pypy default: unroll these set operations like list does Message-ID: <20130325094241.033E61C00E4@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62736:394d0dfa0fc6 Date: 2013-03-25 03:43 -0400 http://bitbucket.org/pypy/pypy/changeset/394d0dfa0fc6/ Log: unroll these set operations like list does diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -13,7 +13,7 @@ from rpython.rlib.objectmodel import r_dict from rpython.rlib.rarithmetic import intmask, r_uint -from rpython.rlib import rerased +from rpython.rlib import rerased, jit class W_BaseSetObject(W_Object): typedef = None @@ -390,6 +390,8 @@ """ Returns a wrapped version of the given unwrapped item. """ raise NotImplementedError + @jit.look_inside_iff(lambda self, list_w: + jit.loop_unrolling_heuristic(list_w, len(list_w))) def get_storage_from_list(self, list_w): setdata = self.get_empty_dict() for w_item in list_w: @@ -1026,6 +1028,8 @@ _pick_correct_strategy(space, w_set, iterable_w) + at jit.look_inside_iff(lambda space, w_set, iterable_w: + jit.loop_unrolling_heuristic(iterable_w, len(iterable_w))) def _pick_correct_strategy(space, w_set, iterable_w): # check for integers for w_item in iterable_w: From noreply at buildbot.pypy.org Mon Mar 25 10:42:42 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 10:42:42 +0100 (CET) Subject: [pypy-commit] pypy default: unroll these list operations like tuple does Message-ID: <20130325094242.477551C00E4@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62737:fd57a72ffc21 Date: 2013-03-25 04:51 -0400 http://bitbucket.org/pypy/pypy/changeset/fd57a72ffc21/ Log: unroll these list operations like tuple does 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 @@ -1468,6 +1468,11 @@ w_list.inplace_mul(times) return w_list +def list_unroll_condition(space, w_list1, w_list2): + return jit.loop_unrolling_heuristic(w_list1, w_list1.length()) or \ + jit.loop_unrolling_heuristic(w_list2, w_list2.length()) + + at jit.look_inside_iff(list_unroll_condition) def eq__List_List(space, w_list1, w_list2): # needs to be safe against eq_w() mutating the w_lists behind our back if w_list1.length() != w_list2.length(): @@ -1485,6 +1490,8 @@ def _make_list_comparison(name): import operator op = getattr(operator, name) + + @jit.look_inside_iff(list_unroll_condition) def compare_unwrappeditems(space, w_list1, w_list2): # needs to be safe against eq_w() mutating the w_lists behind our back # Search for the first index where items are different From noreply at buildbot.pypy.org Mon Mar 25 10:51:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 10:51:10 +0100 (CET) Subject: [pypy-commit] buildbot default: typo Message-ID: <20130325095110.B3F3D1C03ED@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r762:f108d98d0bc8 Date: 2013-03-25 02:50 -0700 http://bitbucket.org/pypy/buildbot/changeset/f108d98d0bc8/ Log: typo diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -267,7 +267,7 @@ BUILDLINUXARM = "build-pypy-c-linux-armel" BUILDJITLINUXARM = "build-pypy-c-jit-linux-armel" -extra_opts= {'xerxes': {'keepalive-interval': 15}} +extra_opts= {'xerxes': {'keepalive_interval': 15}} BuildmasterConfig = { 'slavePortnum': slavePortnum, From noreply at buildbot.pypy.org Mon Mar 25 12:08:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 12:08:18 +0100 (CET) Subject: [pypy-commit] pypy default: unroll this too Message-ID: <20130325110818.9A1C41C2F86@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62738:23fcef6e69f8 Date: 2013-03-25 07:00 -0400 http://bitbucket.org/pypy/pypy/changeset/23fcef6e69f8/ Log: unroll this too diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -398,6 +398,8 @@ setdata[self.unwrap(w_item)] = None return self.erase(setdata) + @jit.look_inside_iff(lambda self, items: + jit.loop_unrolling_heuristic(items, len(items))) def get_storage_from_unwrapped_list(self, items): setdata = self.get_empty_dict() for item in items: From noreply at buildbot.pypy.org Mon Mar 25 12:08:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 12:08:19 +0100 (CET) Subject: [pypy-commit] pypy default: correct the unroll logic for min/max Message-ID: <20130325110819.D0A541C2F86@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62739:6d2bc9b00a8d Date: 2013-03-25 07:07 -0400 http://bitbucket.org/pypy/pypy/changeset/6d2bc9b00a8d/ Log: correct the unroll logic for min/max diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -202,8 +202,8 @@ @specialize.arg(2) def min_max(space, args, implementation_of): - if not jit.we_are_jitted() or jit.loop_unrolling_heuristic( - args.arguments_w, len(args.arguments_w)): + if not jit.we_are_jitted() or len(args.arguments_w) != 1 and \ + jit.loop_unrolling_heuristic(args.arguments_w, len(args.arguments_w)): return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) From noreply at buildbot.pypy.org Mon Mar 25 12:19:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 12:19:09 +0100 (CET) Subject: [pypy-commit] pypy default: prevent useless comparisons between IntSet and UnicodeSet Message-ID: <20130325111909.EBF851C1591@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62740:b05ee63f0d20 Date: 2013-03-25 07:18 -0400 http://bitbucket.org/pypy/pypy/changeset/b05ee63f0d20/ Log: prevent useless comparisons between IntSet and UnicodeSet diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -805,6 +805,8 @@ def may_contain_equal_elements(self, strategy): if strategy is self.space.fromcache(StringSetStrategy): return False + if strategy is self.space.fromcache(UnicodeSetStrategy): + return False if strategy is self.space.fromcache(EmptySetStrategy): return False return True From noreply at buildbot.pypy.org Mon Mar 25 12:39:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 12:39:24 +0100 (CET) Subject: [pypy-commit] pypy default: use UnicodeSetStrategy when creating from an iterable, test Message-ID: <20130325113925.016EF1C1591@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62741:7799ba9b4dc3 Date: 2013-03-25 07:38 -0400 http://bitbucket.org/pypy/pypy/changeset/7799ba9b4dc3/ Log: use UnicodeSetStrategy when creating from an iterable, test diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -1053,6 +1053,15 @@ w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) return + # check for unicode + for w_item in iterable_w: + if type(w_item) is not W_UnicodeObject: + break + else: + w_set.strategy = space.fromcache(UnicodeSetStrategy) + w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) + return + w_set.strategy = space.fromcache(ObjectSetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -84,7 +84,7 @@ assert space.is_true(self.space.eq(result, W_SetObject(space, self.space.wrap("")))) def test_create_set_from_list(self): - from pypy.objspace.std.setobject import ObjectSetStrategy, StringSetStrategy + from pypy.objspace.std.setobject import ObjectSetStrategy, StringSetStrategy, UnicodeSetStrategy from pypy.objspace.std.floatobject import W_FloatObject from pypy.objspace.std.model import W_Object @@ -106,6 +106,12 @@ assert w_set.strategy is self.space.fromcache(StringSetStrategy) assert w_set.strategy.unerase(w_set.sstorage) == {"1":None, "2":None, "3":None} + w_list = self.space.iter(W_ListObject(self.space, [w(u"1"), w(u"2"), w(u"3")])) + w_set = W_SetObject(self.space) + _initialize_set(self.space, w_set, w_list) + assert w_set.strategy is self.space.fromcache(UnicodeSetStrategy) + assert w_set.strategy.unerase(w_set.sstorage) == {u"1":None, u"2":None, u"3":None} + w_list = W_ListObject(self.space, [w("1"), w(2), w("3")]) w_set = W_SetObject(self.space) _initialize_set(self.space, w_set, w_list) From noreply at buildbot.pypy.org Mon Mar 25 14:10:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 14:10:24 +0100 (CET) Subject: [pypy-commit] pypy default: should try listview_unicode here too Message-ID: <20130325131024.E72891C3022@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62742:7a260b2c4511 Date: 2013-03-25 09:10 -0400 http://bitbucket.org/pypy/pypy/changeset/7a260b2c4511/ Log: should try listview_unicode here too 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 @@ -726,6 +726,13 @@ w_list.lstorage = strategy.erase(strlist[:]) return + unilist = space.listview_unicode(w_iterable) + if unilist is not None: + w_list.strategy = strategy = space.fromcache(UnicodeListStrategy) + # need to copy because intlist can share with w_iterable + w_list.lstorage = strategy.erase(unilist[:]) + return + ListStrategy._extend_from_iterable(self, w_list, w_iterable) def reverse(self, w_list): From noreply at buildbot.pypy.org Mon Mar 25 17:48:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 17:48:40 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Phew, finally I have (maybe) found out the right algorithm... Message-ID: <20130325164840.B65A21C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62743:21829c4cca75 Date: 2013-03-25 17:48 +0100 http://bitbucket.org/pypy/pypy/changeset/21829c4cca75/ Log: Phew, finally I have (maybe) found out the right algorithm... diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -74,7 +74,8 @@ is_rpython_class, has_custom_trace, get_custom_trace, - fast_path_tracing): + fast_path_tracing, + call_finalizer): self.getdestructor = getdestructor self.is_varsize = is_varsize self.has_gcptr_in_varsize = has_gcptr_in_varsize @@ -91,6 +92,7 @@ self.has_custom_trace = has_custom_trace self.get_custom_trace = get_custom_trace self.fast_path_tracing = fast_path_tracing + self.call_finalizer = call_finalizer def get_member_index(self, type_id): return self.member_index(type_id) @@ -351,22 +353,16 @@ obj = self.run_finalizers_queue.peekleft() finalizer = self.registered_finalizers.get(obj) ll_assert(finalizer != llmemory.NULL, "lost finalizer") - finalizer = llmemory.cast_adr_to_ptr(finalizer, FINALIZER) - try: - finalizer(obj) - except rgc.FinalizeLater: + if not self.call_finalizer(finalizer, obj): break - except Exception, e: - XXX obj1 = self.run_finalizers_queue.popleft() ll_assert(obj1 == obj, "wrong finalized object") + self.registered_finalizers.setitem(obj, NULL) + # XXX MISSING: must clean up the dict regularly! finally: self.running_finalizers = False -FINALIZER = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void)) - - class MovingGCBase(GCBase): moving_gc = True diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1250,6 +1250,10 @@ # We proceed until 'old_objects_pointing_to_young' is empty. self.collect_oldrefs_to_nursery() # + # Also copy out of the nursery the objects with finalizers. + if self.young_objects_with_finalizers.non_empty(): + self.deal_with_young_objects_with_finalizers() + # # Now all live nursery objects should be out. Update the young # weakrefs' targets. if self.young_objects_with_weakrefs.non_empty(): @@ -1882,63 +1886,65 @@ # ---------- # Finalizers - def collect_roots_from_finalizers(self): - self.young_objects_with_finalizers.foreach( - self._collect_root_from_finalizer, None) - - def _collect_root_from_finalizer(self, obj, ignored): - # idea: every young object with a finalizer xxxxxxxxxxxx - self.temp_root.address[0] = obj - self._trace_drag_out1(self.temp_root) - def deal_with_young_objects_with_finalizers(self): - """We need to enqueue to run_finalizers_queue all dying young + """We need to enqueue to 'run_finalizers_queue' all dying young objects with finalizers. As these survive for a bit longer, - we also need to copy them out of the nursery. + we also need to copy them out of the nursery. The tricky part + here is to enqueue them in topological order, if possible. """ - xxxxxxxx - if self.young_objects_call_finalizers is not None: - xxxx - - - if not self.young_objects_with_finalizers.non_empty(): - return False - + finalizers_scheduled = self.AddressStack() + pending = self.old_objects_pointing_to_young + # while self.young_objects_with_finalizers.non_empty(): obj = self.young_objects_with_finalizers.pop() - if not self.is_forwarded(obj): - # - # If the object is not forwarded so far, then it is a - # newly discovered object that is about to be finalized. - ll_assert((self.header(obj).tid & GCFLAG_HAS_FINALIZER) != 0, - "lost the GCFLAG_HAS_FINALIZER") - # - # The object survives this collection; it must be tracked. - # - # Add the object in the 'young_objects_call_finalizers' - # stack. - if self.young_objects_call_finalizers is None: - self.young_objects_call_finalizers = self.AddressStack() - self.young_objects_call_finalizers.append(obj) - # - # We want to ensure topological ordering on the finalizers, - # at least assuming that there are no cycles. So xxxx - # - - # - # The stack will be moved to 'run_finalizers_queue' - # to reverse the order: - # - xxx - - - - else: - yyy - obj = self.get_forwarding_address(obj) - self.old_objects_with_finalizers.append(obj) - - return self.young_objects_call_finalizers is not None + ll_assert(not pending.non_empty(), + "deal_with_young_objects_with_finalizers: " + "old_objects_pointing_to_young should be empty") + # + # Un-register the finalizer, because 'obj' will likely move + _finalizer = self.registered_finalizers.get(obj) + ll_assert(_finalizer != llmemory.NULL, "lost _finalizer") + self.registered_finalizers.setitem(obj, NULL) + # + # The following lines move 'obj' out of the nursery and add it to + # 'self.old_objects_pointing_to_young', unless the object was + # already seen previously, in which case they have no effect. + root = self.temp_root + root.address[0] = obj + self._trace_drag_out1(root) + objcopy = root.address[0] + # + # Re-regsiter the finalizer + self.registered_finalizers.setitem(objcopy, _finalizer) + # + # Follow all refs + while pending.non_empty(): + assert not self.old_objects_with_cards_set.non_empty(), "XXX" + obj = pending.pop() + if obj: + # + if self.header(obj).tid & GCFLAG_HAS_FINALIZER: + self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER + pending.append(obj) + pending.append(NULL) # marker + # + ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS + == 0, "bad flags [deal_young_finalizer]") + self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS + self.trace_and_drag_out_of_nursery(obj) + # + else: + # seen a NULL marker + obj = pending.pop() + finalizers_scheduled.append(obj) + # End of loop + # + # Copy the objects scheduled into 'run_finalizers_queue', in + # reverse order. + while finalizers_scheduled.non_empty(): + obj = finalizers_scheduled.pop() + self.run_finalizers_queue.append(obj) + finalizers_scheduled.delete() def deal_with_old_objects_with_finalizers(self): diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -3,6 +3,8 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.debug import ll_assert from rpython.rlib.rarithmetic import intmask +from rpython.rlib import rgc +from rpython.rlib.objectmodel import we_are_translated from rpython.tool.identity_dict import identity_dict @@ -135,6 +137,19 @@ infobits = self.get(typeid).infobits return infobits & T_ANY_SLOW_FLAG == 0 + def q_call_finalizer(self, finalizer, obj): + XXX + FINALIZER = lltype.Ptr(lltype.FuncType([llmemory.Address], + lltype.Void)) + finalizer = llmemory.cast_adr_to_ptr(finalizer, FINALIZER) + finalizer(obj) +## except rgc.FinalizeLater: +## xxx +## except Exception, e: +## XXX + return True + + def set_query_functions(self, gc): gc.set_query_functions( self.q_is_varsize, @@ -152,7 +167,8 @@ self.q_is_rpython_class, self.q_has_custom_trace, self.q_get_custom_trace, - self.q_fast_path_tracing) + self.q_fast_path_tracing, + self.q_call_finalizer) # the lowest 16bits are used to store group member index @@ -387,8 +403,11 @@ # must be overridden for proper custom tracer support return None - def initialize_gc_query_function(self, gc): - return GCData(self.type_info_group).set_query_functions(gc) + def initialize_gc_query_function(self, gc, call_finalizer=None): + gcdata = GCData(self.type_info_group) + if call_finalizer is not None: + gcdata.q_call_finalizer = call_finalizer # for tests + gcdata.set_query_functions(gc) def consider_constant(self, TYPE, value, gc): if value is not lltype.top_container(value): diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -29,7 +29,8 @@ lltype2vtable, self.llinterp) self.get_type_id = layoutbuilder.get_type_id - layoutbuilder.initialize_gc_query_function(self.gc) + layoutbuilder.initialize_gc_query_function( + self.gc, layoutbuilder._call_finalizer) constants = collect_constants(flowgraphs) for obj in constants: @@ -238,6 +239,13 @@ else: return None + def _call_finalizer(self, finalizer, obj): + FUNC = lltype.typeOf(finalizer.ptr).TO + obj = llmemory.cast_adr_to_ptr(obj, FUNC.ARGS[0]) + self.llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], + recursive=True) + return True + def collect_constants(graphs): constants = {} diff --git a/rpython/memory/support.py b/rpython/memory/support.py --- a/rpython/memory/support.py +++ b/rpython/memory/support.py @@ -114,6 +114,11 @@ self.shrink() return result + def peek(self): + used = self.used_in_last_chunk - 1 + ll_assert(used >= 0, "peek on empty AddressStack") + return self.chunk.items[used] + def delete(self): cur = self.chunk while cur: @@ -270,6 +275,14 @@ cur = next free_non_gc_object(self) + def tolist(self): + """NOT_RPYTHON. Returns the content as a list.""" + lst = [] + def _add(obj, lst): + lst.append(obj) + self.foreach(_add, lst) + return lst + cache[chunk_size] = AddressDeque return AddressDeque @@ -332,6 +345,14 @@ for key, value in self.data.iteritems(): callback(self._wrapkey(key), value, arg) + def tolist(self): + """NOT_RPYTHON. Returns the content as a list.""" + lst = [] + def _add(key, value, lst): + lst.append((key, value)) + self.foreach(_add, lst) + return lst + def copy_and_update(dict, surviving, updated_address): """Make a copy of 'dict' in which the keys are updated as follows: diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -158,13 +158,14 @@ pass b = B() b.nextid = 0 - b.num_finalized = 0 + b.num_finalized = -42 class A(object): def __init__(self): self.id = b.nextid b.nextid += 1 def finalizer(self): b.num_finalized += 1 + print "BIP", b.num_finalized def allocate(x): i = 0 while i < x: @@ -172,9 +173,14 @@ a = A() rgc.register_finalizer(a.finalizer) def f(x): + print 'START' + b.num_finalized = 0 allocate(x) + print 'XX', b.num_finalized llop.gc__collect(lltype.Void) + print 'XX', b.num_finalized llop.gc__collect(lltype.Void) + print 'XX', b.num_finalized return b.num_finalized res = self.interpret(f, [6]) assert res == 6 diff --git a/rpython/memory/test/test_support.py b/rpython/memory/test/test_support.py --- a/rpython/memory/test/test_support.py +++ b/rpython/memory/test/test_support.py @@ -49,8 +49,9 @@ print i ll.append(addrs[i]) for i in range(3000)[::-1]: + b = ll.peek() a = ll.pop() - assert a == addrs[i] + assert b == a == addrs[i] for i in range(3000): print i ll.append(addrs[i]) From noreply at buildbot.pypy.org Mon Mar 25 18:55:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 18:55:47 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Fixes Message-ID: <20130325175547.5730E1C2F70@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62744:5bf139dc8885 Date: 2013-03-25 18:11 +0100 http://bitbucket.org/pypy/pypy/changeset/5bf139dc8885/ Log: Fixes diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -37,7 +37,7 @@ # and in its overriden versions! for the benefit of test_transformed_gc self.running_finalizers = False self.run_finalizers_queue = self.AddressDeque() - self.registered_finalizers = self.AddressDict() + self.run_finalizers_funcs = self.AddressDeque() def post_setup(self): # More stuff that needs to be initialized when the GC is already @@ -333,15 +333,9 @@ def register_finalizer(self, gcobj, llfn): llobj = llmemory.cast_ptr_to_adr(gcobj) - llfn1 = self.registered_finalizers.get(llobj) - if llfn1 == llmemory.NULL: - self.registered_finalizers.setitem(llobj, llfn) - else: - ll_assert(llfn1 == llfn, - "registering multiple different finalizers") - self._register_finalizer_set_flag(llobj) + self._register_finalizer(llobj, llfn) - def _register_finalizer_set_flag(self, obj): + def _register_finalizer(self, obj, llfn): raise NotImplementedError # must be overridden def execute_finalizers(self): @@ -350,15 +344,12 @@ self.running_finalizers = True try: while self.run_finalizers_queue.non_empty(): + func = self.run_finalizers_funcs.peekleft() obj = self.run_finalizers_queue.peekleft() - finalizer = self.registered_finalizers.get(obj) - ll_assert(finalizer != llmemory.NULL, "lost finalizer") - if not self.call_finalizer(finalizer, obj): + if not self.call_finalizer(func, obj): break - obj1 = self.run_finalizers_queue.popleft() - ll_assert(obj1 == obj, "wrong finalized object") - self.registered_finalizers.setitem(obj, NULL) - # XXX MISSING: must clean up the dict regularly! + self.run_finalizers_funcs.popleft() + self.run_finalizers_queue.popleft() finally: self.running_finalizers = False diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -302,9 +302,8 @@ self.old_objects_with_destructors = self.AddressStack() # # Two lists of all objects with finalizers, and a temporary - self.young_objects_with_finalizers = self.AddressStack() - self.old_objects_with_finalizers = self.AddressStack() - self.pending_objects_with_finalizers = self.AddressStack() + self.young_objects_with_finalizers = self.AddressStack() # (obj,fn) + self.old_objects_with_finalizers = self.AddressStack() # (obj,fn) # # Two lists of the objects with weakrefs. No weakref can be an # old object weakly pointing to a young object: indeed, weakrefs @@ -967,12 +966,16 @@ "the card marker bits are not cleared") i -= 1 - def _register_finalizer_set_flag(self, obj): + def _register_finalizer(self, obj, llfn): + if self.header(obj).tid & GCFLAG_HAS_FINALIZER: + return # already have one self.header(obj).tid |= GCFLAG_HAS_FINALIZER if self.is_young_object(obj): - self.young_objects_with_finalizers.append(obj) + lst = self.young_objects_with_finalizers else: - self.old_objects_with_finalizers.append(obj) + lst = self.old_objects_with_finalizers + lst.append(obj) + lst.append(llfn) # ---------- # Write barrier @@ -1892,59 +1895,58 @@ we also need to copy them out of the nursery. The tricky part here is to enqueue them in topological order, if possible. """ - finalizers_scheduled = self.AddressStack() pending = self.old_objects_pointing_to_young + ll_assert(not pending.non_empty(), + "deal_with_young_objects_with_finalizers: " + "old_objects_pointing_to_young should be empty") + finalizer_funcs = self.AddressDict() # while self.young_objects_with_finalizers.non_empty(): + func = self.young_objects_with_finalizers.pop() obj = self.young_objects_with_finalizers.pop() - ll_assert(not pending.non_empty(), - "deal_with_young_objects_with_finalizers: " - "old_objects_pointing_to_young should be empty") - # - # Un-register the finalizer, because 'obj' will likely move - _finalizer = self.registered_finalizers.get(obj) - ll_assert(_finalizer != llmemory.NULL, "lost _finalizer") - self.registered_finalizers.setitem(obj, NULL) # # The following lines move 'obj' out of the nursery and add it to - # 'self.old_objects_pointing_to_young', unless the object was - # already seen previously, in which case they have no effect. + # 'self.old_objects_pointing_to_young'. root = self.temp_root root.address[0] = obj self._trace_drag_out1(root) objcopy = root.address[0] # - # Re-regsiter the finalizer - self.registered_finalizers.setitem(objcopy, _finalizer) - # - # Follow all refs - while pending.non_empty(): - assert not self.old_objects_with_cards_set.non_empty(), "XXX" + # Remember the finalizer in the dict + finalizer_funcs.setitem(objcopy, func) + # + # Now follow all the refs + finalizers_scheduled = self.AddressStack() + while pending.non_empty(): + assert not self.old_objects_with_cards_set.non_empty(), "XXX" + obj = pending.pop() + if obj: + # + if self.header(obj).tid & GCFLAG_HAS_FINALIZER: + self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER + pending.append(obj) + pending.append(NULL) # marker + # + ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS + == 0, "bad flags [deal_young_finalizer]") + self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS + self.trace_and_drag_out_of_nursery(obj) + # + else: + # seen a NULL marker obj = pending.pop() - if obj: - # - if self.header(obj).tid & GCFLAG_HAS_FINALIZER: - self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER - pending.append(obj) - pending.append(NULL) # marker - # - ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS - == 0, "bad flags [deal_young_finalizer]") - self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS - self.trace_and_drag_out_of_nursery(obj) - # - else: - # seen a NULL marker - obj = pending.pop() - finalizers_scheduled.append(obj) - # End of loop + finalizers_scheduled.append(obj) # # Copy the objects scheduled into 'run_finalizers_queue', in # reverse order. while finalizers_scheduled.non_empty(): obj = finalizers_scheduled.pop() + func = finalizer_funcs.get(obj) + ll_assert(func != llmemory.NULL, "lost finalizer [1]") self.run_finalizers_queue.append(obj) + self.run_finalizers_funcs.append(func) finalizers_scheduled.delete() + finalizer_funcs.delete() def deal_with_old_objects_with_finalizers(self): From noreply at buildbot.pypy.org Mon Mar 25 18:55:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 18:55:48 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Record surviving young objects with finalizers. Message-ID: <20130325175548.A39591C2F70@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62745:53d11c6f0880 Date: 2013-03-25 18:29 +0100 http://bitbucket.org/pypy/pypy/changeset/53d11c6f0880/ Log: Record surviving young objects with finalizers. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1596,8 +1596,8 @@ # with a finalizer and all objects reachable from there (and also # moves some objects from 'objects_with_finalizers' to # 'run_finalizers'). - #if self.objects_with_finalizers.non_empty(): - # self.deal_with_objects_with_finalizers() + if self.old_objects_with_finalizers.non_empty(): + self.deal_with_old_objects_with_finalizers() # self.objects_to_trace.delete() # @@ -1880,11 +1880,29 @@ if not self.is_forwarded(obj): destructor = self.getdestructor(self.get_type_id(obj)) ll_assert(bool(destructor), "destructor missing") - destructor(obj, llmemory.NULL) + destructor(obj, NULL) else: obj = self.get_forwarding_address(obj) self.old_objects_with_destructors.append(obj) + def deal_with_old_objects_with_destructors(self): + """Same as deal_with_young_objects_with_destructors(), but for + old objects. + """ + new_objects = self.AddressStack() + while self.old_objects_with_destructors.non_empty(): + obj = self.old_objects_with_destructors.pop() + if self.header(obj).tid & GCFLAG_VISITED: + # surviving + new_objects.append(obj) + else: + # dying + destructor = self.getdestructor(self.get_type_id(obj)) + ll_assert(bool(destructor), "no light finalizer found") + destructor(obj, NULL) + self.old_objects_with_destructors.delete() + self.old_objects_with_destructors = new_objects + # ---------- # Finalizers @@ -1906,7 +1924,9 @@ obj = self.young_objects_with_finalizers.pop() # # The following lines move 'obj' out of the nursery and add it to - # 'self.old_objects_pointing_to_young'. + # 'self.old_objects_pointing_to_young' --- unless the object + # survive, in which case it was already seen and the following + # lines have no effect. root = self.temp_root root.address[0] = obj self._trace_drag_out1(root) @@ -1942,36 +1962,27 @@ while finalizers_scheduled.non_empty(): obj = finalizers_scheduled.pop() func = finalizer_funcs.get(obj) - ll_assert(func != llmemory.NULL, "lost finalizer [1]") + ll_assert(func != NULL, "lost finalizer [1]") self.run_finalizers_queue.append(obj) self.run_finalizers_funcs.append(func) + finalizer_funcs.setitem(obj, NULL) finalizers_scheduled.delete() + # + # The non-NULL entries remaining in 'finalizer_funcs' correspond + # to objects that survived, because they have not been traced by + # this function but already before. + finalizer_funcs.foreach(self._move_to_old_finalizer, + self.old_objects_with_finalizers) finalizer_funcs.delete() + @staticmethod + def _move_to_old_finalizer(obj, finalizer, old_objects_with_finalizers): + if finalizer != NULL: + old_objects_with_finalizers.append(obj) + old_objects_with_finalizers.append(finalizer) + def deal_with_old_objects_with_finalizers(self): - """ This is a much simpler version of dealing with finalizers - and an optimization - we can reasonably assume that those finalizers - don't do anything fancy and *just* call them. Among other things - they won't resurrect objects - """ - XXXX - new_objects = self.AddressStack() - while self.old_objects_with_light_finalizers.non_empty(): - obj = self.old_objects_with_light_finalizers.pop() - if self.header(obj).tid & GCFLAG_VISITED: - # surviving - new_objects.append(obj) - else: - # dying - finalizer = self.getlightfinalizer(self.get_type_id(obj)) - ll_assert(bool(finalizer), "no light finalizer found") - finalizer(obj, llmemory.NULL) - self.old_objects_with_light_finalizers.delete() - self.old_objects_with_light_finalizers = new_objects - - def deal_with_objects_with_finalizers(self): - XXXXXXXXX # Walk over list of objects with finalizers. # If it is not surviving, add it to the list of to-be-called # finalizers and make it survive, to make the finalizer runnable. From noreply at buildbot.pypy.org Mon Mar 25 18:55:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 18:55:49 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Copy the logic for young objects with finalizers, for the Message-ID: <20130325175549.EB4101C2F70@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62746:a5a3becb36e8 Date: 2013-03-25 18:55 +0100 http://bitbucket.org/pypy/pypy/changeset/a5a3becb36e8/ Log: Copy the logic for young objects with finalizers, for the handling of old objects with finalizers. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -940,6 +940,10 @@ # the GCFLAG_VISITED should not be set between collections ll_assert(self.header(obj).tid & GCFLAG_VISITED == 0, "unexpected GCFLAG_VISITED") + # the GCFLAG_NO_HEAP_PTRS and GCFLAG_HAS_FINALIZER must not be both set + ll_assert(self.header(obj).tid & GCFLAG_NO_HEAP_PTRS == 0 or + self.header(obj).tid & GCFLAG_HAS_FINALIZER == 0, + "GCFLAG_NO_HEAP_PTRS && GCFLAG_HAS_FINALIZER") # the GCFLAG_CARDS_SET should not be set between collections ll_assert(self.header(obj).tid & GCFLAG_CARDS_SET == 0, "unexpected GCFLAG_CARDS_SET") @@ -967,8 +971,10 @@ i -= 1 def _register_finalizer(self, obj, llfn): - if self.header(obj).tid & GCFLAG_HAS_FINALIZER: - return # already have one + if self.header(obj).tid & ( + GCFLAG_HAS_FINALIZER | # obj has already a finalizer + GCFLAG_NO_HEAP_PTRS): # immortal object anyway, and we don't + return # want confusion in visit() self.header(obj).tid |= GCFLAG_HAS_FINALIZER if self.is_young_object(obj): lst = self.young_objects_with_finalizers @@ -1989,90 +1995,60 @@ # We try to run the finalizers in a "reasonable" order, like # CPython does. The details of this algorithm are in # pypy/doc/discussion/finalizer-order.txt. - new_with_finalizer = self.AddressDeque() - marked = self.AddressDeque() - pending = self.AddressStack() - self.tmpstack = self.AddressStack() - while self.objects_with_finalizers.non_empty(): - x = self.objects_with_finalizers.popleft() - ll_assert(self._finalization_state(x) != 1, - "bad finalization state 1") - if self.header(x).tid & GCFLAG_VISITED: - new_with_finalizer.append(x) - continue - marked.append(x) - pending.append(x) - while pending.non_empty(): - y = pending.pop() - state = self._finalization_state(y) - if state == 0: - self._bump_finalization_state_from_0_to_1(y) - self.trace(y, self._append_if_nonnull, pending) - elif state == 2: - self._recursively_bump_finalization_state_from_2_to_3(y) - self._recursively_bump_finalization_state_from_1_to_2(x) - - while marked.non_empty(): - x = marked.popleft() - state = self._finalization_state(x) - ll_assert(state >= 2, "unexpected finalization state < 2") - if state == 2: - self.run_finalizers.append(x) - # we must also fix the state from 2 to 3 here, otherwise - # we leave the GCFLAG_FINALIZATION_ORDERING bit behind - # which will confuse the next collection - self._recursively_bump_finalization_state_from_2_to_3(x) + # + ll_assert(not self.objects_to_trace.non_empty(), + "objects_to_trace non empty [deal_old_finalizer]") + # + old_objs = self.old_objects_with_finalizers + self.old_objects_with_finalizers = self.AddressStack() + finalizer_funcs = self.AddressDict() + # + while old_objs.non_empty(): + func = old_objs.pop() + obj = old_objs.pop() + ll_assert(bool(self.header(obj).tid & GCFLAG_HAS_FINALIZER), + "lost GCFLAG_HAS_FINALIZER") + # + if self.header(obj).tid & GCFLAG_VISITED: + # surviving + self.old_objects_with_finalizers.append(obj) + self.old_objects_with_finalizers.append(func) + # else: - new_with_finalizer.append(x) - - self.tmpstack.delete() - pending.delete() - marked.delete() - self.objects_with_finalizers.delete() - self.objects_with_finalizers = new_with_finalizer - - def _append_if_nonnull(pointer, stack): - stack.append(pointer.address[0]) - _append_if_nonnull = staticmethod(_append_if_nonnull) - - def _finalization_state(self, obj): - tid = self.header(obj).tid - if tid & GCFLAG_VISITED: - if tid & GCFLAG_FINALIZATION_ORDERING: - return 2 + # dying + self.objects_to_trace.append(obj) + finalizer_funcs.setitem(obj, func) + # + # Now follow all the refs + finalizers_scheduled = self.AddressStack() + pending = self.objects_to_trace + while pending.non_empty(): + obj = pending.pop() + if obj: + # + if self.header(obj).tid & GCFLAG_HAS_FINALIZER: + self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER + pending.append(obj) + pending.append(NULL) # marker + # + self.visit(obj) + # else: - return 3 - else: - if tid & GCFLAG_FINALIZATION_ORDERING: - return 1 - else: - return 0 - - def _bump_finalization_state_from_0_to_1(self, obj): - ll_assert(self._finalization_state(obj) == 0, - "unexpected finalization state != 0") - hdr = self.header(obj) - hdr.tid |= GCFLAG_FINALIZATION_ORDERING - - def _recursively_bump_finalization_state_from_2_to_3(self, obj): - ll_assert(self._finalization_state(obj) == 2, - "unexpected finalization state != 2") - pending = self.tmpstack - ll_assert(not pending.non_empty(), "tmpstack not empty") - pending.append(obj) - while pending.non_empty(): - y = pending.pop() - hdr = self.header(y) - if hdr.tid & GCFLAG_FINALIZATION_ORDERING: # state 2 ? - hdr.tid &= ~GCFLAG_FINALIZATION_ORDERING # change to state 3 - self.trace(y, self._append_if_nonnull, pending) - - def _recursively_bump_finalization_state_from_1_to_2(self, obj): - # recursively convert objects from state 1 to state 2. - # The call to visit_all_objects() will add the GCFLAG_VISITED - # recursively. - self.objects_to_trace.append(obj) - self.visit_all_objects() + # seen a NULL marker + obj = pending.pop() + finalizers_scheduled.append(obj) + # + # Copy the objects scheduled into 'run_finalizers_queue', in + # reverse order. + while finalizers_scheduled.non_empty(): + obj = finalizers_scheduled.pop() + func = finalizer_funcs.get(obj) + ll_assert(func != NULL, "lost finalizer [2]") + self.run_finalizers_queue.append(obj) + self.run_finalizers_funcs.append(func) + finalizers_scheduled.delete() + finalizer_funcs.delete() + old_objs.delete() # ---------- diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -8,6 +8,7 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.objectmodel import compute_unique_id +from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import rgc from rpython.rlib.rstring import StringBuilder from rpython.rlib.rarithmetic import LONG_BIT @@ -158,14 +159,13 @@ pass b = B() b.nextid = 0 - b.num_finalized = -42 + b.num_finalized = 0 class A(object): def __init__(self): self.id = b.nextid b.nextid += 1 def finalizer(self): b.num_finalized += 1 - print "BIP", b.num_finalized def allocate(x): i = 0 while i < x: @@ -173,14 +173,41 @@ a = A() rgc.register_finalizer(a.finalizer) def f(x): - print 'START' + allocate(x) + llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) + return b.num_finalized + res = self.interpret(f, [6]) + assert res == 6 + + def test_finalizer_old(self): + class B(object): + pass + b = B() + b.nextid = 0 + b.num_finalized = 0 + class A(object): + def __init__(self): + self.id = b.nextid + b.nextid += 1 + def finalizer(self): + b.num_finalized += 1 + def allocate(x): + i = 0 + next = None + while i < x: + i += 1 + a = A() + a.next = next + next = a + rgc.register_finalizer(a.finalizer) + llop.gc__collect(lltype.Void) # all objects are now old + keepalive_until_here(next) + def f(x): b.num_finalized = 0 allocate(x) - print 'XX', b.num_finalized llop.gc__collect(lltype.Void) - print 'XX', b.num_finalized llop.gc__collect(lltype.Void) - print 'XX', b.num_finalized return b.num_finalized res = self.interpret(f, [6]) assert res == 6 From noreply at buildbot.pypy.org Mon Mar 25 19:04:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 19:04:37 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Relax the test, allowing now several finalizers to be called by the same Message-ID: <20130325180437.C46011C2F79@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62747:7ef9ac5bf2d6 Date: 2013-03-25 19:04 +0100 http://bitbucket.org/pypy/pypy/changeset/7ef9ac5bf2d6/ Log: Relax the test, allowing now several finalizers to be called by the same gc.collect() --- but still checking that the order is correct. diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -56,6 +56,7 @@ def finalize(self): assert state.age[self.key] == -1 state.age[self.key] = state.time + state.time += 1 state.progress = True def build_example(input): @@ -73,7 +74,7 @@ while i < len(examples): input, components, strict = examples[i] build_example(input) - while state.time < len(letters): + while state.time < 2 * len(letters): state.progress = False llop.gc__collect(lltype.Void) if not state.progress: From noreply at buildbot.pypy.org Mon Mar 25 19:22:02 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 19:22:02 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Various efforts to make this test pass --- but it was actually miswritten. Message-ID: <20130325182202.C9E6E1C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62748:a1039dd12074 Date: 2013-03-25 19:21 +0100 http://bitbucket.org/pypy/pypy/changeset/a1039dd12074/ Log: Various efforts to make this test pass --- but it was actually miswritten. diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -220,16 +220,16 @@ t = self.llinterp.typer.annotator.translator DestructorAnalyzer(t).check_destructor(destrgraph) - def ll_finalizer(addr, dummy): + def ll_destructor(addr, dummy): assert dummy == llmemory.NULL try: v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) self.llinterp.eval_graph(destrgraph, [v], recursive=True) except llinterp.LLException: raise RuntimeError( - "a finalizer raised an exception, shouldn't happen") + "a destructor raised an exception, shouldn't happen") return llmemory.NULL - return llhelper(gctypelayout.GCData.DESTRUCTOR_OR_CT, ll_finalizer) + return llhelper(gctypelayout.GCData.DESTRUCTOR_OR_CT, ll_destructor) def make_custom_trace_funcptr_for_type(self, TYPE): from rpython.memory.gctransform.support import get_rtti @@ -242,8 +242,12 @@ def _call_finalizer(self, finalizer, obj): FUNC = lltype.typeOf(finalizer.ptr).TO obj = llmemory.cast_adr_to_ptr(obj, FUNC.ARGS[0]) - self.llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], - recursive=True) + try: + self.llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], + recursive=True) + except llinterp.LLException: + raise RuntimeError( + "a finalizer raised an exception, shouldn't happen") return True diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -12,6 +12,7 @@ from rpython.rlib import rgc from rpython.rlib.rstring import StringBuilder from rpython.rlib.rarithmetic import LONG_BIT +from rpython.rlib.debug import debug_print WORD = LONG_BIT // 8 @@ -224,7 +225,10 @@ self.id = b.nextid b.nextid += 1 def finalizer(self): - assert n.num_deleted <= b.num_finalized + if b.num_deleted > b.num_finalized: + debug_print("Oups! num_deleted =", b.num_deleted, + "but num_finalized =", b.num_finalized) + raise AssertionError b.num_finalized += 1 def __del__(self): b.num_deleted += 1 @@ -235,8 +239,13 @@ while i < x: i += 1 a = A() + rgc.register_finalizer(a.finalizer) + a = None + debug_print("first collection (minor only)...") + llop.gc__collect(lltype.Void, 0) + debug_print("second collection...") llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) + debug_print("done") return b.num_finalized * 100 + b.num_deleted res = self.interpret(f, [5]) assert res == 606 From noreply at buildbot.pypy.org Mon Mar 25 19:31:43 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 25 Mar 2013 19:31:43 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: merge default into branch Message-ID: <20130325183143.7BFDE1C2F7B@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62749:6dddd0f38a66 Date: 2013-03-22 17:59 -0700 http://bitbucket.org/pypy/pypy/changeset/6dddd0f38a66/ Log: merge default into branch diff too long, truncating to 2000 out of 129998 lines diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -12,6 +12,11 @@ import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from itertools import imap as _imap +try: + from __pypy__ import newdict +except ImportError: + assert '__pypy__' not in _sys.builtin_module_names + newdict = lambda _ : {} try: from thread import get_ident as _get_ident @@ -326,8 +331,11 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = newdict('module') + namespace['OrderedDict'] = OrderedDict + namespace['_property'] = property + namespace['_tuple'] = tuple + namespace['__name__'] = 'namedtuple_%s' % typename try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2/distutils/sysconfig_pypy.py b/lib-python/2/distutils/sysconfig_pypy.py --- a/lib-python/2/distutils/sysconfig_pypy.py +++ b/lib-python/2/distutils/sysconfig_pypy.py @@ -23,7 +23,7 @@ leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. """ - return sys.version[0] + return sys.version[:3] def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): @@ -43,7 +43,7 @@ if prefix is None: prefix = PREFIX if standard_lib: - return os.path.join(prefix, "lib-python", get_python_version()) + return os.path.join(prefix, "lib-python", sys.version[0]) return os.path.join(prefix, 'site-packages') @@ -61,6 +61,7 @@ g['SO'] = _get_so_extension() or ".so" g['SOABI'] = g['SO'].rsplit('.')[0] g['LIBDIR'] = os.path.join(sys.prefix, 'lib') + g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check global _config_vars _config_vars = g diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1409,11 +1409,26 @@ except ImportError: from StringIO import StringIO +try: + from __pypy__.builders import StringBuilder +except ImportError: + assert '__pypy__' not in sys.builtin_module_names + StringBuilderFile = StringIO +else: + class StringBuilderFile(object): + ''' pickle uses only file.write - provide this method, + use StringBuilder for speed + ''' + def __init__(self): + self.builder = StringBuilder() + self.write = self.builder.append + self.getvalue = self.builder.build + def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib-python/2/sre_parse.py b/lib-python/2/sre_parse.py --- a/lib-python/2/sre_parse.py +++ b/lib-python/2/sre_parse.py @@ -19,8 +19,8 @@ try: from __pypy__ import newdict except ImportError: - def newdict(tp): - return {} + assert '__pypy__' not in sys.builtin_module_names + newdict = lambda _ : {} SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -7,7 +7,6 @@ # the "sandboxed" process. It must work for Python2 as well. import types -from _codecs import utf_8_decode, utf_8_encode try: intern @@ -166,9 +165,8 @@ def dump_unicode(self, x): self._write(TYPE_UNICODE) - #s = x.encode('utf8') - s, len_s = utf_8_encode(x) - self.w_long(len_s) + s = x.encode('utf8') + self.w_long(len(s)) self._write(s) try: unicode @@ -386,8 +384,7 @@ def load_unicode(self): n = self.r_long() s = self._read(n) - #ret = s.decode('utf8') - ret, len_ret = utf_8_decode(s) + ret = s.decode('utf8') return ret dispatch[TYPE_UNICODE] = load_unicode diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -364,9 +364,10 @@ self._in_transaction = False self.isolation_level = isolation_level - self._cursors = [] + self.__cursors = [] + self.__cursors_counter = 0 self.__statements = [] - self.__statement_counter = 0 + self.__statements_counter = 0 self._statement_cache = _StatementCache(self, cached_statements) self.__func_cache = {} @@ -394,10 +395,7 @@ def close(self): self._check_thread() - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._finalize() + self.__do_all_statements(Statement._finalize, True) if self._db: ret = _lib.sqlite3_close(self._db) @@ -469,13 +467,33 @@ exc.error_code = error_code return exc + def _remember_cursor(self, cursor): + self.__cursors.append(weakref.ref(cursor)) + self.__cursors_counter += 1 + if self.__cursors_counter < 200: + return + self.__cursors_counter = 0 + self.__cursors = [r for r in self.__cursors if r() is not None] + def _remember_statement(self, statement): self.__statements.append(weakref.ref(statement)) - self.__statement_counter += 1 + self.__statements_counter += 1 + if self.__statements_counter < 200: + return + self.__statements_counter = 0 + self.__statements = [r for r in self.__statements if r() is not None] - if self.__statement_counter % 100 == 0: - self.__statements = [ref for ref in self.__statements - if ref() is not None] + def __do_all_statements(self, action, reset_cursors): + for weakref in self.__statements: + statement = weakref() + if statement is not None: + action(statement) + + if reset_cursors: + for weakref in self.__cursors: + cursor = weakref() + if cursor is not None: + cursor._reset = True @_check_thread_wrap @_check_closed_wrap @@ -528,10 +546,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() + self.__do_all_statements(Statement._reset, False) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, @@ -552,15 +567,7 @@ if not self._in_transaction: return - for statement in self.__statements: - obj = statement() - if obj is not None: - obj._reset() - - for cursor_ref in self._cursors: - cursor = cursor_ref() - if cursor: - cursor._reset = True + self.__do_all_statements(Statement._reset, True) statement = c_void_p() ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, @@ -787,14 +794,9 @@ __statement = None def __init__(self, con): - self.__initialized = True - self.__connection = con - if not isinstance(con, Connection): raise TypeError - con._check_thread() - con._check_closed() - con._cursors.append(weakref.ref(self)) + self.__connection = con self.arraysize = 1 self.row_factory = None @@ -804,11 +806,12 @@ self.__description = None self.__rowcount = -1 + con._check_thread() + con._remember_cursor(self) + + self.__initialized = True + def __del__(self): - try: - self.__connection._cursors.remove(weakref.ref(self)) - except (AttributeError, ValueError): - pass if self.__statement: self.__statement._reset() @@ -883,7 +886,6 @@ self.__rowcount += _lib.sqlite3_changes(self.__connection._db) finally: self.__locked = False - return self @__check_cursor_wrap @@ -921,9 +923,10 @@ if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement) if rc == _lib.SQLITE_OK: - return self + break else: raise self.__connection._get_exception(rc) + rc = _lib.sqlite3_finalize(statement) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) @@ -1000,6 +1003,7 @@ def __init__(self, connection, sql): self.__con = connection + self.__con._remember_statement(self) if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") @@ -1027,10 +1031,9 @@ ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1, byref(self._statement), byref(sql)) self._kind = Statement._DQL - if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) - self.__con._remember_statement(self) + sql = sql.value.decode('utf-8') if _check_remaining_sql(sql): raise Warning("You can only execute one statement at a time.") diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -97,12 +97,18 @@ from pickle import StringIO +try: + from pickle import StringBuilderFile +except ImportError: + assert '__pypy__' not in sys.builtin_module_names + StringBuilderFile = StringIO + PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringIO() + self.__f = StringBuilderFile() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) @@ -120,7 +126,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringIO() + file = StringBuilderFile() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -4,6 +4,7 @@ 'array_repr', 'array_str', 'set_string_function', 'array_equal', 'outer', 'vdot', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + 'seterr', ] import sys diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/TODO b/pypy/TODO new file mode 100644 --- /dev/null +++ b/pypy/TODO @@ -0,0 +1,2 @@ + +* ARM diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -33,7 +33,7 @@ modname = os.path.basename(modname) try: checkmodule(modname) - except Exception, e: + except Exception: import traceback, pdb traceback.print_exc() pdb.post_mortem(sys.exc_info()[2]) diff --git a/pypy/bin/dotviewer.py b/pypy/bin/dotviewer.py --- a/pypy/bin/dotviewer.py +++ b/pypy/bin/dotviewer.py @@ -4,6 +4,7 @@ Run with no arguments for help. """ +import os import sys sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))) from dotviewer.dotviewer import main diff --git a/pypy/bin/pyinteractive.py b/pypy/bin/pyinteractive.py --- a/pypy/bin/pyinteractive.py +++ b/pypy/bin/pyinteractive.py @@ -6,14 +6,13 @@ """ -import os, sys +import os +import sys import time sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) -import pypy from pypy.tool import option -from optparse import make_option from pypy.interpreter import main, interactive, error, gateway from rpython.config.config import OptionDescription, BoolOption, StrOption from rpython.config.config import Config, to_optparse diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -61,7 +61,6 @@ def main(): - import sys try: kwds = parse_options(sys.argv[1:]) except AssertionError: diff --git a/pypy/config/test/test_makerestdoc.py b/pypy/config/test/test_makerestdoc.py --- a/pypy/config/test/test_makerestdoc.py +++ b/pypy/config/test/test_makerestdoc.py @@ -1,6 +1,7 @@ +import py + from rpython.config.config import * from pypy.config.makerestdoc import make_cmdline_overview - from pypy.tool.rest.rest import process as restcheck tempdir = py.test.ensuretemp('config') @@ -19,7 +20,7 @@ def generate_html(descr): config = Config(descr) txt = descr.make_rest_doc().text() - + result = {"": txt} for path in config.getpaths(include_groups=True): subconf, step = config._cfgimpl_get_home_by_path(path) diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -20,7 +20,7 @@ * a compliant, flexible and fast implementation of the Python_ Language which uses the above toolchain to enable new advanced high-level features - without having to encode the low-level details. + without having to encode the low-level details. We call this PyPy. By separating concerns in this way, our implementation of Python - and other dynamic languages - is able to automatically @@ -34,7 +34,7 @@ High Level Goals ============================= -PyPy - the Translation Framework +RPython - the Translation Toolchain ----------------------------------------------- Traditionally, language interpreters are written in a target platform language @@ -83,7 +83,7 @@ very challenging because of the involved complexity. -PyPy - the Python Interpreter +PyPy - the Python Interpreter -------------------------------------------- Our main motivation for developing the translation framework is to @@ -113,11 +113,11 @@ of `Extreme Programming`_, the architecture of PyPy has evolved over time and continues to evolve. Nevertheless, the high level architecture is stable. As described above, there are two rather independent basic -subsystems: the `Python Interpreter`_ and the `Translation Framework`_. +subsystems: the `PyPy Python Interpreter`_ and the `RPython Translation Toolchain`_. .. _`translation framework`: -The Translation Framework +RPython Translation Toolchain ------------------------- The job of the RPython toolchain is to translate RPython_ programs @@ -153,7 +153,7 @@ * Optionally, `various transformations`_ can then be applied which, for example, perform optimizations such as inlining, add capabilities - such as stackless-style concurrency (deprecated), or insert code for the + such as stackless-style concurrency, or insert code for the `garbage collector`_. * Then, the graphs are converted to source code for the target platform @@ -174,7 +174,7 @@ .. _`standard interpreter`: .. _`python interpreter`: -The Python Interpreter +PyPy Python Interpreter ------------------------------------- PyPy's *Python Interpreter* is written in RPython and implements the diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -57,7 +57,8 @@ CPython extension and replace it with a pure python version that the JIT can see. -We fully support ctypes-based extensions. +We fully support ctypes-based extensions. But for best performance, we +recommend that you use the cffi_ module to interface with C code. For information on which third party extensions work (or do not work) with PyPy see the `compatibility wiki`_. @@ -65,7 +66,9 @@ .. _`extension modules`: cpython_differences.html#extension-modules .. _`cpython differences`: cpython_differences.html -.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home +.. _`compatibility wiki`: +.. https://bitbucket.org/pypy/compatibility/wiki/Home +.. _cffi: http://cffi.readthedocs.org/ --------------------------------- On which platforms does PyPy run? @@ -77,6 +80,7 @@ bootstrap, as cross compilation is not really meant to work yet. At the moment you need CPython 2.5 - 2.7 for the translation process. PyPy's JIT requires an x86 or x86_64 CPU. +(There has also been good progress on getting the JIT working for ARMv7.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -389,8 +393,7 @@ * Second, and perhaps most important: do you have a really good reason for writing the module in RPython in the first place? Nowadays you should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. + using cffi_ if it needs to call C code. In this context it is not that important to be able to translate RPython modules independently of translating the complete interpreter. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -12,11 +12,10 @@ The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can be used to translate the `full Python interpreter`_). To be able to experiment with it -you need to: +you need to download and install the usual (CPython) version of: - * Download and install Pygame_. - - * Download and install `Dot Graphviz`_ + * Pygame_ + * `Dot Graphviz`_ To start the interactive translator shell do:: @@ -108,8 +107,7 @@ There is a small-to-medium demo showing the translator and the annotator:: - cd demo - ../rpython/translator/goal/translate.py --view --annotate bpnn.py + python bin/rpython --view --annotate translator/goal/bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -120,7 +118,7 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../rpython/translator/goal/translate.py bpnn.py + python bin/rpython translator/goal/bpnn.py Translating Full Programs @@ -130,8 +128,7 @@ ``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd rpython/translator/goal - python translate.py targetrpystonedalone + python bin/rpython translator/goal/targetrpystonedalone This will produce the executable "targetrpystonedalone-c". @@ -139,6 +136,17 @@ interpreter`_. There is also an FAQ about how to set up this process for `your own interpreters`_. +There are several environment variables you can find useful while playing with the RPython: + +``PYPY_USESSION_DIR`` + RPython uses temporary session directories to store files that are generated during the + translation process(e.g., translated C files). ``PYPY_USESSION_DIR`` serves as a base directory for these session + dirs. The default value for this variable is the system's temporary dir. + +``PYPY_USESSION_KEEP`` + By default RPython keeps only the last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. + Increase this value if you want to preserve C files longer (useful when producing lots of lldebug builds). + .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters .. _`start reading sources`: diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -13,7 +13,7 @@ implemented. It's helpful to have an understanding of how the `RPython translation toolchain`_ works before digging into the sources. -Almost all JIT specific code is found in pypy/jit subdirectories. Translation +Almost all JIT specific code is found in rpython/jit subdirectories. Translation time code is in the codewriter directory. The metainterp directory holds platform independent code including the the tracer and the optimizer. Code in the backend directory is responsible for generating machine code. @@ -175,7 +175,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf +.. __: https://bitbucket.org/pypy/extradoc/src/tip/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py --- a/pypy/doc/test/test_whatsnew.py +++ b/pypy/doc/test/test_whatsnew.py @@ -1,6 +1,6 @@ import py import pypy -from commands import getoutput +from commands import getoutput, getstatusoutput ROOT = py.path.local(pypy.__file__).dirpath().dirpath() @@ -20,6 +20,9 @@ return startrev, branches def get_merged_branches(path, startrev, endrev): + if getstatusoutput('hg root')[0]: + py.test.skip('no Mercurial repo') + # X = take all the merges which are descendants of startrev and are on default # revset = all the parents of X which are not on default # ===> 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 @@ -11,6 +11,8 @@ .. branch: callback-jit Callbacks from C are now better JITted +.. branch: fix-jit-logs + .. branch: remove-globals-in-jit .. branch: length-hint @@ -18,13 +20,22 @@ .. branch: numpypy-longdouble Long double support for numpypy + .. branch: numpypy-disable-longdouble Since r_longdouble support is missing, disable all longdouble and derivative dtypes using ENABLED_LONG_DOUBLE = False + .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality +.. branch: indexing-by-array +Adds indexing by scalar, adds int conversion from scalar and single element array, +fixes compress, indexing by an array with a smaller shape and the indexed object. + +.. branch: str-dtype-improvement +Allow concatenation of str and numeric arrays + .. branch: signatures Improved RPython typing @@ -42,6 +53,8 @@ .. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal +.. branch: pickle-dumps +.. branch: scalar_get_set .. branch: release-2.0-beta1 @@ -85,3 +98,15 @@ .. branch: vendor-rename Remove minor verison number from lib-python dirs to simplify stdlib upgrades. + +.. branch: jitframe-on-heap +Moves optimized JIT frames from stack to heap. As a side effect it enables +stackless to work well with the JIT on PyPy. Also removes a bunch of code from +the GC which fixes cannot find gc roots. + +.. branch: pycon2013-doc-fixes +Documentation fixes after going through the docs at PyCon 2013 sprint. + +.. branch: extregistry-refactor + +.. branch: remove-list-smm diff --git a/pypy/goal/getnightly.py b/pypy/goal/getnightly.py new file mode 100755 --- /dev/null +++ b/pypy/goal/getnightly.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import sys +import os +import py + +if sys.platform.startswith('linux'): + arch = 'linux' +else: + print 'Cannot determine the platform, please update this scrip' + sys.exit(1) + +if sys.maxint == 2**63 - 1: + arch += '64' + +filename = 'pypy-c-jit-latest-%s.tar.bz2' % arch +url = 'http://buildbot.pypy.org/nightly/trunk/%s' % filename +tmp = py.path.local.mkdtemp() +mydir = tmp.chdir() +print 'Downloading pypy to', tmp +if os.system('wget "%s"' % url) != 0: + sys.exit(1) + +print 'Extracting pypy binary' +mydir.chdir() +os.system("tar -x -v --wildcards --strip-components=2 -f %s '*/bin/pypy'" % tmp.join(filename)) + diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.tool.ann_override import PyPyAnnotatorPolicy -from rpython.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE +from rpython.config.config import to_optparse, make_dict, SUPPRESS_USAGE from rpython.config.config import ConflictConfigError from pypy.tool.option import make_objspace from pypy.conftest import pypydir diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -629,7 +629,6 @@ # start a prompt if requested if inspect_requested(): - inteactive = False try: from _pypy_interact import interactive_console success = run_toplevel(interactive_console, mainmodule) diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -538,7 +538,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -555,7 +555,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -621,7 +621,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,27 +1,30 @@ import sys +from rpython.rlib.cache import Cache +from rpython.tool.uid import HUGEVAL_BYTES +from rpython.rlib import jit, types +from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, + compute_unique_id) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import r_uint + from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, UserDelAction, FrameTraceAction) from pypy.interpreter.error import (OperationError, operationerrfmt, new_exception_class, typed_unwrap_error_msg) from pypy.interpreter.argument import Arguments from pypy.interpreter.miscutils import ThreadLocals -from rpython.rlib.cache import Cache -from rpython.tool.uid import HUGEVAL_BYTES -from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.objectmodel import we_are_translated, newlist_hint,\ - compute_unique_id -from rpython.rlib.rarithmetic import r_uint -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) -unpackiterable_driver = jit.JitDriver(name = 'unpackiterable', - greens = ['tp'], - reds = ['items', 'w_iterator']) +unpackiterable_driver = jit.JitDriver(name='unpackiterable', + greens=['tp'], + reds=['items', 'w_iterator']) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -216,16 +219,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True - def __spacebind__(self, space): return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -336,10 +333,8 @@ if e.match(self, self.w_KeyError): continue raise - modname = self.str_w(w_modname) - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -348,9 +343,8 @@ self.call_function(w_exitfunc) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -422,14 +416,12 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): """NOT_RPYTHON""" - from pypy.tool.lib_pypy import LIB_PYPY try: return self._builtinmodule_list except AttributeError: @@ -698,6 +690,7 @@ raise return None + @signature(types.any(), types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True @@ -721,52 +714,28 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): - """ - This method should NOT be called unless you are really sure about - it. It is used inside the implementation of end_finally() in - pyopcode.py, and it's there so that it can be overridden by the - FlowObjSpace. - """ - if self.is_w(w_obj, self.w_None): - return True - obj = self.interpclass_w(w_obj) - return isinstance(obj, RequiredClass) - def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable into a real (interpreter-level) list. @@ -1042,8 +1011,7 @@ def is_oldstyle_instance(self, w_obj): # xxx hack hack hack from pypy.module.__builtin__.interp_classobj import W_InstanceObject - obj = self.interpclass_w(w_obj) - return obj is not None and isinstance(obj, W_InstanceObject) + return isinstance(w_obj, W_InstanceObject) def callable(self, w_obj): if self.lookup(w_obj, "__call__") is not None: @@ -1680,7 +1648,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1697,7 +1664,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp @@ -145,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -209,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/callbench/bltn04.py b/pypy/interpreter/callbench/bltn04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn04.py +++ /dev/null @@ -1,40 +0,0 @@ -from sup import run - -def w(N, start): - c = chr - - start() - i = 0 - while i < N: - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltn_instantiate.py b/pypy/interpreter/callbench/bltn_instantiate.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn_instantiate.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - o = object - start() - i = 0 - while i < N: - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna1.py b/pypy/interpreter/callbench/bltna1.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna1.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - while i < N: - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna2.py b/pypy/interpreter/callbench/bltna2.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna2.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - z = l.__init__ - while i < N: - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bm14.py b/pypy/interpreter/callbench/bm14.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bm14.py +++ /dev/null @@ -1,51 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f0(self): - pass - def f1(self, a): - pass - def f2(self, a, b): - pass - def f3(self, a, b, c): - pass - def f4(self, a, b, c, d): - pass - - a = A() - f0 = a.f0 - f1 = a.f1 - f2 = a.f2 - f3 = a.f3 - f4 = a.f4 - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f1(1) - f2(1, 2) - f2(1, 2) - f2(1, 2) - f3(1, 2, 3) - f3(1, 2, 3) - f4(1, 2, 3, 4) - - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f2(1, 2) - - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmabvararg.py b/pypy/interpreter/callbench/bmabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmabvararg.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f(self, a, b, *args): - pass - - a = A() - f = a.f - z = (3, 4, 5) - - start() - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmfilter.py b/pypy/interpreter/callbench/bmfilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmfilter.py +++ /dev/null @@ -1,20 +0,0 @@ -from sup import run - -def w(N, start): - x = range(50) - class A(object): - def f1(self, a): - return False - - x = range(50) - a = A() - f1 = a.f1 - flt = filter - - start() - i = 0 - while i < N: - flt(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/bmmore.py b/pypy/interpreter/callbench/bmmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmmore.py +++ /dev/null @@ -1,30 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f4(self, a, b, c, d): - pass - def f5(self, a, b, c, d, e): - pass - a = A() - f4 = a.f4 - f5 = a.f5 - - start() - i = 0 - while i < N: - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) From noreply at buildbot.pypy.org Mon Mar 25 19:31:44 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 25 Mar 2013 19:31:44 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: (coding) fixes needed after having merged default Message-ID: <20130325183144.C64101C2F7B@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62750:b253b799130e Date: 2013-03-25 11:30 -0700 http://bitbucket.org/pypy/pypy/changeset/b253b799130e/ Log: (coding) fixes needed after having merged default diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -1150,10 +1150,10 @@ memory_regulator.register(cppinstance) return w_cppinstance - at unwrap_spec(cppinstance=W_CPPInstance) -def addressof(space, cppinstance): + at unwrap_spec(w_cppinstance=W_CPPInstance) +def addressof(space, w_cppinstance): """Takes a bound C++ instance, returns the raw address.""" - address = rffi.cast(rffi.LONG, cppinstance.get_rawobject()) + address = rffi.cast(rffi.LONG, w_cppinstance.get_rawobject()) return space.wrap(address) @unwrap_spec(address=int, owns=bool) diff --git a/pypy/module/cppyy/test/advancedcpp.h b/pypy/module/cppyy/test/advancedcpp.h --- a/pypy/module/cppyy/test/advancedcpp.h +++ b/pypy/module/cppyy/test/advancedcpp.h @@ -243,7 +243,9 @@ int m_i; }; +#ifndef __CINT__ template class std::vector; +#endif //=========================================================================== diff --git a/pypy/module/cppyy/test/advancedcpp_LinkDef.h b/pypy/module/cppyy/test/advancedcpp_LinkDef.h --- a/pypy/module/cppyy/test/advancedcpp_LinkDef.h +++ b/pypy/module/cppyy/test/advancedcpp_LinkDef.h @@ -58,6 +58,8 @@ #pragma link C++ class some_class_with_data; #pragma link C++ class some_class_with_data::some_data; +#pragma link C++ class ref_tester; +#pragma link C++ class std::vector; #pragma link C++ class pointer_pass; #pragma link C++ class multi1; diff --git a/pypy/module/cppyy/test/test_crossing.py b/pypy/module/cppyy/test/test_crossing.py --- a/pypy/module/cppyy/test/test_crossing.py +++ b/pypy/module/cppyy/test/test_crossing.py @@ -80,7 +80,7 @@ AppTestCpythonExtensionBase.setup_method.im_func(self, func) @unwrap_spec(name=str, init=str, body=str) - def load_cdll(space, name, init, body, w_symbols): + def create_cdll(space, name, init, body, w_symbols): # the following is loosely from test_cpyext.py import_module; it # is copied here to be able to tweak the call to # compile_extension_module and to get a different return result @@ -98,13 +98,12 @@ mod = compile_extension_module(space, name, symbols, **kwds) # explicitly load the module as a CDLL rather than as a module - import ctypes from pypy.module.imp.importing import get_so_extension fullmodname = os.path.join( os.path.dirname(mod), name + get_so_extension(space)) - return ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) + return space.wrap(fullmodname) - self.w_load_cdll = self.space.wrap(interp2app(load_cdll)) + self.w_create_cdll = self.space.wrap(interp2app(create_cdll)) def test00_base_class(self): """Test from cpyext; only here to see whether the imported class works""" @@ -144,11 +143,10 @@ }; """ # explicitly load the module as a CDLL rather than as a module -# dirname = space.wrap(os.path.dirname(mod)) - -# dirname = self.import_module(name='bar', init=init, body=body, load_it=False) -# fullmodname = os.path.join(dirname, name + self.soext) - self.cmodule = self.load_cdll(name, init, body, ['bar_unwrap', 'bar_wrap'])#ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL) + import ctypes + self.cmodule = ctypes.CDLL( + self.create_cdll(name, init, body, ['bar_unwrap', 'bar_wrap']), + ctypes.RTLD_GLOBAL) def test02_crossing_dict(self): """Test availability of all needed classes in the dict""" From noreply at buildbot.pypy.org Mon Mar 25 19:33:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 19:33:17 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Next test. Message-ID: <20130325183317.A0E961C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62751:5082b68711e3 Date: 2013-03-25 19:33 +0100 http://bitbucket.org/pypy/pypy/changeset/5082b68711e3/ Log: Next test. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -573,10 +573,13 @@ def collect(self, gen=1): - """Do a minor (gen=0) or major (gen>0) collection.""" - self.minor_collection() - if gen > 0: - self.major_collection() + """Do a minor (gen=0) or major (gen>0) collection, + or merely executes pending finalizers (gen<0). + """ + if gen >= 0: + self.minor_collection() + if gen > 0: + self.major_collection() self.execute_finalizers() def collect_and_reserve(self, totalsize): diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -245,7 +245,9 @@ try: self.llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], recursive=True) - except llinterp.LLException: + except llinterp.LLException, e: + if ''.join(e.args[0].name) == 'FinalizeLater\x00': + return False raise RuntimeError( "a finalizer raised an exception, shouldn't happen") return True diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -262,6 +262,7 @@ b.nextid += 1 def finalizer(self): b.num_finalized += 1 + debug_print("call to finalizer() number", b.num_finalized) if (b.num_finalized % 3) == 0: raise rgc.FinalizeLater def f(x): @@ -271,6 +272,8 @@ while i < x: i += 1 a = A() + rgc.register_finalizer(a.finalizer) + a = None llop.gc__collect(lltype.Void) if b.num_finalized == 0: llop.gc__collect(lltype.Void) @@ -282,7 +285,6 @@ rgc.progress_through_finalizer_queue() assert b.num_finalized == 8 res = self.interpret(f, [5]) - assert res == 606 def test_custom_trace(self): from rpython.rtyper.annlowlevel import llhelper diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -377,6 +377,18 @@ return hop.genop('gc_register_finalizer', [v_self, v_llfn], resulttype=lltype.Void) +class ProgressThroughFinalizerQueueEntry(ExtRegistryEntry): + _about_ = progress_through_finalizer_queue + + def compute_result_annotation(self): + from rpython.annotator import model as annmodel + return annmodel.s_None + + def specialize_call(self, hop): + hop.exception_cannot_occur() + args_v = [hop.inputconst(lltype.Signed, -1)] + return hop.genop('gc__collect', args_v, resulttype=hop.r_result) + # ____________________________________________________________ From noreply at buildbot.pypy.org Mon Mar 25 19:55:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 19:55:20 +0100 (CET) Subject: [pypy-commit] pypy gc-del: In-progress: start on framework.py. Message-ID: <20130325185520.21AE91C3098@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62752:df1b2661e5c8 Date: 2013-03-25 19:55 +0100 http://bitbucket.org/pypy/pypy/changeset/df1b2661e5c8/ Log: In-progress: start on framework.py. diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -241,7 +241,6 @@ [s_gc, s_typeid16, annmodel.SomeInteger(nonneg=True), annmodel.SomeBool(), - annmodel.SomeBool(), annmodel.SomeBool()], s_gcref, inline = False) if hasattr(GCClass, 'malloc_fixedsize'): @@ -251,7 +250,6 @@ [s_gc, s_typeid16, annmodel.SomeInteger(nonneg=True), annmodel.SomeBool(), - annmodel.SomeBool(), annmodel.SomeBool()], s_gcref, inline = False) else: @@ -322,7 +320,7 @@ malloc_fast, [s_gc, s_typeid16, annmodel.SomeInteger(nonneg=True), - s_False, s_False, s_False], s_gcref, + s_False, s_False], s_gcref, inline = True) else: self.malloc_fast_ptr = None @@ -892,7 +890,7 @@ c_false = rmodel.inputconst(lltype.Bool, False) c_has_weakptr = rmodel.inputconst(lltype.Bool, True) args = [self.c_const_gc, c_type_id, c_size, - c_false, c_false, c_has_weakptr] + c_false, c_has_weakptr] # push and pop the current live variables *including* the argument # to the weakref_create operation, which must be kept alive and diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -1,13 +1,14 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, llgroup from rpython.rtyper.lltypesystem import rclass from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rlib.debug import ll_assert +from rpython.rlib.debug import ll_assert, debug_print from rpython.rlib.rarithmetic import intmask from rpython.rlib import rgc from rpython.rlib.objectmodel import we_are_translated from rpython.tool.identity_dict import identity_dict + class GCData(object): """The GC information tables, and the query functions that the GC calls to decode their content. The encoding of this information @@ -28,6 +29,7 @@ llmemory.Address], llmemory.Address) DESTRUCTOR_OR_CT = lltype.Ptr(DESTRUCTOR_OR_CT_FUNC) + FINALIZER = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void)) # structure describing the layout of a typeid TYPE_INFO = lltype.Struct("type_info", @@ -138,15 +140,14 @@ return infobits & T_ANY_SLOW_FLAG == 0 def q_call_finalizer(self, finalizer, obj): - XXX - FINALIZER = lltype.Ptr(lltype.FuncType([llmemory.Address], - lltype.Void)) - finalizer = llmemory.cast_adr_to_ptr(finalizer, FINALIZER) - finalizer(obj) -## except rgc.FinalizeLater: -## xxx -## except Exception, e: -## XXX + finalizer = llmemory.cast_adr_to_ptr(finalizer, self.FINALIZER) + try: + finalizer(obj) + except rgc.FinalizeLater: + return False + except Exception: + debug_print("exception from finalizer", finalizer, "of", obj) + llop.debug_fatalerror(lltype.Void, "exception from finalizer!") return True diff --git a/rpython/memory/test/test_transformed_gc.py b/rpython/memory/test/test_transformed_gc.py --- a/rpython/memory/test/test_transformed_gc.py +++ b/rpython/memory/test/test_transformed_gc.py @@ -287,7 +287,7 @@ res = run([]) assert res == 42 - def define_finalizer(cls): + def define_destructor(cls): class B(object): pass b = B() @@ -312,42 +312,10 @@ def test_finalizer(self): run = self.runner("finalizer") - res = run([5, 42]) #XXX pure lazyness here too + res = run([5, 42]) assert res == 6 - def define_finalizer_calls_malloc(cls): - class B(object): - pass - b = B() - b.nextid = 0 - b.num_deleted = 0 - class AAA(object): - def __init__(self): - self.id = b.nextid - b.nextid += 1 - def __del__(self): - b.num_deleted += 1 - C() - class C(AAA): - def __del__(self): - b.num_deleted += 1 - def f(x, y): - a = AAA() - i = 0 - while i < x: - i += 1 - a = AAA() - llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) - return b.num_deleted - return f - - def test_finalizer_calls_malloc(self): - run = self.runner("finalizer_calls_malloc") - res = run([5, 42]) #XXX pure lazyness here too - assert res == 12 - - def define_finalizer_resurrects(cls): + def define_finalizer(cls): class B(object): pass b = B() @@ -357,9 +325,9 @@ def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): + rgc.register_finalizer(self.finalizer) + def finalizer(self): b.num_deleted += 1 - b.a = self def f(x, y): a = A() i = 0 @@ -368,18 +336,13 @@ a = A() llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) - aid = b.a.id - b.a = None - # check that __del__ is not called again - llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) - return b.num_deleted * 10 + aid + 100 * (b.a is None) + return b.num_deleted return f - def test_finalizer_resurrects(self): - run = self.runner("finalizer_resurrects") - res = run([5, 42]) #XXX pure lazyness here too - assert 160 <= res <= 165 + def test_finalizer(self): + run = self.runner("finalizer") + res = run([5, 42]) + assert res == 6 def define_custom_trace(cls): from rpython.rtyper.annlowlevel import llhelper @@ -475,13 +438,16 @@ def __init__(self): self.id = b.nextid b.nextid += 1 - def __del__(self): + rgc.register_finalizer(self.finalizer) + def finalizer(self): + self.finalizer1() # possibly-overriden method + def finalizer1(self): llop.gc__collect(lltype.Void) b.num_deleted += 1 C() C() class C(A): - def __del__(self): + def finalizer1(self): b.num_deleted += 1 b.num_deleted_c += 1 def f(x, y): @@ -504,7 +470,7 @@ def test_collect_during_collect(self): run = self.runner("collect_during_collect") # runs collect recursively 4 times - res = run([4, 42]) #XXX pure lazyness here too + res = run([4, 42]) assert res == 12 def define_collect_0(cls): @@ -782,8 +748,7 @@ if op.opname == 'do_malloc_fixedsize_clear': op.args = [Constant(type_id, llgroup.HALFWORD), Constant(llmemory.sizeof(P), lltype.Signed), - Constant(False, lltype.Bool), # has_finalizer - Constant(False, lltype.Bool), # is_finalizer_light + Constant(False, lltype.Bool), # has_destructor Constant(False, lltype.Bool)] # contains_weakptr break else: @@ -819,8 +784,7 @@ if op.opname == 'do_malloc_fixedsize_clear': op.args = [Constant(type_id, llgroup.HALFWORD), Constant(llmemory.sizeof(P), lltype.Signed), - Constant(False, lltype.Bool), # has_finalizer - Constant(False, lltype.Bool), # is_finalizer_light + Constant(False, lltype.Bool), # has_destructor Constant(False, lltype.Bool)] # contains_weakptr break else: From noreply at buildbot.pypy.org Mon Mar 25 20:45:27 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 25 Mar 2013 20:45:27 +0100 (CET) Subject: [pypy-commit] pypy default: remove the skipping unicodedb_6_0_0 tests, add a basic test that doesn't Message-ID: <20130325194527.A098A1C2F88@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r62753:3b8a305fa3ff Date: 2013-03-25 12:42 -0700 http://bitbucket.org/pypy/pypy/changeset/3b8a305fa3ff/ Log: remove the skipping unicodedb_6_0_0 tests, add a basic test that doesn't diff --git a/rpython/rlib/unicodedata/test/test_unicodedata.py b/rpython/rlib/unicodedata/test/test_unicodedata.py --- a/rpython/rlib/unicodedata/test/test_unicodedata.py +++ b/rpython/rlib/unicodedata/test/test_unicodedata.py @@ -102,29 +102,19 @@ class TestUnicodeData600(object): - def setup_class(cls): - # XXX: this can only be tested on Python3! - if unicodedata.unidata_version != '6.0.0': - py.test.skip('Needs python with unicode 6.0.0 database.') - seed = random.getrandbits(32) - print("random seed: ", seed) - random.seed(seed) - cls.charlist = charlist = [] - cls.nocharlist = nocharlist = [] - while len(charlist) < 1000 or len(nocharlist) < 1000: - chr = unichr(random.randrange(65536)) - try: - charlist.append((chr, unicodedata.name(chr))) - except ValueError: - nocharlist.append(chr) - - def test_random_charnames(self): - for chr, name in self.charlist: - assert unicodedb_6_0_0.name(ord(chr)) == name - assert unicodedb_6_0_0.lookup(name) == ord(chr) - - def test_random_missing_chars(self): - for chr in self.nocharlist: - py.test.raises(KeyError, unicodedb_6_0_0.name, ord(chr)) - + def test_some_additions(self): + additions = { + ord(u"\u20B9"): 'INDIAN RUPEE SIGN', + # u'\U0001F37A' + 127866: 'BEER MUG', + # u'\U0001F37B' + 127867: 'CLINKING BEER MUGS', + # u"\U0001F0AD" + 127149: 'PLAYING CARD QUEEN OF SPADES', + # u"\U0002B740" + 177984: "CJK UNIFIED IDEOGRAPH-2B740", + } + for un, name in additions.iteritems(): + assert unicodedb_6_0_0.name(un) == name + assert unicodedb_6_0_0.isprintable(un) From noreply at buildbot.pypy.org Mon Mar 25 21:10:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 21:10:04 +0100 (CET) Subject: [pypy-commit] pypy default: (weirdo) fix mingw_x64 Message-ID: <20130325201004.18F6C1C2F70@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62754:e63fd73a1951 Date: 2013-03-25 13:09 -0700 http://bitbucket.org/pypy/pypy/changeset/e63fd73a1951/ Log: (weirdo) fix mingw_x64 diff --git a/rpython/translator/c/src/thread_nt.c b/rpython/translator/c/src/thread_nt.c --- a/rpython/translator/c/src/thread_nt.c +++ b/rpython/translator/c/src/thread_nt.c @@ -29,7 +29,7 @@ * Return the thread Id instead of an handle. The Id is said to uniquely identify the thread in the system */ -int RPyThreadGetIdent() +long RPyThreadGetIdent() { return GetCurrentThreadId(); } From noreply at buildbot.pypy.org Mon Mar 25 21:56:55 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 21:56:55 +0100 (CET) Subject: [pypy-commit] pypy default: fix longs Message-ID: <20130325205655.3E79D1C2F70@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62755:a832d5973ed3 Date: 2013-03-25 13:56 -0700 http://bitbucket.org/pypy/pypy/changeset/a832d5973ed3/ Log: fix longs diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py --- a/pypy/objspace/std/longobject.py +++ b/pypy/objspace/std/longobject.py @@ -6,35 +6,16 @@ from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.noneobject import W_NoneObject -from rpython.rlib.rbigint import rbigint, SHIFT - -class W_AbstractLongObject(W_Object): - __slots__ = () - - def is_w(self, space, w_other): - if not isinstance(w_other, W_AbstractLongObject): - return False - if self.user_overridden_class or w_other.user_overridden_class: - return self is w_other - return space.bigint_w(self).eq(space.bigint_w(w_other)) - - def immutable_unique_id(self, space): - if self.user_overridden_class: - return None - from pypy.objspace.std.model import IDTAG_LONG as tag - b = space.bigint_w(self) - b = b.lshift(3).or_(rbigint.fromint(tag)) - return space.newlong_from_rbigint(b) - - def unwrap(w_self, space): #YYYYYY - return w_self.longval() +from rpython.rlib.rbigint import rbigint +from pypy.objspace.std.longtype import long_typedef, W_AbstractLongObject class W_LongObject(W_AbstractLongObject): """This is a wrapper of rbigint.""" - from pypy.objspace.std.longtype import long_typedef as typedef _immutable_fields_ = ['num'] + typedef = long_typedef + def __init__(w_self, l): w_self.num = l # instance of rbigint @@ -88,6 +69,9 @@ return self.num.tofloat() def int(self, space): + if (type(self) is not W_LongObject and + space.is_overloaded(self, space.w_long, '__int__')): + return W_Object.int(self, space) try: return space.newint(self.num.toint()) except OverflowError: diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -1,9 +1,11 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, SMM +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault,\ + interpindirect2app +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.strutil import string_to_bigint, ParseStringError +from rpython.rlib.rbigint import rbigint def descr_conjugate(space, w_int): return space.long(w_int) @@ -12,7 +14,6 @@ @unwrap_spec(w_x = WrappedDefault(0)) def descr__new__(space, w_longtype, w_x, w_base=None): from pypy.objspace.std.longobject import W_LongObject - from rpython.rlib.rbigint import rbigint if space.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject else: @@ -56,7 +57,7 @@ else: try: s = space.str_w(w_value) - except OperationError, e: + except OperationError: raise OperationError(space.w_TypeError, space.wrap("long() can't convert non-string " "with explicit base")) @@ -114,6 +115,30 @@ # ____________________________________________________________ +class W_AbstractLongObject(W_Object): + __slots__ = () + + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractLongObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + return space.bigint_w(self).eq(space.bigint_w(w_other)) + + def immutable_unique_id(self, space): + if self.user_overridden_class: + return None + from pypy.objspace.std.model import IDTAG_LONG as tag + b = space.bigint_w(self) + b = b.lshift(3).or_(rbigint.fromint(tag)) + return space.newlong_from_rbigint(b) + + def unwrap(w_self, space): #YYYYYY + return w_self.longval() + + def int(self, space): + raise NotImplementedError + long_typedef = StdTypeDef("long", __doc__ = '''long(x[, base]) -> integer @@ -129,5 +154,6 @@ real = typedef.GetSetProperty(descr_get_real), imag = typedef.GetSetProperty(descr_get_imag), bit_length = interp2app(bit_length), + __int__ = interpindirect2app(W_AbstractLongObject.int), ) long_typedef.registermethods(globals()) diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -231,13 +231,13 @@ def test_math_log(self): import math - raises(ValueError, math.log, 0L) - raises(ValueError, math.log, -1L) - raises(ValueError, math.log, -2L) + raises(ValueError, math.log, 0L) + raises(ValueError, math.log, -1L) + raises(ValueError, math.log, -2L) raises(ValueError, math.log, -(1L << 10000)) - #raises(ValueError, math.log, 0) - raises(ValueError, math.log, -1) - raises(ValueError, math.log, -2) + #raises(ValueError, math.log, 0) + raises(ValueError, math.log, -1) + raises(ValueError, math.log, -2) def test_long(self): import sys @@ -327,3 +327,11 @@ class A(long): pass b = A(5).real assert type(b) is long + + def test__int__(self): + class A(long): + def __int__(self): + return 42 + + assert int(long(3)) == long(3) + assert int(A(13)) == 42 From noreply at buildbot.pypy.org Mon Mar 25 22:01:09 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 22:01:09 +0100 (CET) Subject: [pypy-commit] pypy default: fix those tests Message-ID: <20130325210109.F31881C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62756:a87df44115c5 Date: 2013-03-25 14:00 -0700 http://bitbucket.org/pypy/pypy/changeset/a87df44115c5/ Log: fix those tests diff --git a/pypy/config/test/test_pypyoption.py b/pypy/config/test/test_pypyoption.py --- a/pypy/config/test/test_pypyoption.py +++ b/pypy/config/test/test_pypyoption.py @@ -11,11 +11,11 @@ assert conf.objspace.usemodules.gc - conf.objspace.std.withsmallint = True - assert not conf.objspace.std.withprebuiltint + conf.objspace.std.withmapdict = True + assert conf.objspace.std.withmethodcache conf = get_pypy_config() - conf.objspace.std.withprebuiltint = True - py.test.raises(ConfigError, "conf.objspace.std.withsmallint = True") + conf.objspace.std.withmethodcache = False + py.test.raises(ConfigError, "conf.objspace.std.withmapdict = True") def test_conflicting_gcrootfinder(): conf = get_pypy_config() diff --git a/pypy/doc/config/objspace.std.withsmallint.txt b/pypy/doc/config/objspace.std.withsmallint.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.std.withsmallint.txt +++ /dev/null @@ -1,6 +0,0 @@ -Use "tagged pointers" to represent small enough integer values: Integers that -fit into 31 bits (respective 63 bits on 64 bit machines) are not represented by -boxing them in an instance of ``W_IntObject``. Instead they are represented as a -pointer having the lowest bit set and the rest of the bits used to store the -value of the integer. This gives a small speedup for integer operations as well -as better memory behaviour. From noreply at buildbot.pypy.org Mon Mar 25 22:39:06 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Mar 2013 22:39:06 +0100 (CET) Subject: [pypy-commit] pypy default: fix translation (maybe) Message-ID: <20130325213906.F2FAF1C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62757:b1537cfcaaed Date: 2013-03-25 14:38 -0700 http://bitbucket.org/pypy/pypy/changeset/b1537cfcaaed/ Log: fix translation (maybe) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -22,7 +22,6 @@ assert not func.can_change_code return func.code - class Function(W_Root): """A function is a code object captured with some environment: an object space, a dictionary of globals, default arguments, diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -812,6 +812,8 @@ d = {} exec func_code.compile() in d f = d['f'] + f.__module__ = func.__module__ + # necessary for unique identifiers for pickling f.func_name = func.func_name if unwrap_spec is None: unwrap_spec = {} diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -1,7 +1,7 @@ import operator -from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.objspace.std import model, newformat +from pypy.objspace.std.floattype import float_typedef, W_AbstractFloatObject from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all @@ -19,36 +19,14 @@ import math from pypy.objspace.std.intobject import W_IntObject -class W_AbstractFloatObject(W_Object): - __slots__ = () - - def is_w(self, space, w_other): - from rpython.rlib.longlong2float import float2longlong - if not isinstance(w_other, W_AbstractFloatObject): - return False - if self.user_overridden_class or w_other.user_overridden_class: - return self is w_other - one = float2longlong(space.float_w(self)) - two = float2longlong(space.float_w(w_other)) - return one == two - - def immutable_unique_id(self, space): - if self.user_overridden_class: - return None - from rpython.rlib.longlong2float import float2longlong - from pypy.objspace.std.model import IDTAG_FLOAT as tag - val = float2longlong(space.float_w(self)) - b = rbigint.fromrarith_int(val) - b = b.lshift(3).or_(rbigint.fromint(tag)) - return space.newlong_from_rbigint(b) - class W_FloatObject(W_AbstractFloatObject): """This is a implementation of the app-level 'float' type. The constructor takes an RPython float as an argument.""" - from pypy.objspace.std.floattype import float_typedef as typedef _immutable_fields_ = ['floatval'] + typedef = float_typedef + def __init__(w_self, floatval): w_self.floatval = floatval @@ -59,6 +37,9 @@ return self.floatval def int(self, space): + if (type(self) is not W_FloatObject and + space.is_overloaded(self, space.w_float, '__int__')): + return W_Object.int(self, space) try: value = ovfcheck_float_to_int(self.floatval) except OverflowError: diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py --- a/pypy/objspace/std/floattype.py +++ b/pypy/objspace/std/floattype.py @@ -3,13 +3,15 @@ from rpython.rlib.unroll import unrolling_iterable from rpython.rlib import rfloat, rarithmetic from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault,\ + interpindirect2app from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.strutil import ParseStringError from pypy.objspace.std.strutil import string_to_float +from pypy.objspace.std.model import W_Object +from rpython.rlib.rbigint import rbigint float_as_integer_ratio = SMM("as_integer_ratio", 1) @@ -270,6 +272,32 @@ # ____________________________________________________________ +class W_AbstractFloatObject(W_Object): + __slots__ = () + + def is_w(self, space, w_other): + from rpython.rlib.longlong2float import float2longlong + if not isinstance(w_other, W_AbstractFloatObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + one = float2longlong(space.float_w(self)) + two = float2longlong(space.float_w(w_other)) + return one == two + + def immutable_unique_id(self, space): + if self.user_overridden_class: + return None + from rpython.rlib.longlong2float import float2longlong + from pypy.objspace.std.model import IDTAG_FLOAT as tag + val = float2longlong(space.float_w(self)) + b = rbigint.fromrarith_int(val) + b = b.lshift(3).or_(rbigint.fromint(tag)) + return space.newlong_from_rbigint(b) + + def int(self, space): + raise NotImplementedError + float_typedef = StdTypeDef("float", __doc__ = '''float(x) -> floating point number @@ -280,5 +308,6 @@ conjugate = interp2app(descr_conjugate), real = typedef.GetSetProperty(descr_get_real), imag = typedef.GetSetProperty(descr_get_imag), + __int__ = interpindirect2app(W_AbstractFloatObject.int), ) float_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Mon Mar 25 23:25:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 23:25:23 +0100 (CET) Subject: [pypy-commit] pypy gc-del: test_gc and test_transformed_gc pass now (with MiniMark only!) Message-ID: <20130325222523.54A401C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62758:ff9d7eba9314 Date: 2013-03-25 21:37 +0100 http://bitbucket.org/pypy/pypy/changeset/ff9d7eba9314/ Log: test_gc and test_transformed_gc pass now (with MiniMark only!) diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -331,13 +331,6 @@ def debug_check_object(self, obj): pass - def register_finalizer(self, gcobj, llfn): - llobj = llmemory.cast_ptr_to_adr(gcobj) - self._register_finalizer(llobj, llfn) - - def _register_finalizer(self, obj, llfn): - raise NotImplementedError # must be overridden - def execute_finalizers(self): if self.running_finalizers: return # the outer invocation of execute_finalizers() will do it diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -973,7 +973,7 @@ "the card marker bits are not cleared") i -= 1 - def _register_finalizer(self, obj, llfn): + def register_finalizer(self, obj, llfn): if self.header(obj).tid & ( GCFLAG_HAS_FINALIZER | # obj has already a finalizer GCFLAG_NO_HEAP_PTRS): # immortal object anyway, and we don't diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -431,6 +431,12 @@ annmodel.SomeInteger(nonneg=True)], annmodel.s_None) + self.register_finalizer_ptr = getfn(GCClass.register_finalizer.im_func, + [s_gc, + annmodel.SomeAddress(), + annmodel.SomeAddress()], + annmodel.s_None) + self.write_barrier_ptr = None self.write_barrier_from_array_ptr = None if GCClass.needs_write_barrier: @@ -1194,8 +1200,14 @@ def pop_roots(self, hop, livevars): raise NotImplementedError - def gct_gc_register_finalizer(self, op): - xxx + def gct_gc_register_finalizer(self, hop): + v_obj, v_func = hop.spaceop.args + v_obj_addr = hop.genop("cast_ptr_to_adr", [v_obj], + resulttype = llmemory.Address) + hop.genop("direct_call", [self.register_finalizer_ptr, + self.c_const_gc, + v_obj_addr, v_func], + resultvar = hop.spaceop.result) class TransformerLayoutBuilder(gctypelayout.TypeLayoutBuilder): diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -1,10 +1,10 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, llgroup from rpython.rtyper.lltypesystem import rclass from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rlib.debug import ll_assert, debug_print +from rpython.rlib.debug import ll_assert, debug_print, llinterpcall from rpython.rlib.rarithmetic import intmask from rpython.rlib import rgc -from rpython.rlib.objectmodel import we_are_translated +from rpython.rlib.objectmodel import we_are_translated, running_on_llinterp from rpython.tool.identity_dict import identity_dict @@ -140,14 +140,36 @@ return infobits & T_ANY_SLOW_FLAG == 0 def q_call_finalizer(self, finalizer, obj): + if not we_are_translated(): + return GCData.p_call_finalizer(finalizer, obj) + if running_on_llinterp: + return llinterpcall(lltype.Bool, GCData.p_call_finalizer, + finalizer, obj) finalizer = llmemory.cast_adr_to_ptr(finalizer, self.FINALIZER) try: finalizer(obj) except rgc.FinalizeLater: return False except Exception: - debug_print("exception from finalizer", finalizer, "of", obj) - llop.debug_fatalerror(lltype.Void, "exception from finalizer!") + debug_print("WARNING: unhandled exception from finalizer", + finalizer, "of", obj) + return True + + @staticmethod + def p_call_finalizer(finalizer, obj): + "NOT_RPYTHON" + from rpython.rtyper.llinterp import LLInterpreter, LLException + FUNC = lltype.typeOf(finalizer.ptr).TO + obj = llmemory.cast_adr_to_ptr(obj, FUNC.ARGS[0]) + llinterp = LLInterpreter.current_interpreter + try: + llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], + recursive=True) + except LLException, e: + if ''.join(e.args[0].name) == 'FinalizeLater\x00': + return False + raise RuntimeError( + "a finalizer raised an exception, shouldn't happen") return True @@ -404,11 +426,8 @@ # must be overridden for proper custom tracer support return None - def initialize_gc_query_function(self, gc, call_finalizer=None): - gcdata = GCData(self.type_info_group) - if call_finalizer is not None: - gcdata.q_call_finalizer = call_finalizer # for tests - gcdata.set_query_functions(gc) + def initialize_gc_query_function(self, gc): + GCData(self.type_info_group).set_query_functions(gc) def consider_constant(self, TYPE, value, gc): if value is not lltype.top_container(value): diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -29,8 +29,7 @@ lltype2vtable, self.llinterp) self.get_type_id = layoutbuilder.get_type_id - layoutbuilder.initialize_gc_query_function( - self.gc, layoutbuilder._call_finalizer) + layoutbuilder.initialize_gc_query_function(self.gc) constants = collect_constants(flowgraphs) for obj in constants: @@ -169,7 +168,8 @@ return (hdr.tid & self.gc.gcflag_extra) != 0 def register_finalizer(self, llptr, llfn): - self.gc.register_finalizer(llptr, llfn) + llobj = llmemory.cast_ptr_to_adr(llptr) + self.gc.register_finalizer(llobj, llfn) # ____________________________________________________________ @@ -239,19 +239,6 @@ else: return None - def _call_finalizer(self, finalizer, obj): - FUNC = lltype.typeOf(finalizer.ptr).TO - obj = llmemory.cast_adr_to_ptr(obj, FUNC.ARGS[0]) - try: - self.llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], - recursive=True) - except llinterp.LLException, e: - if ''.join(e.args[0].name) == 'FinalizeLater\x00': - return False - raise RuntimeError( - "a finalizer raised an exception, shouldn't happen") - return True - def collect_constants(graphs): constants = {} diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -140,12 +140,13 @@ class B: count = 0 class A: - def __del__(self): + def finalizer(self): self.b.count += 1 def g(): b = B() a = A() a.b = b + rgc.register_finalizer(a.finalizer) i = 0 lst = [None] while i < MAX: diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -373,8 +373,6 @@ count = 0 a = A() class B(object): - def __init__(self, ref): - rgc.register_finalizer(self.finalizer) def finalizer(self): # when the finalizer is called, the weakref to myself is # still valid in RPython @@ -383,7 +381,8 @@ b = B() ref = weakref.ref(b) b.ref = ref - return b + rgc.register_finalizer(b.finalizer) + return ref def f(): ref = g() llop.gc__collect(lltype.Void) @@ -412,14 +411,12 @@ res = self.interpret(f, []) assert res - def test_cycle_with_weakref_and_del(self): + def test_cycle_with_weakref_and_finalizer(self): import weakref class A(object): count = 0 a = A() class B(object): - def __init__(self, ref): - rgc.register_finalizer(self.finalizer) def finalizer(self): # when the finalizer is called, the weakref to c should be dead if self.ref() is None: @@ -433,6 +430,7 @@ c.b = B() ref = weakref.ref(c) c.b.ref = ref + rgc.register_finalizer(c.b.finalizer) return ref def f(): ref = g() @@ -448,13 +446,12 @@ class A(object): pass class B(object): - def __init__(self, ref): - rgc.register_finalizer(self.finalizer) def finalizer(self): self.wref().x += 1 def g(a): b = B() b.wref = weakref.ref(a) + rgc.register_finalizer(b.finalizer) # the only way to reach this weakref is via B, which is an # object with finalizer (but the weakref itself points to # a, which does not go away but will move during the next From noreply at buildbot.pypy.org Mon Mar 25 23:25:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 23:25:24 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Fix test Message-ID: <20130325222524.9D0E11C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62759:1fef469bc625 Date: 2013-03-25 21:49 +0100 http://bitbucket.org/pypy/pypy/changeset/1fef469bc625/ Log: Fix test diff --git a/rpython/translator/backendopt/destructor.py b/rpython/translator/backendopt/destructor.py --- a/rpython/translator/backendopt/destructor.py +++ b/rpython/translator/backendopt/destructor.py @@ -3,7 +3,8 @@ from rpython.rtyper.lltypesystem import lltype class DestructorError(Exception): - """The __del__() method contains unsupported operations""" + """The __del__() method contains unsupported operations. + (You may have to use the newer rgc.register_finalizer())""" class DestructorAnalyzer(graphanalyze.BoolGraphAnalyzer): """ Analyzer that checks if a destructor is lightweight enough for diff --git a/rpython/translator/backendopt/test/test_finalizer.py b/rpython/translator/backendopt/test/test_destructor.py rename from rpython/translator/backendopt/test/test_finalizer.py rename to rpython/translator/backendopt/test/test_destructor.py --- a/rpython/translator/backendopt/test/test_finalizer.py +++ b/rpython/translator/backendopt/test/test_destructor.py @@ -1,7 +1,7 @@ import py -from rpython.translator.backendopt.finalizer import FinalizerAnalyzer,\ - FinalizerError +from rpython.translator.backendopt.destructor import DestructorAnalyzer,\ + DestructorError from rpython.translator.translator import TranslationContext, graphof from rpython.translator.backendopt.all import backend_optimizations from rpython.translator.unsimplify import varoftype @@ -10,7 +10,7 @@ from rpython.rlib import rgc -class BaseFinalizerAnalyzerTests(object): +class BaseDestructorAnalyzerTests(object): """ Below are typical destructors that we encounter in pypy """ @@ -26,9 +26,9 @@ backend_optimizations(t) if option.view: t.view() - a = FinalizerAnalyzer(t) + a = DestructorAnalyzer(t) fgraph = graphof(t, func_to_analyze) - result = a.analyze_light_finalizer(fgraph) + result = a.analyze_direct_call(fgraph) return result def test_nothing(self): @@ -47,7 +47,7 @@ ('z', Z)) v1 = varoftype(lltype.Bool) v2 = varoftype(lltype.Signed) - f = FinalizerAnalyzer(None) + f = DestructorAnalyzer(None) r = f.analyze(SpaceOperation('cast_int_to_bool', [v2], v1)) assert not r @@ -63,7 +63,7 @@ v4], None)) -class TestLLType(BaseFinalizerAnalyzerTests): +class TestLLType(BaseDestructorAnalyzerTests): type_system = 'lltype' def test_malloc(self): @@ -126,17 +126,6 @@ r = self.analyze(f, [], A.__del__.im_func) assert r - def test_must_be_light_finalizer_decorator(self): - S = lltype.GcStruct('S') - @rgc.must_be_light_finalizer - def f(): - lltype.malloc(S) - @rgc.must_be_light_finalizer - def g(): - pass - self.analyze(g, []) # did not explode - py.test.raises(FinalizerError, self.analyze, f, []) - -class TestOOType(BaseFinalizerAnalyzerTests): +class TestOOType(BaseDestructorAnalyzerTests): type_system = 'ootype' From noreply at buildbot.pypy.org Mon Mar 25 23:25:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 23:25:25 +0100 (CET) Subject: [pypy-commit] pypy gc-del: An extra test. Message-ID: <20130325222525.D1B891C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62760:b56873d13d98 Date: 2013-03-25 21:55 +0100 http://bitbucket.org/pypy/pypy/changeset/b56873d13d98/ Log: An extra test. diff --git a/rpython/translator/backendopt/destructor.py b/rpython/translator/backendopt/destructor.py --- a/rpython/translator/backendopt/destructor.py +++ b/rpython/translator/backendopt/destructor.py @@ -19,9 +19,11 @@ 'raw_free'] def check_destructor(self, graph): + self.unsupported_op = None result = self.analyze_direct_call(graph) if result is self.top_result(): - raise DestructorError(DestructorError.__doc__, graph) + raise DestructorError(DestructorError.__doc__, graph, + self.unsupported_op) def analyze_simple_operation(self, op, graphinfo): if op.opname in self.ok_operations: @@ -39,4 +41,5 @@ if not isinstance(TP, lltype.Ptr) or TP.TO._gckind == 'raw': # primitive type return self.bottom_result() + self.unsupported_op = op return self.top_result() diff --git a/rpython/translator/backendopt/test/test_destructor.py b/rpython/translator/backendopt/test/test_destructor.py --- a/rpython/translator/backendopt/test/test_destructor.py +++ b/rpython/translator/backendopt/test/test_destructor.py @@ -108,6 +108,25 @@ r = self.analyze(g, [], f, backendopt=True) assert not r + def test_c_call_2(self): + X = lltype.Ptr(lltype.Struct('X')) + x = rffi.llexternal('x', [X], lltype.Signed, threadsafe=True) + class C(object): + lib = rffi.cast(X, -1) + + def g(): + c = C() + c.lib = rffi.cast(X, -2) + f(c) + + def f(c): + if c.lib != rffi.cast(X, -1): + x(c.lib) + c.lib = rffi.cast(X, -1) + + r = self.analyze(g, [], f, backendopt=True) + assert not r + def test_chain(self): class B(object): def __init__(self): From noreply at buildbot.pypy.org Mon Mar 25 23:25:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 23:25:27 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Support raw array manipulations too Message-ID: <20130325222527.0FA511C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62761:7ce93195ebd3 Date: 2013-03-25 22:00 +0100 http://bitbucket.org/pypy/pypy/changeset/7ce93195ebd3/ Log: Support raw array manipulations too diff --git a/rpython/translator/backendopt/destructor.py b/rpython/translator/backendopt/destructor.py --- a/rpython/translator/backendopt/destructor.py +++ b/rpython/translator/backendopt/destructor.py @@ -31,12 +31,13 @@ if (op.opname.startswith('int_') or op.opname.startswith('float_') or op.opname.startswith('cast_')): return self.bottom_result() - if op.opname == 'setfield' or op.opname == 'bare_setfield': - TP = op.args[2].concretetype + if (op.opname == 'setfield' or op.opname == 'bare_setfield' or + op.opname == 'setarrayitem' or op.opname == 'bare_setarrayitem'): + TP = op.args[-1].concretetype if not isinstance(TP, lltype.Ptr) or TP.TO._gckind == 'raw': # primitive type return self.bottom_result() - if op.opname == 'getfield': + if op.opname == 'getfield' or op.opname == 'getarrayitem': TP = op.result.concretetype if not isinstance(TP, lltype.Ptr) or TP.TO._gckind == 'raw': # primitive type diff --git a/rpython/translator/backendopt/test/test_destructor.py b/rpython/translator/backendopt/test/test_destructor.py --- a/rpython/translator/backendopt/test/test_destructor.py +++ b/rpython/translator/backendopt/test/test_destructor.py @@ -127,6 +127,15 @@ r = self.analyze(g, [], f, backendopt=True) assert not r + def test_setarrayitem(self): + x = lltype.malloc(lltype.Array(lltype.Signed), 5, flavor='raw', + immortal=True) + def f(): + x[1] += 1 + + r = self.analyze(f, [], f) + assert not r + def test_chain(self): class B(object): def __init__(self): From noreply at buildbot.pypy.org Mon Mar 25 23:25:28 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 23:25:28 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Hack until test_newgc compiles. Message-ID: <20130325222528.485881C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62762:559f98495630 Date: 2013-03-25 22:04 +0100 http://bitbucket.org/pypy/pypy/changeset/559f98495630/ Log: Hack until test_newgc compiles. diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py --- a/rpython/rlib/clibffi.py +++ b/rpython/rlib/clibffi.py @@ -646,8 +646,7 @@ def __del__(self): if self.ll_args: - argnum = len(self.argtypes) - for i in range(argnum): + for i in range(self.argnum): if self.ll_args[i]: lltype.free(self.ll_args[i], flavor='raw') lltype.free(self.ll_args, flavor='raw') diff --git a/rpython/translator/c/test/test_newgc.py b/rpython/translator/c/test/test_newgc.py --- a/rpython/translator/c/test/test_newgc.py +++ b/rpython/translator/c/test/test_newgc.py @@ -44,7 +44,8 @@ t = Translation(main, gc=cls.gcpolicy, taggedpointers=cls.taggedpointers, gcremovetypeptr=cls.removetypeptr) - t.disable(['backendopt']) + #t.disable(['backendopt']) -- XXX temporary maybe? needed for __del__ + # -- that calls external C functions t.set_backend_extra_options(c_debug_defines=True) t.rtype() if option.view: @@ -371,7 +372,7 @@ res = self.run('framework_opaque') assert res == -70 - def define_framework_finalizer(cls): + def define_framework_destructor(cls): class B(object): pass b = B() @@ -384,11 +385,41 @@ def __del__(self): b.num_deleted += 1 def f(): - a = A() + A() i = 0 while i < 5: i += 1 - a = A() + A() + llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) + return b.num_deleted + return f + + def test_framework_destructor(self): + res = self.run('framework_destructor') + assert res == 6 + + def define_framework_finalizer(cls): + class B(object): + pass + b = B() + b.nextid = 0 + b.num_deleted = 0 + class A(object): + def __init__(self): + self.id = b.nextid + b.nextid += 1 + rgc.register_finalizer(self.finalizer) + def finalizer(self): + b.num_deleted += 1 + if b.num_deleted == 3: + raise rgc.FinalizeLater + def f(): + A() + i = 0 + while i < 5: + i += 1 + A() llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) return b.num_deleted @@ -441,6 +472,21 @@ def test_del_raises(self): self.run('del_raises') # does not raise + def define_finalizer_raises(cls): + class B(object): + def finalizer(self): + raise TypeError + def func(): + b = B() + rgc.register_finalizer(b.finalizer) + b = None + rgc.collect() + return 0 + return func + + def test_finalizer_raises(self): + self.run('finalizer_raises') # does not raise + def define_custom_trace(cls): from rpython.rtyper.annlowlevel import llhelper # From noreply at buildbot.pypy.org Mon Mar 25 23:25:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Mar 2013 23:25:29 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Add a test that fails consistently, and fix. Message-ID: <20130325222529.78C121C2F7B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62763:e7ca33c2ef41 Date: 2013-03-25 23:25 +0100 http://bitbucket.org/pypy/pypy/changeset/e7ca33c2ef41/ Log: Add a test that fails consistently, and fix. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1492,6 +1492,7 @@ # We will fix such references to point to the copy of the young # objects when we walk 'old_objects_pointing_to_young'. self.old_objects_pointing_to_young.append(newobj) + #debug_print("adding", newobj) _trace_drag_out._always_inline_ = True def _visit_young_rawmalloced_object(self, obj): @@ -1922,11 +1923,11 @@ we also need to copy them out of the nursery. The tricky part here is to enqueue them in topological order, if possible. """ - pending = self.old_objects_pointing_to_young - ll_assert(not pending.non_empty(), + ll_assert(not self.old_objects_pointing_to_young.non_empty(), "deal_with_young_objects_with_finalizers: " "old_objects_pointing_to_young should be empty") finalizer_funcs = self.AddressDict() + self.finalizers_scheduled = self.AddressStack() # while self.young_objects_with_finalizers.non_empty(): func = self.young_objects_with_finalizers.pop() @@ -1940,19 +1941,44 @@ root.address[0] = obj self._trace_drag_out1(root) objcopy = root.address[0] + #debug_print("finalizer for", obj) + #debug_print("object moving to", objcopy) # # Remember the finalizer in the dict finalizer_funcs.setitem(objcopy, func) + # + # Now follow all the refs + self._follow_references_from_young_object_with_finalizer() # - # Now follow all the refs - finalizers_scheduled = self.AddressStack() + # Copy the objects scheduled into 'run_finalizers_queue', in + # reverse order. + while self.finalizers_scheduled.non_empty(): + obj = self.finalizers_scheduled.pop() + func = finalizer_funcs.get(obj) + ll_assert(func != NULL, "lost finalizer [1]") + self.run_finalizers_queue.append(obj) + self.run_finalizers_funcs.append(func) + finalizer_funcs.setitem(obj, NULL) + self.finalizers_scheduled.delete() + # + # The non-NULL entries remaining in 'finalizer_funcs' correspond + # to objects that survived, because they have not been traced by + # this function but already before. + finalizer_funcs.foreach(self._move_to_old_finalizer, + self.old_objects_with_finalizers) + finalizer_funcs.delete() + + def _follow_references_from_young_object_with_finalizer(self): + pending = self.old_objects_pointing_to_young while pending.non_empty(): assert not self.old_objects_with_cards_set.non_empty(), "XXX" obj = pending.pop() + #debug_print("popping", obj) if obj: # if self.header(obj).tid & GCFLAG_HAS_FINALIZER: self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER + #debug_print("this object has a finalizer") pending.append(obj) pending.append(NULL) # marker # @@ -1964,25 +1990,8 @@ else: # seen a NULL marker obj = pending.pop() - finalizers_scheduled.append(obj) - # - # Copy the objects scheduled into 'run_finalizers_queue', in - # reverse order. - while finalizers_scheduled.non_empty(): - obj = finalizers_scheduled.pop() - func = finalizer_funcs.get(obj) - ll_assert(func != NULL, "lost finalizer [1]") - self.run_finalizers_queue.append(obj) - self.run_finalizers_funcs.append(func) - finalizer_funcs.setitem(obj, NULL) - finalizers_scheduled.delete() - # - # The non-NULL entries remaining in 'finalizer_funcs' correspond - # to objects that survived, because they have not been traced by - # this function but already before. - finalizer_funcs.foreach(self._move_to_old_finalizer, - self.old_objects_with_finalizers) - finalizer_funcs.delete() + #debug_print("adding to scheduled", obj) + self.finalizers_scheduled.append(obj) @staticmethod def _move_to_old_finalizer(obj, finalizer, old_objects_with_finalizers): diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -2,6 +2,7 @@ from rpython.tool.udir import udir from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib.debug import debug_print from rpython.rlib import rgc @@ -10,6 +11,11 @@ def definestr_finalizer_order(cls): import random + x = random.randrange(0,10000) + print "R"*1000 + print x + print '-'*60 + random.seed(x) from rpython.tool.algo import graphlib cls.finalizer_order_examples = examples = [] @@ -72,8 +78,12 @@ def f(_): i = 0 while i < len(examples): + debug_print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") input, components, strict = examples[i] build_example(input) + if i & 1: + rgc.collect() + debug_print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") while state.time < 2 * len(letters): state.progress = False llop.gc__collect(lltype.Void) @@ -98,16 +108,17 @@ % (c, d)) # check that two instances in the same strong component # are never finalized during the same collection - for component in components: - seen = {} - for c in component: - age = state.age[c] - if age in seen: - d = seen[age] - return error(i, summary, - "%s and %s should not be finalized" - " at the same time" % (c, d)) - seen[age] = c + # <<< disabled now >>> + #for component in components: + # seen = {} + # for c in component: + # age = state.age[c] + # if age in seen: + # d = seen[age] + # return error(i, summary, + # "%s and %s should not be finalized" + # " at the same time" % (c, d)) + # seen[age] = c i += 1 return "ok" diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -1058,3 +1058,10 @@ class TestMiniMarkGCCardMarking(TestMiniMarkGC): GC_PARAMS = {'card_page_indices': 4} + +class TestMiniMarkGCLargeNursery(TestMiniMarkGC): + GC_PARAMS = {'nursery_size': 1024*WORD} + def setup_class(cls): + py.test.skip("takes a lot of extra time to run") + def teardown_class(cls): + pass From noreply at buildbot.pypy.org Mon Mar 25 23:35:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Mar 2013 23:35:19 +0100 (CET) Subject: [pypy-commit] pypy default: restore previous unroll heuristic cutoffs Message-ID: <20130325223519.E55B71C2F7B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62764:9fcfef88e333 Date: 2013-03-25 18:22 -0400 http://bitbucket.org/pypy/pypy/changeset/9fcfef88e333/ Log: restore previous unroll heuristic cutoffs diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -12,6 +12,8 @@ from rpython.rlib import rerased, jit +UNROLL_CUTOFF = 5 + def _is_str(space, w_key): return space.is_w(space.type(w_key), space.w_str) @@ -35,7 +37,7 @@ an actual dict """ return jit.isvirtual(w_dct) or (jit.isconstant(w_dct) and - w_dct.length() <= jit.UNROLL_CUTOFF) + w_dct.length() <= UNROLL_CUTOFF) class W_DictMultiObject(W_Object): 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 @@ -18,6 +18,7 @@ from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from sys import maxint +UNROLL_CUTOFF = 5 class W_AbstractListObject(W_Object): __slots__ = () @@ -42,7 +43,7 @@ return W_ListObject.from_storage_and_strategy(space, storage, strategy) @jit.look_inside_iff(lambda space, list_w, sizehint: - jit.loop_unrolling_heuristic(list_w, len(list_w))) + jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF)) def get_strategy_from_list_objects(space, list_w, sizehint): if not list_w: if sizehint != -1: @@ -956,7 +957,7 @@ raise NotImplementedError("abstract base class") @jit.look_inside_iff(lambda space, w_list, list_w: - jit.loop_unrolling_heuristic(list_w, len(list_w))) + jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF)) def init_from_list_w(self, w_list, list_w): l = [self.unwrap(w_item) for w_item in list_w] w_list.lstorage = self.erase(l) @@ -1005,7 +1006,7 @@ return self.wrap(r) @jit.look_inside_iff(lambda self, w_list: - jit.loop_unrolling_heuristic(w_list, w_list.length())) + jit.loop_unrolling_heuristic(w_list, w_list.length(), UNROLL_CUTOFF)) def getitems_copy(self, w_list): return [self.wrap(item) for item in self.unerase(w_list.lstorage)] @@ -1014,7 +1015,7 @@ return [self.wrap(item) for item in self.unerase(w_list.lstorage)] @jit.look_inside_iff(lambda self, w_list: - jit.loop_unrolling_heuristic(w_list, w_list.length())) + jit.loop_unrolling_heuristic(w_list, w_list.length(), UNROLL_CUTOFF)) def getitems_fixedsize(self, w_list): return self.getitems_unroll(w_list) @@ -1476,8 +1477,8 @@ return w_list def list_unroll_condition(space, w_list1, w_list2): - return jit.loop_unrolling_heuristic(w_list1, w_list1.length()) or \ - jit.loop_unrolling_heuristic(w_list2, w_list2.length()) + return jit.loop_unrolling_heuristic(w_list1, w_list1.length(), UNROLL_CUTOFF) or \ + jit.loop_unrolling_heuristic(w_list2, w_list2.length(), UNROLL_CUTOFF) @jit.look_inside_iff(list_unroll_condition) def eq__List_List(space, w_list1, w_list2): diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -15,6 +15,8 @@ from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib import rerased, jit +UNROLL_CUTOFF = 5 + class W_BaseSetObject(W_Object): typedef = None @@ -391,7 +393,7 @@ raise NotImplementedError @jit.look_inside_iff(lambda self, list_w: - jit.loop_unrolling_heuristic(list_w, len(list_w))) + jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF)) def get_storage_from_list(self, list_w): setdata = self.get_empty_dict() for w_item in list_w: @@ -399,7 +401,7 @@ return self.erase(setdata) @jit.look_inside_iff(lambda self, items: - jit.loop_unrolling_heuristic(items, len(items))) + jit.loop_unrolling_heuristic(items, len(items), UNROLL_CUTOFF)) def get_storage_from_unwrapped_list(self, items): setdata = self.get_empty_dict() for item in items: @@ -1033,7 +1035,7 @@ _pick_correct_strategy(space, w_set, iterable_w) @jit.look_inside_iff(lambda space, w_set, iterable_w: - jit.loop_unrolling_heuristic(iterable_w, len(iterable_w))) + jit.loop_unrolling_heuristic(iterable_w, len(iterable_w), UNROLL_CUTOFF)) def _pick_correct_strategy(space, w_set, iterable_w): # check for integers for w_item in iterable_w: diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -10,6 +10,7 @@ from rpython.rlib import jit from rpython.tool.sourcetools import func_with_new_name +UNROLL_CUTOFF = 10 class W_AbstractTupleObject(W_Object): __slots__ = () @@ -84,7 +85,7 @@ return space.newtuple(w_tuple.wrappeditems[start:stop]) @jit.look_inside_iff(lambda space, w_tuple, w_obj: - jit.loop_unrolling_heuristic(w_tuple, len(w_tuple.wrappeditems))) + jit.loop_unrolling_heuristic(w_tuple, len(w_tuple.wrappeditems), UNROLL_CUTOFF)) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): @@ -119,8 +120,8 @@ return mul_tuple_times(space, w_tuple, w_times) def tuple_unroll_condition(space, w_tuple1, w_tuple2): - return jit.loop_unrolling_heuristic(w_tuple1, len(w_tuple1.wrappeditems)) or \ - jit.loop_unrolling_heuristic(w_tuple2, len(w_tuple2.wrappeditems)) + return jit.loop_unrolling_heuristic(w_tuple1, len(w_tuple1.wrappeditems), UNROLL_CUTOFF) or \ + jit.loop_unrolling_heuristic(w_tuple2, len(w_tuple2.wrappeditems), UNROLL_CUTOFF) @jit.look_inside_iff(tuple_unroll_condition) def eq__Tuple_Tuple(space, w_tuple1, w_tuple2): @@ -173,7 +174,7 @@ return space.wrap(hash_tuple(space, w_tuple.wrappeditems)) @jit.look_inside_iff(lambda space, wrappeditems: - jit.loop_unrolling_heuristic(wrappeditems, len(wrappeditems))) + jit.loop_unrolling_heuristic(wrappeditems, len(wrappeditems), UNROLL_CUTOFF)) def hash_tuple(space, wrappeditems): # this is the CPython 2.4 algorithm (changed from 2.3) mult = 1000003 diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -206,13 +206,11 @@ return NonConstant(False) isvirtual._annspecialcase_ = "specialize:call_location" -UNROLL_CUTOFF = 5 - @specialize.call_location() -def loop_unrolling_heuristic(lst, size): +def loop_unrolling_heuristic(lst, size, cutoff=2): """ In which cases iterating over items of lst can be unrolled """ - return isvirtual(lst) or (isconstant(size) and size <= UNROLL_CUTOFF) + return isvirtual(lst) or (isconstant(size) and size <= cutoff) class Entry(ExtRegistryEntry): _about_ = hint From noreply at buildbot.pypy.org Mon Mar 25 23:44:25 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 25 Mar 2013 23:44:25 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: add test for operator int/long/float converter Message-ID: <20130325224425.4CBAE1C2F7A@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62765:9cbb25a33305 Date: 2013-03-25 11:56 -0700 http://bitbucket.org/pypy/pypy/changeset/9cbb25a33305/ Log: add test for operator int/long/float converter diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -591,6 +591,23 @@ assert len(a) == 1 assert a[0].m_i == 42 - # a[0] = gbl.ref_tester(33) - # assert len(a) == 1 - # assert a[0].m_i == 33 + # TODO: + # a[0] = gbl.ref_tester(33) + # assert len(a) == 1 + # assert a[0].m_i == 33 + + def test19_math_converters(self): + """Test operator int/long/double incl. typedef""" + + from cppyy import gbl + + a = gbl.some_convertible() + a.m_i = 1234 + a.m_d = 4321. + + assert int(a) == 1234 + assert int(a) == a.m_i + assert long(a) == a.m_i + + assert float(a) == 4321. + assert float(a) == a.m_d From noreply at buildbot.pypy.org Mon Mar 25 23:44:26 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 25 Mar 2013 23:44:26 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: add test for globally overloaded (in-)equality operators Message-ID: <20130325224426.8BF641C2F7A@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62766:66e9a50cc4a4 Date: 2013-03-25 13:12 -0700 http://bitbucket.org/pypy/pypy/changeset/66e9a50cc4a4/ Log: add test for globally overloaded (in-)equality operators diff --git a/pypy/module/cppyy/test/advancedcpp.xml b/pypy/module/cppyy/test/advancedcpp.xml --- a/pypy/module/cppyy/test/advancedcpp.xml +++ b/pypy/module/cppyy/test/advancedcpp.xml @@ -33,6 +33,11 @@ + + + + + diff --git a/pypy/module/cppyy/test/advancedcpp_LinkDef.h b/pypy/module/cppyy/test/advancedcpp_LinkDef.h --- a/pypy/module/cppyy/test/advancedcpp_LinkDef.h +++ b/pypy/module/cppyy/test/advancedcpp_LinkDef.h @@ -58,6 +58,10 @@ #pragma link C++ class some_class_with_data; #pragma link C++ class some_class_with_data::some_data; +#pragma link C++ class some_comparable; +#pragma link C++ function operator==(const some_comparable&, const some_comparable&); +#pragma link C++ function operator!=(const some_comparable&, const some_comparable&); + #pragma link C++ class ref_tester; #pragma link C++ class std::vector; #pragma link C++ class pointer_pass; diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -611,3 +611,21 @@ assert float(a) == 4321. assert float(a) == a.m_d + + def test20_comparator(self): + """Check that the global operator!=/== is picked up""" + + from cppyy import gbl + + a, b = gbl.some_comparable(), gbl.some_comparable() + + assert a == b + assert b == a + assert a.__eq__(b) + assert b.__eq__(a) + assert a.__ne__(a) + assert b.__ne__(b) + assert a.__eq__(b) == True + assert b.__eq__(a) == True + assert a.__eq__(a) == False + assert b.__eq__(b) == False From noreply at buildbot.pypy.org Mon Mar 25 23:44:29 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 25 Mar 2013 23:44:29 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: merge default into branch Message-ID: <20130325224429.DFC521C2F7A@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62767:1c230df535d9 Date: 2013-03-25 13:18 -0700 http://bitbucket.org/pypy/pypy/changeset/1c230df535d9/ Log: merge default into branch diff too long, truncating to 2000 out of 6369 lines diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1409,26 +1409,11 @@ except ImportError: from StringIO import StringIO -try: - from __pypy__.builders import StringBuilder -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO -else: - class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - self.getvalue = self.builder.build - def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -97,18 +97,12 @@ from pickle import StringIO -try: - from pickle import StringBuilderFile -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO - PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringBuilderFile() + self.__f = StringIO() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) @@ -126,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -189,11 +189,6 @@ BoolOption("withtproxy", "support transparent proxies", default=True), - BoolOption("withsmallint", "use tagged integers", - default=False, - requires=[("objspace.std.withprebuiltint", False), - ("translation.taggedpointers", True)]), - BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -204,9 +199,7 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False, - requires=[("objspace.std.withsmallint", False)]), - # ^^^ because of missing delegate_xx2yy + default=False), BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1144,7 +1144,7 @@ assert space.eq_w(get_num("-0"), space.wrap(0)) assert space.eq_w(get_num("-0xAAAAAAL"), space.wrap(-0xAAAAAAL)) n = get_num(str(-sys.maxint - 1)) - assert space.is_true(space.isinstance(n, space.w_int)) + assert space.isinstance_w(n, space.w_int) for num in ("0o53", "0O53", "0o0000053", "0O00053"): assert space.eq_w(get_num(num), space.wrap(053)) for num in ("0b00101", "0B00101", "0b101", "0B101"): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -211,6 +211,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def float_w(self, space): + raise OperationError(space.w_TypeError, + typed_unwrap_error_msg(space, "float", self)) + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -219,6 +223,22 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def int(self, space): + w_impl = space.lookup(self, '__int__') + if w_impl is None: + typename = space.type(self).getname(space) + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for int(): '%s'", + typename) + w_result = space.get_and_call_function(w_impl, self) + + if (space.isinstance_w(w_result, space.w_int) or + space.isinstance_w(w_result, space.w_long)): + return w_result + typename = space.type(w_result).getname(space) + msg = "__int__ returned non-int (type '%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) + def __spacebind__(self, space): return self @@ -257,18 +277,13 @@ def __init__(self, space): Cache.__init__(self) self.space = space + def _build(self, key): - val = self.space.enter_cache_building_mode() - try: - return self.build(key) - finally: - self.space.leave_cache_building_mode(val) + return self.build(key) + def _ready(self, result): - val = self.space.enter_cache_building_mode() - try: - return self.ready(result) - finally: - self.space.leave_cache_building_mode(val) + return self.ready(result) + def ready(self, result): pass @@ -557,11 +572,6 @@ """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" - def enter_cache_building_mode(self): - "hook for the flow object space" - def leave_cache_building_mode(self, val): - "hook for the flow object space" - @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." @@ -903,7 +913,7 @@ if self.is_w(w_exc_type, w_check_class): return True # fast path (also here to handle string exceptions) try: - if self.is_true(self.isinstance(w_check_class, self.w_tuple)): + if self.isinstance_w(w_check_class, self.w_tuple): for w_t in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_t): return True @@ -1031,9 +1041,6 @@ def issequence_w(self, w_obj): return (self.findattr(w_obj, self.wrap("__getitem__")) is not None) - def isinstance_w(self, w_obj, w_type): - return self.is_true(self.isinstance(w_obj, w_type)) - # The code below only works # for the simple case (new-style instance). # These methods are patched with the full logic by the __builtin__ @@ -1045,11 +1052,11 @@ def abstract_isinstance_w(self, w_obj, w_cls): # Equivalent to 'isinstance(obj, cls)'. - return self.is_true(self.isinstance(w_obj, w_cls)) + return self.isinstance_w(w_obj, w_cls) def abstract_isclass_w(self, w_obj): # Equivalent to 'isinstance(obj, type)'. - return self.is_true(self.isinstance(w_obj, self.w_type)) + return self.isinstance_w(w_obj, self.w_type) def abstract_getclass(self, w_obj): # Equivalent to 'obj.__class__'. @@ -1087,7 +1094,7 @@ expression = compiler.compile(expression, '?', 'eval', 0, hidden_applevel=hidden_applevel) else: - raise TypeError, 'space.eval(): expected a string, code or PyCode object' + raise TypeError('space.eval(): expected a string, code or PyCode object') return expression.exec_code(self, w_globals, w_locals) def exec_(self, statement, w_globals, w_locals, hidden_applevel=False, @@ -1101,7 +1108,7 @@ statement = compiler.compile(statement, filename, 'exec', 0, hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): - raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') if not self.is_true(self.contains(w_globals, w_key)): self.setitem(w_globals, w_key, self.wrap(self.builtin)) @@ -1157,7 +1164,7 @@ -> (index, 0, 0) or (start, stop, step) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) @@ -1177,7 +1184,7 @@ -> (index, 0, 0, 1) or (start, stop, step, slice_length) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step, length = w_index_or_slice.indices4(self, @@ -1305,15 +1312,21 @@ def int_w(self, w_obj): return w_obj.int_w(self) + def int(self, w_obj): + return w_obj.int(self) + def uint_w(self, w_obj): return w_obj.uint_w(self) def bigint_w(self, w_obj): return w_obj.bigint_w(self) + def float_w(self, w_obj): + return w_obj.float_w(self) + def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. - if not self.is_true(self.isinstance(w_obj, self.w_str)): + if not self.isinstance_w(w_obj, self.w_str): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) return self.str_w(w_obj) @@ -1333,7 +1346,7 @@ def realunicode_w(self, w_obj): # Like unicode_w, but only works if w_obj is really of type # 'unicode'. - if not self.is_true(self.isinstance(w_obj, self.w_unicode)): + if not self.isinstance_w(w_obj, self.w_unicode): raise OperationError(self.w_TypeError, self.wrap('argument must be a unicode')) return self.unicode_w(w_obj) @@ -1345,7 +1358,7 @@ # This is all interface for gateway.py. def gateway_int_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.int_w(self.int(w_obj)) @@ -1354,19 +1367,19 @@ return self.float_w(self.float(w_obj)) def gateway_r_longlong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_longlong_w(self.int(w_obj)) def gateway_r_uint_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.uint_w(self.int(w_obj)) def gateway_r_ulonglong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_ulonglong_w(self.int(w_obj)) @@ -1483,23 +1496,28 @@ space.exec_(str(source), w_glob, w_glob) return space.getitem(w_glob, space.wrap('anonymous')) + class DummyLock(object): def acquire(self, flag): return True + def release(self): pass + def _freeze_(self): return True + def __enter__(self): pass + def __exit__(self, *args): pass dummy_lock = DummyLock() -## Table describing the regular part of the interface of object spaces, -## namely all methods which only take w_ arguments and return a w_ result -## (if any). Note: keep in sync with rpython.flowspace.operation.Table. +# Table describing the regular part of the interface of object spaces, +# namely all methods which only take w_ arguments and return a w_ result +# (if any). ObjSpace.MethodTable = [ # method name # symbol # number of arguments # special method name(s) @@ -1526,7 +1544,7 @@ ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), - ('abs' , 'abs', 1, ['__abs__']), + ('abs', 'abs', 1, ['__abs__']), ('hex', 'hex', 1, ['__hex__']), ('oct', 'oct', 1, ['__oct__']), ('ord', 'ord', 1, []), @@ -1579,12 +1597,12 @@ ('delete', 'delete', 2, ['__delete__']), ('userdel', 'del', 1, ['__del__']), ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py - ] +] ObjSpace.BuiltinModuleTable = [ '__builtin__', 'sys', - ] +] ObjSpace.ConstantTable = [ 'None', @@ -1592,7 +1610,7 @@ 'True', 'Ellipsis', 'NotImplemented', - ] +] ObjSpace.ExceptionTable = [ 'ArithmeticError', @@ -1635,7 +1653,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', - ] +] if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] @@ -1673,4 +1691,4 @@ 'newslice', 'call_args', 'marshal_w', - ] +] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -183,7 +183,7 @@ # w_type = self.w_type w_value = self.get_w_value(space) - while space.is_true(space.isinstance(w_type, space.w_tuple)): + while space.isinstance_w(w_type, space.w_tuple): w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): @@ -198,7 +198,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.is_true(space.isinstance(w_value, space.w_tuple)): + if space.isinstance_w(w_value, space.w_tuple): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -208,7 +208,7 @@ def descr_function__new__(space, w_subtype, w_code, w_globals, w_name=None, w_argdefs=None, w_closure=None): code = space.interp_w(Code, w_code) - if not space.is_true(space.isinstance(w_globals, space.w_dict)): + if not space.isinstance_w(w_globals, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("expected dict")) if not space.is_none(w_name): name = space.str_w(w_name) @@ -356,7 +356,7 @@ if space.is_w(w_defaults, space.w_None): self.defs_w = [] return - if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): + if not space.isinstance_w(w_defaults, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -81,7 +81,7 @@ def descr__reduce__(self, space): w_name = space.finditem(self.w_dict, space.wrap('__name__')) if (w_name is None or - not space.is_true(space.isinstance(w_name, space.w_str))): + not space.isinstance_w(w_name, space.w_str)): # maybe raise exception here (XXX this path is untested) return space.w_None w_modules = space.sys.get('modules') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -232,7 +232,7 @@ def getdocstring(self, space): if self.co_consts_w: # it is probably never empty w_first = self.co_consts_w[0] - if space.is_true(space.isinstance(w_first, space.w_basestring)): + if space.isinstance_w(w_first, space.w_basestring): return w_first return space.w_None @@ -246,20 +246,20 @@ else: consts[num] = self.space.unwrap(w) num += 1 - return new.code( self.co_argcount, - self.co_nlocals, - self.co_stacksize, - self.co_flags, - self.co_code, - tuple(consts), - tuple(self.co_names), - tuple(self.co_varnames), - self.co_filename, - self.co_name, - self.co_firstlineno, - self.co_lnotab, - tuple(self.co_freevars), - tuple(self.co_cellvars) ) + return new.code(self.co_argcount, + self.co_nlocals, + self.co_stacksize, + self.co_flags, + self.co_code, + tuple(consts), + tuple(self.co_names), + tuple(self.co_varnames), + self.co_filename, + self.co_name, + self.co_firstlineno, + self.co_lnotab, + tuple(self.co_freevars), + tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): from pypy.interpreter.pyframe import CPythonFrame @@ -349,12 +349,12 @@ if nlocals < 0: raise OperationError(space.w_ValueError, space.wrap("code: nlocals must not be negative")) - if not space.is_true(space.isinstance(w_constants, space.w_tuple)): + if not space.isinstance_w(w_constants, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("Expected tuple for constants")) - consts_w = space.fixedview(w_constants) - names = unpack_str_tuple(space, w_names) - varnames = unpack_str_tuple(space, w_varnames) + consts_w = space.fixedview(w_constants) + names = unpack_str_tuple(space, w_names) + varnames = unpack_str_tuple(space, w_varnames) if w_freevars is not None: freevars = unpack_str_tuple(space, w_freevars) else: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -777,12 +777,12 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space - if space.is_true(space.isinstance(w_2, space.w_tuple)): + if space.isinstance_w(w_2, space.w_tuple): for w_t in space.fixedview(w_2): - if space.is_true(space.isinstance(w_t, space.w_str)): + if space.isinstance_w(w_t, space.w_str): msg = "catching of string exceptions is deprecated" space.warn(space.wrap(msg), space.w_DeprecationWarning) - elif space.is_true(space.isinstance(w_2, space.w_str)): + elif space.isinstance_w(w_2, space.w_str): msg = "catching of string exceptions is deprecated" space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.newbool(space.exception_match(w_1, w_2)) @@ -796,7 +796,7 @@ w_result = getattr(self, attr)(w_1, w_2) break else: - raise BytecodeCorruption, "bad COMPARE_OP oparg" + raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) def IMPORT_NAME(self, nameindex, next_instr): diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -61,7 +61,6 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - if w_tb is None or not space.is_true(space.isinstance(w_tb, - space.gettypeobject(PyTraceback.typedef))): + if w_tb is None or not space.isinstance_w(w_tb, space.gettypeobject(PyTraceback.typedef)): raise OperationError(space.w_TypeError, space.wrap(msg)) return w_tb 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 @@ -24,8 +24,12 @@ assert code.signature() == Signature(['x', 'y'], 'hello', None) def d(self, w_boo): pass + + class W_X(W_Root): + pass + code = gateway.BuiltinCode(d, unwrap_spec= ['self', - gateway.W_Root], self_type=gateway.W_Root) + gateway.W_Root], self_type=W_X) assert code.signature() == Signature(['self', 'boo'], None, None) def e(space, w_x, w_y, __args__): pass diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -342,7 +342,7 @@ # a couple of helpers for the Proto classes above, factored out to reduce # the translated code size def check_new_dictionary(space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("setting dictionary to a non-dict")) from pypy.objspace.std import dictmultiobject @@ -552,7 +552,7 @@ self.w_cls = w_cls def typecheck(self, space, w_obj): - if not space.is_true(space.isinstance(w_obj, self.w_cls)): + if not space.isinstance_w(w_obj, self.w_cls): raise operationerrfmt(space.w_TypeError, "descriptor '%s' for '%s'" " objects doesn't apply to '%s' object", diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -114,7 +114,7 @@ else: if w_builtin is space.builtin: # common case return space.builtin - if space.is_true(space.isinstance(w_builtin, space.w_dict)): + if space.isinstance_w(w_builtin, space.w_dict): return module.Module(space, None, w_builtin) if isinstance(w_builtin, module.Module): return w_builtin diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -8,10 +8,12 @@ """ from rpython.rlib import jit + +from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace from pypy.interpreter.error import OperationError from pypy.module.__builtin__.interp_classobj import W_ClassObject from pypy.module.__builtin__.interp_classobj import W_InstanceObject -from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace + def _get_bases(space, w_cls): """Returns 'cls.__bases__'. Returns None if there is @@ -23,7 +25,7 @@ if not e.match(space, space.w_AttributeError): raise # propagate other errors return None - if space.is_true(space.isinstance(w_bases, space.w_tuple)): + if space.isinstance_w(w_bases, space.w_tuple): return w_bases else: return None @@ -47,10 +49,9 @@ @jit.unroll_safe def abstract_isinstance_w(space, w_obj, w_klass_or_tuple, allow_override=False): """Implementation for the full 'isinstance(obj, klass_or_tuple)'.""" - # -- case (anything, tuple) # XXX it might be risky that the JIT sees this - if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)): + if space.isinstance_w(w_klass_or_tuple, space.w_tuple): for w_klass in space.fixedview(w_klass_or_tuple): if abstract_isinstance_w(space, w_obj, w_klass, allow_override): return True @@ -129,8 +130,7 @@ """Implementation for the full 'issubclass(derived, klass_or_tuple)'.""" # -- case (class-like-object, tuple-of-classes) - # XXX it might be risky that the JIT sees this - if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)): + if space.isinstance_w(w_klass_or_tuple, space.w_tuple): for w_klass in space.fixedview(w_klass_or_tuple): if abstract_issubclass_w(space, w_derived, w_klass, allow_override): return True diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -7,6 +7,7 @@ from pypy.interpreter.astcompiler import consts, ast from pypy.interpreter.gateway import unwrap_spec + @unwrap_spec(filename=str, mode=str, flags=int, dont_inherit=int) def compile(space, w_source, filename, mode, flags=0, dont_inherit=0): """Compile the source string (a Python module, statement or expression) @@ -25,10 +26,10 @@ ast_node = None w_ast_type = space.gettypeobject(ast.AST.typedef) str_ = None - if space.is_true(space.isinstance(w_source, w_ast_type)): + if space.isinstance_w(w_source, w_ast_type): ast_node = space.interp_w(ast.mod, w_source) ast_node.sync_app_attrs(space) - elif space.is_true(space.isinstance(w_source, space.w_unicode)): + elif space.isinstance_w(w_source, space.w_unicode): w_utf_8_source = space.call_method(w_source, "encode", space.wrap("utf-8")) str_ = space.str_w(w_utf_8_source) @@ -72,8 +73,8 @@ """ w = space.wrap - if (space.is_true(space.isinstance(w_code, space.w_str)) or - space.is_true(space.isinstance(w_code, space.w_unicode))): + if (space.isinstance_w(w_code, space.w_str) or + space.isinstance_w(w_code, space.w_unicode)): w_code = compile(space, space.call_method(w_code, 'lstrip', space.wrap(' \t')), diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -47,7 +47,8 @@ n = 0 return n - at unwrap_spec(w_step = WrappedDefault(1)) + + at unwrap_spec(w_step=WrappedDefault(1)) def range_int(space, w_x, w_y=None, w_step=None): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to @@ -60,24 +61,24 @@ w_start = w_x w_stop = w_y - if space.is_true(space.isinstance(w_stop, space.w_float)): + if space.isinstance_w(w_stop, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer end argument expected, got float.")) - if space.is_true(space.isinstance(w_start, space.w_float)): + if space.isinstance_w(w_start, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer start argument expected, got float.")) - if space.is_true(space.isinstance(w_step, space.w_float)): + if space.isinstance_w(w_step, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer step argument expected, got float.")) w_start = space.int(w_start) - w_stop = space.int(w_stop) - w_step = space.int(w_step) + w_stop = space.int(w_stop) + w_step = space.int(w_step) try: start = space.int_w(w_start) - stop = space.int_w(w_stop) - step = space.int_w(w_step) + stop = space.int_w(w_stop) + step = space.int_w(w_step) except OperationError, e: if not e.match(space, space.w_OverflowError): raise @@ -107,7 +108,7 @@ start = lo = space.bigint_w(w_start) hi = space.bigint_w(w_stop) - step = st = space.bigint_w(w_step) + step = st = space.bigint_w(w_step) if not step.tobool(): raise OperationError(space.w_ValueError, @@ -201,8 +202,8 @@ @specialize.arg(2) def min_max(space, args, implementation_of): - if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2): + if not jit.we_are_jitted() or len(args.arguments_w) != 1 and \ + jit.loop_unrolling_heuristic(args.arguments_w, len(args.arguments_w)): return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -25,10 +25,10 @@ # XXX it's not clear that we have to catch the TypeError... def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict): - if not space.is_true(space.isinstance(w_bases, space.w_tuple)): + if not space.isinstance_w(w_bases, space.w_tuple): raise_type_err(space, 'bases', 'tuple', w_bases) - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise_type_err(space, 'bases', 'tuple', w_bases) if not space.is_true(space.contains(w_dict, space.wrap("__doc__"))): @@ -68,27 +68,24 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError( space.w_TypeError, space.wrap("__dict__ must be a dictionary object")) self.w_dict = w_dict def setname(self, space, w_newname): - if not space.is_true(space.isinstance(w_newname, space.w_str)): - raise OperationError( - space.w_TypeError, - space.wrap("__name__ must be a string object")) + if not space.isinstance_w(w_newname, space.w_str): + raise OperationError(space.w_TypeError, + space.wrap("__name__ must be a string object") + ) self.name = space.str_w(w_newname) def setbases(self, space, w_bases): - # XXX in theory, this misses a check against inheritance cycles - # although on pypy we don't get a segfault for infinite - # recursion anyway - if not space.is_true(space.isinstance(w_bases, space.w_tuple)): - raise OperationError( - space.w_TypeError, - space.wrap("__bases__ must be a tuple object")) + if not space.isinstance_w(w_bases, space.w_tuple): + raise OperationError(space.w_TypeError, + space.wrap("__bases__ must be a tuple object") + ) bases_w = space.fixedview(w_bases) for w_base in bases_w: if not isinstance(w_base, W_ClassObject): @@ -194,7 +191,7 @@ if not e.match(space, space.w_AttributeError): raise return "?" - if space.is_true(space.isinstance(w_mod, space.w_str)): + if space.isinstance_w(w_mod, space.w_str): return space.str_w(w_mod) return "?" @@ -464,7 +461,7 @@ def descr_len(self, space): w_meth = self.getattr(space, '__len__') w_result = space.call_function(w_meth) - if space.is_true(space.isinstance(w_result, space.w_int)): + if space.isinstance_w(w_result, space.w_int): if space.is_true(space.lt(w_result, space.wrap(0))): raise OperationError( space.w_ValueError, @@ -532,7 +529,7 @@ if w_func is None: return space.w_True w_result = space.call_function(w_func) - if space.is_true(space.isinstance(w_result, space.w_int)): + if space.isinstance_w(w_result, space.w_int): if space.is_true(space.lt(w_result, space.wrap(0))): raise OperationError( space.w_ValueError, @@ -594,16 +591,16 @@ def descr_hash(self, space): w_func = self.getattr(space, '__hash__', False) if w_func is None: - w_eq = self.getattr(space, '__eq__', False) - w_cmp = self.getattr(space, '__cmp__', False) + w_eq = self.getattr(space, '__eq__', False) + w_cmp = self.getattr(space, '__cmp__', False) if w_eq is not None or w_cmp is not None: raise OperationError(space.w_TypeError, space.wrap("unhashable instance")) else: return space.wrap(compute_identity_hash(self)) w_ret = space.call_function(w_func) - if (not space.is_true(space.isinstance(w_ret, space.w_int)) and - not space.is_true(space.isinstance(w_ret, space.w_long))): + if (not space.isinstance_w(w_ret, space.w_int) and + not space.isinstance_w(w_ret, space.w_long)): raise OperationError( space.w_TypeError, space.wrap("__hash__ must return int or long")) @@ -654,7 +651,6 @@ if space.eq_w(w_x, w_obj): return space.w_True - def descr_pow(self, space, w_other, w_modulo=None): if space.is_none(w_modulo): w_a, w_b = _coerce_helper(space, self, w_other) diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -56,13 +56,13 @@ def nonzero(self): return self.space.wrap(bool(self._cdata)) - def int(self): - w_result = self.ctype.int(self._cdata) + def int(self, space): + w_result = self.ctype.cast_to_int(self._cdata) keepalive_until_here(self) return w_result - def long(self): - w_result = self.int() + def long(self, space): + w_result = self.int(space) space = self.space if space.is_w(space.type(w_result), space.w_int): w_result = space.newlong(space.int_w(w_result)) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -54,7 +54,7 @@ raise operationerrfmt(space.w_TypeError, "cannot cast to '%s'", self.name) - def int(self, cdata): + def cast_to_int(self, cdata): space = self.space raise operationerrfmt(space.w_TypeError, "int() not supported on cdata '%s'", self.name) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -99,7 +99,7 @@ _attrs_ = [] cast_anything = True - def int(self, cdata): + def cast_to_int(self, cdata): return self.space.wrap(ord(cdata[0])) def convert_to_object(self, cdata): @@ -124,7 +124,7 @@ class W_CTypePrimitiveUniChar(W_CTypePrimitiveCharOrUniChar): _attrs_ = [] - def int(self, cdata): + def cast_to_int(self, cdata): unichardata = rffi.cast(rffi.CWCHARP, cdata) return self.space.wrap(ord(unichardata[0])) @@ -168,7 +168,7 @@ self.vmin = r_uint(-1) << (sh - 1) self.vrangemax = (r_uint(1) << sh) - 1 - def int(self, cdata): + def cast_to_int(self, cdata): return self.convert_to_object(cdata) def convert_to_object(self, cdata): @@ -213,7 +213,7 @@ sh = self.size * 8 return (r_uint(1) << sh) - 1 - def int(self, cdata): + def cast_to_int(self, cdata): return self.convert_to_object(cdata) def convert_from_object(self, cdata, w_ob): @@ -288,7 +288,7 @@ keepalive_until_here(w_cdata) return w_cdata - def int(self, cdata): + def cast_to_int(self, cdata): w_value = self.float(cdata) return self.space.int(w_value) diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -3,6 +3,7 @@ from rpython.rlib.rstring import UnicodeBuilder from rpython.rlib.objectmodel import we_are_translated + class CodecState(object): def __init__(self, space): self.codec_search_path = [] @@ -35,11 +36,11 @@ space.wrap(endpos), space.wrap(reason)) w_res = space.call_function(w_errorhandler, w_exc) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2 - or not space.is_true(space.isinstance( + or not space.isinstance_w( space.getitem(w_res, space.wrap(0)), - space.w_unicode))): + space.w_unicode)): if decode: msg = ("decoding error handler must return " "(unicode, int) tuple, not %s") @@ -135,8 +136,7 @@ w_result = space.call_function(w_search, space.wrap(normalized_encoding)) if not space.is_w(w_result, space.w_None): - if not (space.is_true(space.isinstance(w_result, - space.w_tuple)) and + if not (space.isinstance_w(w_result, space.w_tuple) and space.len_w(w_result) == 4): raise OperationError( space.w_TypeError, @@ -322,8 +322,7 @@ w_decoder = space.getitem(lookup_codec(space, encoding), space.wrap(1)) if space.is_true(w_decoder): w_res = space.call_function(w_decoder, w_obj, space.wrap(errors)) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) - or space.len_w(w_res) != 2): + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2): raise OperationError( space.w_TypeError, space.wrap("encoder must return a tuple (object, integer)")) @@ -493,7 +492,7 @@ self.w_mapping = w_mapping # fast path for all the stuff in the encodings module - if space.is_true(space.isinstance(w_mapping, space.w_tuple)): + if space.isinstance_w(w_mapping, space.w_tuple): self.mapping_w = space.fixedview(w_mapping) else: self.mapping_w = None diff --git a/pypy/module/_locale/interp_locale.py b/pypy/module/_locale/interp_locale.py --- a/pypy/module/_locale/interp_locale.py +++ b/pypy/module/_locale/interp_locale.py @@ -118,11 +118,12 @@ _strcoll = rlocale.external('strcoll', [rffi.CCHARP, rffi.CCHARP], rffi.INT) _wcscoll = rlocale.external('wcscoll', [rffi.CWCHARP, rffi.CWCHARP], rffi.INT) + def strcoll(space, w_s1, w_s2): "string,string -> int. Compares two strings according to the locale." - if space.is_true(space.isinstance(w_s1, space.w_str)) and \ - space.is_true(space.isinstance(w_s2, space.w_str)): + if (space.isinstance_w(w_s1, space.w_str) and + space.isinstance_w(w_s2, space.w_str)): s1, s2 = space.str_w(w_s1), space.str_w(w_s2) s1_c = rffi.str2charp(s1) @@ -133,11 +134,6 @@ rffi.free_charp(s1_c) rffi.free_charp(s2_c) - #if not space.is_true(space.isinstance(w_s1, space.w_unicode)) and \ - # not space.is_true(space.isinstance(w_s2, space.w_unicode)): - # raise OperationError(space.w_ValueError, - # space.wrap("strcoll arguments must be strings")) - s1, s2 = space.unicode_w(w_s1), space.unicode_w(w_s2) s1_c = rffi.unicode2wcharp(s1) diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -28,9 +28,9 @@ if w_n is None: w_n = space.newint(int(time.time())) else: - if space.is_true(space.isinstance(w_n, space.w_int)): + if space.isinstance_w(w_n, space.w_int): w_n = space.abs(w_n) - elif space.is_true(space.isinstance(w_n, space.w_long)): + elif space.isinstance_w(w_n, space.w_long): w_n = space.abs(w_n) else: # XXX not perfectly like CPython @@ -59,7 +59,7 @@ return space.newtuple(state) def setstate(self, space, w_state): - if not space.is_true(space.isinstance(w_state, space.w_tuple)): + if not space.isinstance_w(w_state, space.w_tuple): errstring = space.wrap("state vector must be tuple") raise OperationError(space.w_TypeError, errstring) if space.len_w(w_state) != rrandom.N + 1: @@ -78,7 +78,7 @@ self._rnd.index = space.int_w(w_item) def jumpahead(self, space, w_n): - if space.is_true(space.isinstance(w_n, space.w_long)): + if space.isinstance_w(w_n, space.w_long): num = space.bigint_w(w_n) n = intmask(num.uintmask()) else: diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py --- a/pypy/module/_rawffi/array.py +++ b/pypy/module/_rawffi/array.py @@ -163,7 +163,7 @@ return itemsize * self.length def decodeslice(self, space, w_slice): - if not space.is_true(space.isinstance(w_slice, space.w_slice)): + if not space.isinstance_w(w_slice, space.w_slice): raise OperationError(space.w_TypeError, space.wrap('index must be int or slice')) letter = self.shape.itemcode diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -91,7 +91,7 @@ def unpack_simple_shape(space, w_shape): # 'w_shape' must be either a letter or a tuple (struct, 1). - if space.is_true(space.isinstance(w_shape, space.w_str)): + if space.isinstance_w(w_shape, space.w_str): letter = space.str_w(w_shape) return letter2tp(space, letter) else: @@ -102,7 +102,7 @@ def unpack_shape_with_length(space, w_shape): # Allow 'w_shape' to be a letter or any (shape, number). # The result is always a W_Array. - if space.is_true(space.isinstance(w_shape, space.w_str)): + if space.isinstance_w(w_shape, space.w_str): letter = space.str_w(w_shape) return letter2tp(space, letter) else: @@ -171,7 +171,7 @@ else: ffi_restype = ffi_type_void - if space.is_true(space.isinstance(w_name, space.w_str)): + if space.isinstance_w(w_name, space.w_str): name = space.str_w(w_name) try: @@ -183,8 +183,7 @@ except LibFFIError: raise got_libffi_error(space) - elif (_MS_WINDOWS and - space.is_true(space.isinstance(w_name, space.w_int))): + elif (_MS_WINDOWS and space.isinstance_w(w_name, space.w_int)): ordinal = space.int_w(w_name) try: ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes, @@ -311,12 +310,13 @@ raise NotImplementedError("abstract base class") def unwrap_truncate_int(TP, space, w_arg): - if space.is_true(space.isinstance(w_arg, space.w_int)): + if space.isinstance_w(w_arg, space.w_int): return rffi.cast(TP, space.int_w(w_arg)) else: return rffi.cast(TP, space.bigint_w(w_arg).ulonglongmask()) unwrap_truncate_int._annspecialcase_ = 'specialize:arg(0)' + def unwrap_value(space, push_func, add_arg, argdesc, letter, w_arg): w = space.wrap if letter in TYPEMAP_PTR_LETTERS: diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py --- a/pypy/module/_rawffi/structure.py +++ b/pypy/module/_rawffi/structure.py @@ -32,7 +32,7 @@ name = space.str_w(l_w[0]) except OperationError: raise OperationError(space.w_TypeError, space.wrap( - "structure field name must be string not %s" % + "structure field name must be string not %s" % space.type(l_w[0]).getname(space))) tp = unpack_shape_with_length(space, l_w[1]) @@ -153,7 +153,7 @@ bitsizes = None self.fields = fields self.size = size - self.alignment = alignment + self.alignment = alignment self.ll_positions = pos self.ll_bitsizes = bitsizes self.name_to_index = name_to_index @@ -223,11 +223,10 @@ self.alignment, fieldtypes) return self.ffi_struct.ffistruct - + def __del__(self): if self.ffi_struct: lltype.free(self.ffi_struct, flavor='raw') - @unwrap_spec(union=bool, pack=int) @@ -236,7 +235,7 @@ raise OperationError(space.w_ValueError, space.wrap( "_pack_ must be a non-negative integer")) - if space.is_true(space.isinstance(w_shapeinfo, space.w_tuple)): + if space.isinstance_w(w_shapeinfo, space.w_tuple): w_size, w_alignment = space.fixedview(w_shapeinfo, expected_length=2) S = W_Structure(space, None, space.int_w(w_size), space.int_w(w_alignment), union) @@ -372,7 +371,7 @@ def __del__(self): if self.ll_buffer: self._free() - + W_StructureInstanceAutoFree.typedef = TypeDef( 'StructureInstanceAutoFree', __repr__ = interp2app(W_StructureInstance.descr_repr), diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -255,9 +255,9 @@ # host can be None, string or unicode if space.is_w(w_host, space.w_None): host = None - elif space.is_true(space.isinstance(w_host, space.w_str)): + elif space.isinstance_w(w_host, space.w_str): host = space.str_w(w_host) - elif space.is_true(space.isinstance(w_host, space.w_unicode)): + elif space.isinstance_w(w_host, space.w_unicode): w_shost = space.call_method(w_host, "encode", space.wrap("idna")) host = space.str_w(w_shost) else: @@ -268,9 +268,9 @@ # port can be None, int or string if space.is_w(w_port, space.w_None): port = None - elif space.is_true(space.isinstance(w_port, space.w_int)): + elif space.isinstance_w(w_port, space.w_int): port = str(space.int_w(w_port)) - elif space.is_true(space.isinstance(w_port, space.w_str)): + elif space.isinstance_w(w_port, space.w_str): port = space.str_w(w_port) else: raise OperationError(space.w_TypeError, diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -32,7 +32,19 @@ assert space.unwrap(ip) == socket.gethostbyname_ex(host) def test_gethostbyaddr(): + try: + socket.gethostbyaddr("::1") + except socket.herror: + ipv6 = False + else: + ipv6 = True for host in ["localhost", "127.0.0.1", "::1"]: + if host == "::1" and not ipv6: + from pypy.interpreter.error import OperationError + with py.test.raises(OperationError): + space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + continue ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) == socket.gethostbyaddr(host) @@ -219,7 +231,7 @@ "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info -def test_unknown_addr_as_object(): +def test_unknown_addr_as_object(): from pypy.module._socket.interp_socket import addr_as_object c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw') c_addr.c_sa_data[0] = 'c' @@ -228,7 +240,7 @@ # to be short enough so we have some data, 1 sounds good enough # + sizeof USHORT w_obj = addr_as_object(rsocket.Address(c_addr, 1 + 2), -1, space) - assert space.is_true(space.isinstance(w_obj, space.w_tuple)) + assert space.isinstance_w(w_obj, space.w_tuple) assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15 assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c' diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -101,18 +101,24 @@ """Make a StrMatchContext or a UnicodeMatchContext for searching in the given w_string object.""" space = self.space - if pos < 0: pos = 0 - if endpos < pos: endpos = pos - if space.is_true(space.isinstance(w_string, space.w_unicode)): + if pos < 0: + pos = 0 + if endpos < pos: + endpos = pos + if space.isinstance_w(w_string, space.w_unicode): unicodestr = space.unicode_w(w_string) - if pos > len(unicodestr): pos = len(unicodestr) - if endpos > len(unicodestr): endpos = len(unicodestr) + if pos > len(unicodestr): + pos = len(unicodestr) + if endpos > len(unicodestr): + endpos = len(unicodestr) return rsre_core.UnicodeMatchContext(self.code, unicodestr, pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) - if pos > len(str): pos = len(str) - if endpos > len(str): endpos = len(str) + if pos > len(str): + pos = len(str) + if endpos > len(str): + endpos = len(str) return rsre_core.StrMatchContext(self.code, str, pos, endpos, self.flags) @@ -212,7 +218,7 @@ w_filter = w_ptemplate filter_is_callable = True else: - if space.is_true(space.isinstance(w_ptemplate, space.w_unicode)): + if space.isinstance_w(w_ptemplate, space.w_unicode): filter_as_unicode = space.unicode_w(w_ptemplate) literal = u'\\' not in filter_as_unicode else: @@ -267,7 +273,7 @@ sublist_w.append(slice_w(space, ctx, last_pos, ctx.end, space.w_None)) - if space.is_true(space.isinstance(w_string, space.w_unicode)): + if space.isinstance_w(w_string, space.w_unicode): w_emptystr = space.wrap(u'') else: w_emptystr = space.wrap('') @@ -381,15 +387,15 @@ return space.call_method(w_re, '_expand', space.wrap(self.srepat), space.wrap(self), w_template) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def start_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[0]) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def end_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[1]) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def span_w(self, w_groupnum): start, end = self.do_span(w_groupnum) return self.space.newtuple([self.space.wrap(start), diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py --- a/pypy/module/_weakref/interp__weakref.py +++ b/pypy/module/_weakref/interp__weakref.py @@ -92,8 +92,7 @@ w_weakreftype = space.gettypeobject(W_Weakref.typedef) for wref in self.other_refs_weak.items(): w_ref = wref() - if (w_ref is not None and - space.is_true(space.isinstance(w_ref, w_weakreftype))): + if (w_ref is not None and space.isinstance_w(w_ref, w_weakreftype)): return w_ref return space.w_None @@ -103,8 +102,8 @@ def __init__(self, space, oldlifeline=None): self.space = space if oldlifeline is not None: - self.cached_weakref = oldlifeline.cached_weakref - self.cached_proxy = oldlifeline.cached_proxy + self.cached_weakref = oldlifeline.cached_weakref + self.cached_proxy = oldlifeline.cached_proxy self.other_refs_weak = oldlifeline.other_refs_weak def __del__(self): diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -108,9 +108,9 @@ raise OperationError(space.w_TypeError, errstring) elif isinstance(w_hkey, W_HKEY): return w_hkey.hkey - elif space.is_true(space.isinstance(w_hkey, space.w_int)): + elif space.isinstance_w(w_hkey, space.w_int): return rffi.cast(rwinreg.HKEY, space.int_w(w_hkey)) - elif space.is_true(space.isinstance(w_hkey, space.w_long)): + elif space.isinstance_w(w_hkey, space.w_long): return rffi.cast(rwinreg.HKEY, space.uint_w(w_hkey)) else: errstring = space.wrap("The object is not a PyHKEY object") @@ -266,7 +266,7 @@ buf = None if typ == rwinreg.REG_DWORD: - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): buflen = rffi.sizeof(rwin32.DWORD) buf1 = lltype.malloc(rffi.CArray(rwin32.DWORD), 1, flavor='raw') buf1[0] = space.uint_w(w_value) @@ -278,7 +278,7 @@ buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') buf[0] = '\0' else: - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): w_value = space.call_method(w_value, 'encode', space.wrap('mbcs')) buf = rffi.str2charp(space.str_w(w_value)) @@ -289,7 +289,7 @@ buflen = 1 buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') buf[0] = '\0' - elif space.is_true(space.isinstance(w_value, space.w_list)): + elif space.isinstance_w(w_value, space.w_list): strings = [] buflen = 0 @@ -298,7 +298,7 @@ while True: try: w_item = space.next(w_iter) - if space.is_true(space.isinstance(w_item, space.w_unicode)): + if space.isinstance_w(w_item, space.w_unicode): w_item = space.call_method(w_item, 'encode', space.wrap('mbcs')) item = space.str_w(w_item) diff --git a/pypy/module/cpyext/complexobject.py b/pypy/module/cpyext/complexobject.py --- a/pypy/module/cpyext/complexobject.py +++ b/pypy/module/cpyext/complexobject.py @@ -12,21 +12,24 @@ Py_complex_fields = (("real", rffi.DOUBLE), ("imag", rffi.DOUBLE)) cpython_struct("Py_complex", Py_complex_fields, Py_complex_t) + @cpython_api([lltype.Float, lltype.Float], PyObject) def PyComplex_FromDoubles(space, real, imag): return space.newcomplex(real, imag) + @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_RealAsDouble(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_complex)): + if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.realval else: return space.float_w(w_obj) + @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_ImagAsDouble(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_complex)): + if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.imagval else: diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -29,7 +29,7 @@ space.setitem(w_globals, space.wrap("__builtins__"), w_builtin) # Get the __import__ function from the builtins - if space.is_true(space.isinstance(w_builtin, space.w_dict)): + if space.isinstance_w(w_builtin, space.w_dict): w_import = space.getitem(w_builtin, space.wrap("__import__")) else: w_import = space.getattr(w_builtin, space.wrap("__import__")) diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py --- a/pypy/module/cpyext/intobject.py +++ b/pypy/module/cpyext/intobject.py @@ -69,6 +69,7 @@ space.wrap("an integer is required, got NULL")) return space.uint_w(space.int(w_obj)) + @cpython_api([PyObject], rffi.ULONG, error=-1) def PyInt_AsUnsignedLongMask(space, w_obj): """Will first attempt to cast the object to a PyIntObject or @@ -76,13 +77,14 @@ unsigned long. This function does not check for overflow. """ w_int = space.int(w_obj) - if space.is_true(space.isinstance(w_int, space.w_int)): + if space.isinstance_w(w_int, space.w_int): num = space.int_w(w_int) return r_uint(num) else: num = space.bigint_w(w_int) return num.uintmask() + @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyInt_AsUnsignedLongLongMask(space, w_obj): """Will first attempt to cast the object to a PyIntObject or @@ -90,7 +92,7 @@ unsigned long long, without checking for overflow. """ w_int = space.int(w_obj) - if space.is_true(space.isinstance(w_int, space.w_int)): + if space.isinstance_w(w_int, space.w_int): num = space.int_w(w_int) return r_ulonglong(num) else: diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -23,6 +23,13 @@ """ return space.newlong(val) + at cpython_api([rffi.SIZE_T], PyObject) +def PyLong_FromSize_t(space, val): + """Return a new PyLongObject object from a C size_t, or NULL on + failure. + """ + return space.wrap(val) + @cpython_api([rffi.LONGLONG], PyObject) def PyLong_FromLongLong(space, val): """Return a new PyLongObject object from a C long long, or NULL diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py --- a/pypy/module/cpyext/pyerrors.py +++ b/pypy/module/cpyext/pyerrors.py @@ -182,7 +182,7 @@ exc is a class object, this also returns true when given is an instance of a subclass. If exc is a tuple, all exceptions in the tuple (and recursively in subtuples) are searched for a match.""" - if (space.is_true(space.isinstance(w_given, space.w_BaseException)) or + if (space.isinstance_w(w_given, space.w_BaseException) or space.is_oldstyle_instance(w_given)): w_given_type = space.exception_getclass(w_given) else: diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1395,13 +1395,6 @@ """ raise NotImplementedError - at cpython_api([rffi.SIZE_T], PyObject) -def PyLong_FromSize_t(space, v): - """Return a new PyLongObject object from a C size_t, or - NULL on failure. - """ - raise NotImplementedError - @cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.INT_real], PyObject) def PyLong_FromUnicode(space, u, length, base): """Convert a sequence of Unicode digits to a Python long integer value. The first diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -146,6 +146,15 @@ assert module.from_longlong() == -1 assert module.from_unsignedlonglong() == (1<<64) - 1 + def test_from_size_t(self): + module = self.import_extension('foo', [ + ("from_unsignedlong", "METH_NOARGS", + """ + return PyLong_FromSize_t((size_t)-1); + """)]) + import sys + assert module.from_unsignedlong() == 2 * sys.maxint + 1 + def test_fromstring(self): module = self.import_extension('foo', [ ("from_string", "METH_NOARGS", diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -304,7 +304,7 @@ api.PyUnicode_Decode(b_text, 4, b_encoding, None)) == u'caf\xe9' w_text = api.PyUnicode_FromEncodedObject(space.wrap("test"), b_encoding, None) - assert space.is_true(space.isinstance(w_text, space.w_unicode)) + assert space.isinstance_w(w_text, space.w_unicode) assert space.unwrap(w_text) == "test" assert api.PyUnicode_FromEncodedObject(space.wrap(u"test"), b_encoding, None) is None diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -248,7 +248,7 @@ Py_DecRef(space, base_object_pyo) def check_descr(space, w_self, w_type): - if not space.is_true(space.isinstance(w_self, w_type)): + if not space.isinstance_w(w_self, w_type): raise DescrMismatch() class GettersAndSetters: @@ -489,7 +489,7 @@ pto.c_tp_as_sequence = heaptype.c_as_sequence pto.c_tp_as_mapping = heaptype.c_as_mapping pto.c_tp_as_buffer = heaptype.c_as_buffer - + return rffi.cast(PyObject, heaptype) def type_attach(space, py_obj, w_type): @@ -734,4 +734,4 @@ return if w_obj.is_cpytype(): w_obj.mutated(None) - + diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -1,6 +1,5 @@ from pypy.interpreter.error import OperationError from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rtyper.lltypesystem import llmemory from pypy.module.unicodedata import unicodedb from pypy.module.cpyext.api import ( CANNOT_FAIL, Py_ssize_t, build_type_checkers, cpython_api, @@ -388,7 +387,7 @@ # - unicode is disallowed # - raise TypeError for non-string types - if space.is_true(space.isinstance(w_obj, space.w_unicode)): + if space.isinstance_w(w_obj, space.w_unicode): w_meth = None else: try: diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -156,7 +156,7 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("setting exceptions's dictionary to a non-dict")) self.w_dict = w_dict diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -182,7 +182,7 @@ def _log_any(space, w_x, base): # base is supposed to be positive or 0.0, which means we use e try: - if space.is_true(space.isinstance(w_x, space.w_long)): + if space.isinstance_w(w_x, space.w_long): # special case to support log(extremely-large-long) num = space.bigint_w(w_x) result = num.log(base) diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py --- a/pypy/module/operator/interp_operator.py +++ b/pypy/module/operator/interp_operator.py @@ -233,8 +233,8 @@ raise OperationError(space.w_TypeError, space.wrap("non-sequence object can't be repeated")) - if not (space.is_true(space.isinstance(w_obj2, space.w_int)) or \ - space.is_true(space.isinstance(w_obj2, space.w_long))): + if not (space.isinstance_w(w_obj2, space.w_int) or + space.isinstance_w(w_obj2, space.w_long)): # second arg has to be int/long raise OperationError(space.w_TypeError, space.wrap('an integer is required')) diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -82,7 +82,7 @@ # perform binds if w_vars is None: pass - elif space.is_true(space.isinstance(w_vars, space.w_dict)): + elif space.isinstance_w(w_vars, space.w_dict): self._setBindVariablesByName(space, w_vars, 1, 0, 0) else: self._setBindVariablesByPos(space, w_vars, 1, 0, 0) @@ -114,7 +114,7 @@ def executemany(self, space, w_stmt, w_list_of_args): if space.is_w(w_stmt, space.w_None): w_stmt = None - if not space.is_true(space.isinstance(w_list_of_args, space.w_list)): + if not space.isinstance_w(w_list_of_args, space.w_list): raise OperationError( space.w_TypeError, space.wrap("list expected")) @@ -137,7 +137,7 @@ for i in range(numrows): w_arguments = args_w[i] deferred = i < numrows - 1 - if space.is_true(space.isinstance(w_arguments, space.w_dict)): + if space.isinstance_w(w_arguments, space.w_dict): self._setBindVariablesByName( space, w_arguments, numrows, i, deferred) else: @@ -317,7 +317,7 @@ if e.match(space, get(space).w_DatabaseError): attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') try: - status = roci.OCIAttrGet( + roci.OCIAttrGet( self.handle, roci.OCI_HTYPE_STMT, rffi.cast(roci.dvoidp, attrptr), lltype.nullptr(roci.Ptr(roci.ub4).TO), @@ -603,7 +603,7 @@ def _setBindVariableHelper(self, space, w_value, origVar, numElements, arrayPos, defer): - valueIsVariable = space.is_true(space.isinstance(w_value, get(space).w_Variable)) + valueIsVariable = space.isinstance_w(w_value, get(space).w_Variable) newVar = None # handle case where variable is already bound @@ -859,8 +859,6 @@ def _createRow(self, space): items_w = [] - numItems = len(self.fetchVariables) - # acquire the value for each item for var in self.fetchVariables: assert isinstance(var, interp_variable.W_Variable) @@ -981,9 +979,9 @@ size = varType.size # determine the number of elements to create - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): numElements = space.len_w(w_value) - elif space.is_true(space.isinstance(w_value, space.w_int)): + elif space.isinstance_w(w_value, space.w_int): numElements = space.int_w(w_value) else: raise OperationError( @@ -995,7 +993,7 @@ var.makeArray(space) # set the value, if applicable - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): var.setArrayValue(space, w_value) return var diff --git a/pypy/module/oracle/interp_variable.py b/pypy/module/oracle/interp_variable.py --- a/pypy/module/oracle/interp_variable.py +++ b/pypy/module/oracle/interp_variable.py @@ -425,7 +425,7 @@ def setArrayValue(self, space, w_value): # ensure we have an array to set - if not space.is_true(space.isinstance(w_value, space.w_list)): + if not space.isinstance_w(w_value, space.w_list): raise OperationError( space.w_TypeError, space.wrap("expecting array data")) @@ -514,7 +514,7 @@ wantBytes = self.charsetForm == roci.SQLCS_IMPLICIT if wantBytes: - if space.is_true(space.isinstance(w_value, space.w_str)): + if space.isinstance_w(w_value, space.w_str): buf = config.StringBuffer() buf.fill(space, w_value) size = buf.size @@ -523,7 +523,7 @@ space.w_TypeError, space.wrap("expecting string or buffer data")) else: - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): buf = config.StringBuffer() buf.fill_with_unicode(space, w_value) size = buf.size @@ -760,7 +760,7 @@ rffi.cast(roci.Ptr(roci.OCINumber), self.data), pos) - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): integerValuePtr = lltype.malloc(roci.Ptr(lltype.Signed).TO, 1, flavor='raw') try: @@ -776,7 +776,7 @@ finally: lltype.free(integerValuePtr, flavor='raw') return - elif space.is_true(space.isinstance(w_value, space.w_long)): + elif space.isinstance_w(w_value, space.w_long): text_buf = config.StringBuffer() text_buf.fill(space, space.str(w_value)) format_buf = config.StringBuffer() @@ -793,7 +793,7 @@ status, "NumberVar_SetValue(): from long") return # XXX The bool case was already processed above - elif space.is_true(space.isinstance(w_value, space.w_float)): + elif space.isinstance_w(w_value, space.w_float): doubleValuePtr = lltype.malloc(roci.Ptr(lltype.Float).TO, 1, flavor='raw') try: @@ -808,7 +808,7 @@ finally: lltype.free(doubleValuePtr, flavor='raw') return - elif space.is_true(space.isinstance(w_value, get(space).w_DecimalType)): + elif space.isinstance_w(w_value, get(space).w_DecimalType): w_text, w_format = transform.DecimalToFormatAndText(self.environment, w_value) text_buf = config.StringBuffer() text_buf.fill(space, w_text) @@ -856,14 +856,14 @@ dataptr = rffi.ptradd( rffi.cast(roci.Ptr(roci.OCIDate), self.data), pos) - if space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if space.isinstance_w(w_value, get(space).w_DateTimeType): year = space.int_w(space.getattr(w_value, space.wrap('year'))) month = space.int_w(space.getattr(w_value, space.wrap('month'))) day = space.int_w(space.getattr(w_value, space.wrap('day'))) hour = space.int_w(space.getattr(w_value, space.wrap('hour'))) minute = space.int_w(space.getattr(w_value, space.wrap('minute'))) second = space.int_w(space.getattr(w_value, space.wrap('second'))) - elif space.is_true(space.isinstance(w_value, get(space).w_DateType)): + elif space.isinstance_w(w_value, get(space).w_DateType): year = space.int_w(space.getattr(w_value, space.wrap('year'))) month = space.int_w(space.getattr(w_value, space.wrap('month'))) day = space.int_w(space.getattr(w_value, space.wrap('day'))) @@ -933,7 +933,7 @@ def setValueProc(self, space, pos, w_value): # make sure a timestamp is being bound - if not space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if not space.isinstance_w(w_value, get(space).w_DateTimeType): raise OperationError( space.w_TypeError, space.wrap("expecting timestamp data")) @@ -985,8 +985,7 @@ self.environment, self.getDataptr(pos)) def setValueProc(self, space, pos, w_value): - if not space.is_true(space.isinstance(w_value, - get(space).w_TimedeltaType)): + if not space.isinstance_w(w_value, get(space).w_TimedeltaType): raise OperationError( space.w_TypeError, space.wrap("expecting timedelta data")) @@ -1208,7 +1207,7 @@ def setValueProc(self, space, pos, w_value): from pypy.module.oracle import interp_cursor w_CursorType = space.gettypeobject(interp_cursor.W_Cursor.typedef) - if not space.is_true(space.isinstance(w_value, w_CursorType)): + if not space.isinstance_w(w_value, w_CursorType): raise OperationError( space.w_TypeError, space.wrap("expecting cursor")) @@ -1414,7 +1413,7 @@ from pypy.objspace.std.typeobject import W_TypeObject moduledict = get(space) - if not space.is_true(space.isinstance(w_type, space.w_type)): + if not space.isinstance_w(w_type, space.w_type): raise OperationError( space.w_TypeError, space.wrap("Variable_TypeByPythonType(): type expected")) @@ -1435,49 +1434,49 @@ if space.is_w(w_value, space.w_None): return VT_String, 1, numElements - if space.is_true(space.isinstance(w_value, space.w_str)): + if space.isinstance_w(w_value, space.w_str): size = space.len_w(w_value) if size > config.MAX_STRING_CHARS: return VT_LongString, size, numElements else: return VT_String, size, numElements - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): size = space.len_w(w_value) return VT_NationalCharString, size, numElements - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): return VT_Integer, 0, numElements - if space.is_true(space.isinstance(w_value, space.w_long)): + if space.isinstance_w(w_value, space.w_long): return VT_LongInteger, 0, numElements - if space.is_true(space.isinstance(w_value, space.w_float)): + if space.isinstance_w(w_value, space.w_float): return VT_Float, 0, numElements # XXX cxBinary # XXX bool - if space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if space.isinstance_w(w_value, get(space).w_DateTimeType): return VT_DateTime, 0, numElements - if space.is_true(space.isinstance(w_value, get(space).w_DateType)): + if space.isinstance_w(w_value, get(space).w_DateType): return VT_Date, 0, numElements # XXX Delta from pypy.module.oracle import interp_cursor - if space.is_true(space.isinstance( # XXX is there an easier way? + if space.isinstance_w( # XXX is there an easier way? w_value, - space.gettypeobject(interp_cursor.W_Cursor.typedef))): + space.gettypeobject(interp_cursor.W_Cursor.typedef)): return VT_Cursor, 0, numElements - if space.is_true(space.isinstance(w_value, get(space).w_DecimalType)): + if space.isinstance_w(w_value, get(space).w_DecimalType): return VT_NumberAsString, 0, numElements # handle arrays - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): elements_w = space.listview(w_value) for w_element in elements_w: if not space.is_w(w_element, space.w_None): @@ -1497,8 +1496,7 @@ space.wrap(cursor), w_value, space.wrap(numElements)) - if not space.is_true(space.isinstance(w_var, - get(space).w_Variable)): + if not space.isinstance_w(w_var, get(space).w_Variable): raise OperationError( space.w_TypeError, space.wrap("expecting variable from input type handler")) @@ -1519,7 +1517,7 @@ if space.is_w(var, space.w_None): varType, size, numElements = typeByValue(space, w_value, numElements) var = varType(cursor, numElements, size) - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): var.makeArray(space) assert isinstance(var, W_Variable) @@ -1539,7 +1537,7 @@ def newVariableByType(space, cursor, w_value, numElements): # passing an integer is assumed to be a string - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): size = space.int_w(w_value) if size > config.MAX_STRING_CHARS: varType = VT_LongString @@ -1548,12 +1546,11 @@ return varType(cursor, numElements, size) # passing an array of two elements define an array - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): return newArrayVariableByType(space, cursor, w_value) # handle directly bound variables - if space.is_true(space.isinstance(w_value, - get(space).w_Variable)): + if space.isinstance_w(w_value, get(space).w_Variable): return space.interp_w(W_Variable, w_value) # everything else ought to be a Python type diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1080,6 +1080,7 @@ func = declare_new_w_star(name) globals()[name] = func + @unwrap_spec(fd=c_int) def ttyname(space, fd): try: @@ -1087,9 +1088,10 @@ except OSError, e: raise wrap_oserror(space, e) + def confname_w(space, w_name, namespace): # XXX slightly non-nice, reuses the sysconf of the underlying os module - if space.is_true(space.isinstance(w_name, space.w_basestring)): + if space.isinstance_w(w_name, space.w_basestring): try: num = namespace[space.str_w(w_name)] except KeyError: diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -796,7 +796,7 @@ Return a new XML parser object.""" if space.is_none(w_encoding): encoding = None - elif space.is_true(space.isinstance(w_encoding, space.w_str)): + elif space.isinstance_w(w_encoding, space.w_str): encoding = space.str_w(w_encoding) else: type_name = space.type(w_encoding).getname(space) @@ -807,7 +807,7 @@ if space.is_none(w_namespace_separator): namespace_separator = 0 - elif space.is_true(space.isinstance(w_namespace_separator, space.w_str)): + elif space.isinstance_w(w_namespace_separator, space.w_str): separator = space.str_w(w_namespace_separator) if len(separator) == 0: namespace_separator = 0 diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -432,10 +432,10 @@ glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO) rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0) - w_accept2dyear = _get_module_object(space, "accept2dyear") - accept2dyear = space.int_w(w_accept2dyear) + if y < 1900: + w_accept2dyear = _get_module_object(space, "accept2dyear") + accept2dyear = space.int_w(w_accept2dyear) - if y < 1900: if not accept2dyear: raise OperationError(space.w_ValueError, space.wrap("year >= 1900 required")) diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -139,6 +139,16 @@ ltime = rctime.localtime() assert rctime.asctime(tuple(ltime)) == rctime.asctime(ltime) + def test_accept2dyear_access(self): + import time as rctime + + accept2dyear = rctime.accept2dyear + del rctime.accept2dyear + try: From noreply at buildbot.pypy.org Mon Mar 25 23:44:31 2013 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 25 Mar 2013 23:44:31 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: overloading based on "argument priority" and associated tests Message-ID: <20130325224431.24F841C2F7A@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62768:43726e21a664 Date: 2013-03-25 15:43 -0700 http://bitbucket.org/pypy/pypy/changeset/43726e21a664/ Log: overloading based on "argument priority" and associated tests diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py --- a/pypy/module/cppyy/capi/cint_capi.py +++ b/pypy/module/cppyy/capi/cint_capi.py @@ -120,7 +120,7 @@ classname = space.str_w(args_w[1]) addr_idx = 2 w_address = args_w[addr_idx] - except OperationError: + except (OperationError, TypeError): addr_idx = 1 w_address = args_w[addr_idx] @@ -140,11 +140,12 @@ branch_class = interp_cppyy.scope_byname(space, "TBranch") w_branch = interp_cppyy.wrap_cppobject(space, vbranch, branch_class) return w_branch - except (OperationError, TypeError, IndexError), e: + except (OperationError, TypeError, IndexError): pass # return control back to the original, unpythonized overload - return tree_class.get_overload("Branch").call(w_self, args_w) + ol = tree_class.get_overload("Branch") + return ol.call(w_self, args_w) def activate_branch(space, w_branch): w_branches = space.call_method(w_branch, "GetListOfBranches") diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py --- a/pypy/module/cppyy/interp_cppyy.py +++ b/pypy/module/cppyy/interp_cppyy.py @@ -16,6 +16,17 @@ class FastCallNotPossible(Exception): pass +# overload priorities: lower is preferred +priority = { 'void*' : 100, + 'void**' : 100, + 'float' : 30, + 'double' : 10, } + +from rpython.rlib.listsort import make_timsort_class +CPPMethodBaseTimSort = make_timsort_class() +class CPPMethodSort(CPPMethodBaseTimSort): + def lt(self, a, b): + return a.priority() < b.priority() @unwrap_spec(name=str) def load_dictionary(space, name): @@ -224,7 +235,8 @@ def _setup(self, cppthis): self.converters = [converter.get_converter(self.space, arg_type, arg_dflt) for arg_type, arg_dflt in self.arg_defs] - self.executor = executor.get_executor(self.space, capi.c_method_result_type(self.scope, self.index)) + self.executor = executor.get_executor( + self.space, capi.c_method_result_type(self.scope, self.index)) for conv in self.converters: if conv.uses_local: @@ -350,6 +362,12 @@ def signature(self): return capi.c_method_signature(self.scope, self.index) + def priority(self): + total_arg_priority = 0 + for p in [priority.get(arg_type, 0) for arg_type, arg_dflt in self.arg_defs]: + total_arg_priority += p + return total_arg_priority + def __del__(self): if self.cif_descr: lltype.free(self.cif_descr.atypes, flavor='raw') @@ -373,7 +391,7 @@ return "CPPFunction: %s" % self.signature() -class CPPTemplatedCall(CPPMethod): # TODO: unnecessary derivation to make rtyper happy +class CPPTemplatedCall(CPPMethod): """Method dispatcher that first needs to resolve the template instance. Note that the derivation is from object: the CPPMethod is a data member.""" @@ -384,7 +402,7 @@ self.space = space self.templ_args = templ_args # TODO: might have to specialize for CPPTemplatedCall on CPPMethod/CPPFunction here - self.method = CPPMethod(space, containing_scope, method_index, arg_defs, args_required) + CPPMethod.__init__(self, space, containing_scope, method_index, arg_defs, args_required) def call(self, cppthis, args_w): assert lltype.typeOf(cppthis) == capi.C_OBJECT @@ -397,10 +415,10 @@ if s != self.templ_args[i]: raise OperationError(self.space.w_TypeError, self.space.wrap( "non-matching template (got %s where %s expected" % (s, self.templ_args[i]))) - return W_CPPBoundMethod(cppthis, self.method) + return W_CPPBoundMethod(cppthis, self) - def signature(self): - return self.method.signature() + def bound_call(self, cppthis, args_w): + return CPPMethod.call(self, cppthis, args_w) def __repr__(self): return "CPPTemplatedCall: %s" % self.signature() @@ -541,7 +559,7 @@ self.method = method def __call__(self, args_w): - return self.method.call(self.cppthis, args_w) + return self.method.bound_call(self.cppthis, args_w) W_CPPBoundMethod.typedef = TypeDef( 'CPPBoundMethod', @@ -662,6 +680,7 @@ # create the overload methods from the method sets for pyname, methods in methods_temp.iteritems(): + CPPMethodSort(methods).sort() overload = W_CPPOverload(self.space, self, methods[:]) self.methods[pyname] = overload diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py --- a/pypy/module/cppyy/test/test_cint.py +++ b/pypy/module/cppyy/test/test_cint.py @@ -329,20 +329,20 @@ mytree._python_owns = False import array - ba = array.array('c', [chr(0)]) - ia = array.array('i', [0]) - da = array.array('d', [0.]) + mytree.ba = array.array('c', [chr(0)]) + mytree.ia = array.array('i', [0]) + mytree.da = array.array('d', [0.]) - mytree.Branch("my_bool", ba, "my_bool/O") - mytree.Branch("my_int", ia, "my_int/I") - mytree.Branch("my_int2", ia, "my_int2/I") - mytree.Branch("my_double", da, "my_double/D") + mytree.Branch("my_bool", mytree.ba, "my_bool/O") + mytree.Branch("my_int", mytree.ia, "my_int/I") + mytree.Branch("my_int2", mytree.ia, "my_int2/I") + mytree.Branch("my_double", mytree.da, "my_double/D") for i in range(self.N): # make sure value is different from default (0) - ba[0] = i%2 and chr(0) or chr(1) - ia[0] = i+1 - da[0] = (i+1)/2. + mytree.ba[0] = i%2 and chr(0) or chr(1) + mytree.ia[0] = i+1 + mytree.da[0] = (i+1)/2. mytree.Fill() f.Write() f.Close() diff --git a/pypy/module/cppyy/test/test_overloads.py b/pypy/module/cppyy/test/test_overloads.py --- a/pypy/module/cppyy/test/test_overloads.py +++ b/pypy/module/cppyy/test/test_overloads.py @@ -62,7 +62,7 @@ assert c.__dispatch__('get_int', 'b_overload*')(b_overload()) == 13 assert c_overload().__dispatch__('get_int', 'a_overload*')(a_overload()) == 42 -# assert c_overload.__dispatch__('get_int', 'b_overload*')(c, b_overload()) == 13 + # TODO: #assert c_overload.__dispatch__('get_int', 'b_overload*')(c, b_overload()) == 13 d = d_overload() assert d.__dispatch__('get_int', 'a_overload*')(a_overload()) == 42 @@ -105,11 +105,9 @@ def test05_array_overloads(self): """Test functions overloaded on different arrays""" - # TODO: buffer to pointer interface - return - import cppyy c_overload = cppyy.gbl.c_overload + d_overload = cppyy.gbl.d_overload from array import array @@ -127,8 +125,8 @@ import cppyy more_overloads = cppyy.gbl.more_overloads -# assert more_overloads().call(1) == "int" -# assert more_overloads().call(1.) == "double" + assert more_overloads().call(1) == "int" + assert more_overloads().call(1.) == "double" assert more_overloads().call1(1) == "int" assert more_overloads().call1(1.) == "double" @@ -143,4 +141,4 @@ for l in ['f', 'd', 'i', 'h', 'l']: a = array.array(l, numbers) - assert(round(cmean(len(a), a) - mean, 8), 0) + assert round(cmean(len(a), a) - mean, 8) == 0 From noreply at buildbot.pypy.org Tue Mar 26 00:25:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Mar 2013 00:25:00 +0100 (CET) Subject: [pypy-commit] pypy gc-del: intermediate checkin, probably going to be partially reverted Message-ID: <20130325232500.D0CCC1C2F79@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62769:c5a0ce8bcab3 Date: 2013-03-26 00:24 +0100 http://bitbucket.org/pypy/pypy/changeset/c5a0ce8bcab3/ Log: intermediate checkin, probably going to be partially reverted diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1243,6 +1243,7 @@ # # Before everything else, remove from 'old_objects_pointing_to_young' # the young arrays. + self.remember_young_rawmalloced_visited = None if self.young_rawmalloced_objects: self.remove_young_arrays_from_old_objects_pointing_to_young() # @@ -1492,7 +1493,7 @@ # We will fix such references to point to the copy of the young # objects when we walk 'old_objects_pointing_to_young'. self.old_objects_pointing_to_young.append(newobj) - #debug_print("adding", newobj) + debug_print("adding", newobj) _trace_drag_out._always_inline_ = True def _visit_young_rawmalloced_object(self, obj): @@ -1522,6 +1523,10 @@ added_somewhere = True # ll_assert(added_somewhere, "wrong flag combination on young array") + # + # If 'remember_young_rawmalloced_visited', record it there as well + if self.remember_young_rawmalloced_visited: + self.remember_young_rawmalloced_visited.append(obj) def _malloc_out_of_nursery(self, totalsize): @@ -1922,85 +1927,75 @@ objects with finalizers. As these survive for a bit longer, we also need to copy them out of the nursery. The tricky part here is to enqueue them in topological order, if possible. + + This is done as three steps: first we find which objects are + not reachable at all from 'outside'; then we copy them outside + the nursery together with everything they point to; and finally + we use on them the generic _deal_with_objects_with_finalizers(). """ ll_assert(not self.old_objects_pointing_to_young.non_empty(), "deal_with_young_objects_with_finalizers: " "old_objects_pointing_to_young should be empty") + ll_assert(not self.objects_to_trace.non_empty(), + "objects_to_trace non empty [deal_young_finalizer]") finalizer_funcs = self.AddressDict() - self.finalizers_scheduled = self.AddressStack() # while self.young_objects_with_finalizers.non_empty(): func = self.young_objects_with_finalizers.pop() obj = self.young_objects_with_finalizers.pop() # - # The following lines move 'obj' out of the nursery and add it to - # 'self.old_objects_pointing_to_young' --- unless the object - # survive, in which case it was already seen and the following - # lines have no effect. - root = self.temp_root - root.address[0] = obj - self._trace_drag_out1(root) - objcopy = root.address[0] - #debug_print("finalizer for", obj) - #debug_print("object moving to", objcopy) + survives = False # - # Remember the finalizer in the dict - finalizer_funcs.setitem(objcopy, func) + if self.is_in_nursery(obj): + if self.is_forwarded(obj): + obj = self.get_forwarding_address(obj) + survives = True + else: + # + # The following lines move 'obj' out of the nursery and + # add it to 'self.old_objects_pointing_to_young'. + root = self.temp_root + root.address[0] = obj + self._trace_drag_out1(root) + obj = root.address[0] # - # Now follow all the refs - self._follow_references_from_young_object_with_finalizer() + elif (bool(self.young_rawmalloced_objects) and + self.young_rawmalloced_objects.contains(obj)): + if self.header(obj).tid & GCFLAG_VISITED: + survives = True + # + if survives: + self.old_objects_with_finalizers.append(obj) + self.old_objects_with_finalizers.append(func) + else: + # Remember the finalizer in the dict + finalizer_funcs.setitem(obj, func) + self.objects_to_trace.append(obj) # - # Copy the objects scheduled into 'run_finalizers_queue', in - # reverse order. - while self.finalizers_scheduled.non_empty(): - obj = self.finalizers_scheduled.pop() - func = finalizer_funcs.get(obj) - ll_assert(func != NULL, "lost finalizer [1]") - self.run_finalizers_queue.append(obj) - self.run_finalizers_funcs.append(func) - finalizer_funcs.setitem(obj, NULL) - self.finalizers_scheduled.delete() + # Follow all refs + self.remember_young_rawmalloced_visited = self.AddressStack() + self.collect_oldrefs_to_nursery() # - # The non-NULL entries remaining in 'finalizer_funcs' correspond - # to objects that survived, because they have not been traced by - # this function but already before. - finalizer_funcs.foreach(self._move_to_old_finalizer, - self.old_objects_with_finalizers) - finalizer_funcs.delete() + # Reset GCFLAG_VISITED on young rawmalloced objects added just before + self.remember_young_rawmalloced_visited.foreach( + self._remove_gcflag_visited, None) + self.remember_young_rawmalloced_visited.delete() + self.remember_young_rawmalloced_visited = None + # + # At this point all objects reachable from 'finalizer_funcs' + # are disconnected from the rest of the world, and none has + # the GCFLAG_VISITED set. Use the generic method. + self._deal_with_objects_with_finalizers(finalizer_funcs) - def _follow_references_from_young_object_with_finalizer(self): - pending = self.old_objects_pointing_to_young - while pending.non_empty(): - assert not self.old_objects_with_cards_set.non_empty(), "XXX" - obj = pending.pop() - #debug_print("popping", obj) - if obj: - # - if self.header(obj).tid & GCFLAG_HAS_FINALIZER: - self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER - #debug_print("this object has a finalizer") - pending.append(obj) - pending.append(NULL) # marker - # - ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS - == 0, "bad flags [deal_young_finalizer]") - self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS - self.trace_and_drag_out_of_nursery(obj) - # - else: - # seen a NULL marker - obj = pending.pop() - #debug_print("adding to scheduled", obj) - self.finalizers_scheduled.append(obj) - @staticmethod - def _move_to_old_finalizer(obj, finalizer, old_objects_with_finalizers): - if finalizer != NULL: - old_objects_with_finalizers.append(obj) - old_objects_with_finalizers.append(finalizer) + def _remove_gcflag_visited(self, obj, ignored): + # 'obj' has GCFLAG_VISITED; remove it. + ll_assert(self.header(obj).tid & GCFLAG_VISITED != 0, + "remove_gcflag_visited: not?") + self.header(obj).tid &= ~GCFLAG_VISITED - def deal_with_old_objects_with_finalizers(self): + def _deal_with_objects_with_finalizers(self, finalizer_funcs): # Walk over list of objects with finalizers. # If it is not surviving, add it to the list of to-be-called # finalizers and make it survive, to make the finalizer runnable. @@ -2008,28 +2003,7 @@ # CPython does. The details of this algorithm are in # pypy/doc/discussion/finalizer-order.txt. # - ll_assert(not self.objects_to_trace.non_empty(), - "objects_to_trace non empty [deal_old_finalizer]") - # - old_objs = self.old_objects_with_finalizers - self.old_objects_with_finalizers = self.AddressStack() - finalizer_funcs = self.AddressDict() - # - while old_objs.non_empty(): - func = old_objs.pop() - obj = old_objs.pop() - ll_assert(bool(self.header(obj).tid & GCFLAG_HAS_FINALIZER), - "lost GCFLAG_HAS_FINALIZER") - # - if self.header(obj).tid & GCFLAG_VISITED: - # surviving - self.old_objects_with_finalizers.append(obj) - self.old_objects_with_finalizers.append(func) - # - else: - # dying - self.objects_to_trace.append(obj) - finalizer_funcs.setitem(obj, func) + xxxxxxxxxxx # # Now follow all the refs finalizers_scheduled = self.AddressStack() @@ -2063,6 +2037,33 @@ old_objs.delete() + def deal_with_old_objects_with_finalizers(self): + ll_assert(not self.objects_to_trace.non_empty(), + "objects_to_trace non empty [deal_old_finalizer]") + # + old_objs = self.old_objects_with_finalizers + self.old_objects_with_finalizers = self.AddressStack() + finalizer_funcs = self.AddressDict() + # + while old_objs.non_empty(): + func = old_objs.pop() + obj = old_objs.pop() + ll_assert(bool(self.header(obj).tid & GCFLAG_HAS_FINALIZER), + "lost GCFLAG_HAS_FINALIZER") + # + if self.header(obj).tid & GCFLAG_VISITED: + # surviving + self.old_objects_with_finalizers.append(obj) + self.old_objects_with_finalizers.append(func) + # + else: + # dying + self.objects_to_trace.append(obj) + finalizer_funcs.setitem(obj, func) + # + self._deal_with_objects_with_finalizers(finalizer_funcs) + + # ---------- # Weakrefs diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -12,6 +12,7 @@ def definestr_finalizer_order(cls): import random x = random.randrange(0,10000) + x = 2696 print "R"*1000 print x print '-'*60 @@ -19,7 +20,7 @@ from rpython.tool.algo import graphlib cls.finalizer_order_examples = examples = [] - if cls.large_tests_ok: + if 1: # cls.large_tests_ok: letters = 'abcdefghijklmnopqrstuvwxyz' COUNT = 20 else: @@ -76,7 +77,7 @@ vertices[c].refs.append(vertices[d]) def f(_): - i = 0 + i = 2 while i < len(examples): debug_print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") input, components, strict = examples[i] diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -1060,8 +1060,8 @@ GC_PARAMS = {'card_page_indices': 4} class TestMiniMarkGCLargeNursery(TestMiniMarkGC): - GC_PARAMS = {'nursery_size': 1024*WORD} - def setup_class(cls): - py.test.skip("takes a lot of extra time to run") - def teardown_class(cls): - pass + GC_PARAMS = {'nursery_size': 16384*WORD} + #def setup_class(cls): + # py.test.skip("takes a lot of extra time to run") + #def teardown_class(cls): + # pass From noreply at buildbot.pypy.org Tue Mar 26 00:47:03 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Tue, 26 Mar 2013 00:47:03 +0100 (CET) Subject: [pypy-commit] pypy default: Configure Tddium Message-ID: <20130325234703.F3FC01C2F70@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62770:fceab4c8f86f Date: 2013-03-25 16:44 -0700 http://bitbucket.org/pypy/pypy/changeset/fceab4c8f86f/ Log: Configure Tddium diff --git a/.tddium.requirements.txt b/.tddium.requirements.txt new file mode 100644 --- /dev/null +++ b/.tddium.requirements.txt @@ -0,0 +1,1 @@ +pytest diff --git a/tddium.yml b/tddium.yml new file mode 100644 --- /dev/null +++ b/tddium.yml @@ -0,0 +1,20 @@ +tddium: + timeout: 1800 + python: + python_version: 2.7 + pip_requirements_file: .tddium.requirements.txt # will go away soon + tests: + - type: pytest + mode: parallel + files: + - pypy/**/test_*.py + - rpython/**/test_*.py + - exclude: pypy/module/test_lib_pypy/ctypes_tests/** # don't run in CPython + - exclude: rpython/jit/backend/cli/** # bitrotted AFAICT + - exclude: rpython/jit/backend/llvm/** # bitrotted AFAICT + # and things requiring a fix in Tddium, omitted to avoid confusion: + - exclude: pypy/tool/pytest/** # we're running upstream pytest + - exclude: rpython/rlib/unicodedata/test/test_ucd.py # need wide build + - exclude: rpython/rlib/test/test_runicode.py # need wide build + - exclude: rpython/rlib/test/test_rsocket.py # not clear why fails + - exclude: pypy/module/cpyext/test/** # multiple failures due to truncated files; not clear why From noreply at buildbot.pypy.org Tue Mar 26 01:32:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:32:02 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: start working on removal of gen_store_back - for now we have a new operation Message-ID: <20130326003202.B20D81C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62771:b21e10d01f46 Date: 2013-03-25 17:08 -0700 http://bitbucket.org/pypy/pypy/changeset/b21e10d01f46/ Log: start working on removal of gen_store_back - for now we have a new operation that checks if we have a fresh virtualizable 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 @@ -286,7 +286,7 @@ def get_savedata_ref(self, deadframe): assert deadframe._saved_data is not None return deadframe._saved_data - + # ------------------------------------------------------------ def calldescrof(self, FUNC, ARGS, RESULT, effect_info): @@ -334,7 +334,7 @@ except KeyError: descr = InteriorFieldDescr(A, fieldname) self.descrs[key] = descr - return descr + return descr def _calldescr_dynamic_for_tests(self, atypes, rtype, abiname='FFI_DEFAULT_ABI'): @@ -566,6 +566,10 @@ def bh_read_timestamp(self): return read_timestamp() + def bh_force_virtualizable(self, v, descr): + vinfo = descr.vinfo + vinfo.clear_vable_token(v) + def store_fail_descr(self, deadframe, descr): pass # I *think* @@ -789,7 +793,7 @@ else: ovf = False self.overflow_flag = ovf - return z + return z def execute_guard_no_overflow(self, descr): if self.overflow_flag: diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -1299,6 +1299,10 @@ from rpython.jit.metainterp import quasiimmut quasiimmut.do_force_quasi_immutable(cpu, struct, mutatefielddescr) + @arguments("cpu", "r", "d") + def bhimpl_force_virtualizable(cpu, v, descr): + cpu.bh_force_virtualizable(v, descr) + @arguments("cpu", "d", returns="r") def bhimpl_new(cpu, descr): return cpu.bh_new(descr) diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py --- a/rpython/jit/metainterp/executor.py +++ b/rpython/jit/metainterp/executor.py @@ -276,6 +276,9 @@ def do_keepalive(cpu, _, x): pass +def do_force_virtualizable(cpu, _, v, descr): + cpu.bh_force_virtualizable(v.getref_base(), descr) + # ____________________________________________________________ ##def do_force_token(cpu): diff --git a/rpython/jit/metainterp/heapcache.py b/rpython/jit/metainterp/heapcache.py --- a/rpython/jit/metainterp/heapcache.py +++ b/rpython/jit/metainterp/heapcache.py @@ -143,6 +143,7 @@ self.heap_cache.clear() self.heap_array_cache.clear() + self.nonstandard_virtualizables.clear() def is_class_known(self, box): return box in self.known_class_boxes diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -603,7 +603,7 @@ def _opimpl_getfield_gc_greenfield_any(self, box, fielddescr, pc): ginfo = self.metainterp.jitdriver_sd.greenfield_info if (ginfo is not None and fielddescr in ginfo.green_field_descrs - and not self._nonstandard_virtualizable(pc, box)): + and not self._nonstandard_virtualizable(pc, box, fielddescr)): # fetch the result, but consider it as a Const box and don't # record any operation resbox = executor.execute(self.metainterp.cpu, self.metainterp, @@ -699,7 +699,7 @@ raise SwitchToBlackhole(Counters.ABORT_FORCE_QUASIIMMUT) self.generate_guard(rop.GUARD_ISNULL, mutatebox, resumepc=orgpc) - def _nonstandard_virtualizable(self, pc, box): + def _nonstandard_virtualizable(self, pc, box, fielddescr): # returns True if 'box' is actually not the "standard" virtualizable # that is stored in metainterp.virtualizable_boxes[-1] if (self.metainterp.jitdriver_sd.virtualizable_info is None and @@ -710,6 +710,10 @@ return False if self.metainterp.heapcache.is_nonstandard_virtualizable(box): return True + vinfo = self.metainterp.jitdriver_sd.virtualizable_info + if vinfo is not fielddescr.vinfo: + self.metainterp.heapcache.nonstandard_virtualizables_now_known(box) + return True eqbox = self.metainterp.execute_and_record(rop.PTR_EQ, None, box, standard_box) eqbox = self.implement_guard_value(eqbox, pc) @@ -717,6 +721,9 @@ if isstandard: self.metainterp.replace_box(box, standard_box) else: + if not self.metainterp.heapcache.is_unescaped(box): + self.metainterp.execute_and_record(rop.FORCE_VIRTUALIZABLE, + fielddescr, box) self.metainterp.heapcache.nonstandard_virtualizables_now_known(box) return not isstandard @@ -728,7 +735,7 @@ @arguments("box", "descr", "orgpc") def _opimpl_getfield_vable(self, box, fielddescr, pc): - if self._nonstandard_virtualizable(pc, box): + if self._nonstandard_virtualizable(pc, box, fielddescr): return self._opimpl_getfield_gc_any(box, fielddescr) self.metainterp.check_synchronized_virtualizable() index = self._get_virtualizable_field_index(fielddescr) @@ -740,7 +747,7 @@ @arguments("box", "box", "descr", "orgpc") def _opimpl_setfield_vable(self, box, valuebox, fielddescr, pc): - if self._nonstandard_virtualizable(pc, box): + if self._nonstandard_virtualizable(pc, box, fielddescr): return self._opimpl_setfield_gc_any(box, valuebox, fielddescr) index = self._get_virtualizable_field_index(fielddescr) self.metainterp.virtualizable_boxes[index] = valuebox @@ -770,7 +777,7 @@ @arguments("box", "box", "descr", "descr", "orgpc") def _opimpl_getarrayitem_vable(self, box, indexbox, fdescr, adescr, pc): - if self._nonstandard_virtualizable(pc, box): + if self._nonstandard_virtualizable(pc, box, fdescr): arraybox = self._opimpl_getfield_gc_any(box, fdescr) return self._opimpl_getarrayitem_gc_any(arraybox, indexbox, adescr) self.metainterp.check_synchronized_virtualizable() @@ -784,7 +791,7 @@ @arguments("box", "box", "box", "descr", "descr", "orgpc") def _opimpl_setarrayitem_vable(self, box, indexbox, valuebox, fdescr, adescr, pc): - if self._nonstandard_virtualizable(pc, box): + if self._nonstandard_virtualizable(pc, box, fdescr): arraybox = self._opimpl_getfield_gc_any(box, fdescr) self._opimpl_setarrayitem_gc_any(arraybox, indexbox, valuebox, adescr) @@ -800,7 +807,7 @@ @arguments("box", "descr", "descr", "orgpc") def opimpl_arraylen_vable(self, box, fdescr, adescr, pc): - if self._nonstandard_virtualizable(pc, box): + if self._nonstandard_virtualizable(pc, box, fdescr): arraybox = self._opimpl_getfield_gc_any(box, fdescr) return self.opimpl_arraylen_gc(arraybox, adescr) vinfo = self.metainterp.jitdriver_sd.virtualizable_info diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -494,6 +494,7 @@ 'VIRTUAL_REF/2', # removed before it's passed to the backend 'READ_TIMESTAMP/0', 'MARK_OPAQUE_PTR/1b', + 'FORCE_VIRTUALIZABLE/1d', # forces a non-standard virtualizable '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'SETARRAYITEM_GC/3d', diff --git a/rpython/jit/metainterp/test/test_virtualizable.py b/rpython/jit/metainterp/test/test_virtualizable.py --- a/rpython/jit/metainterp/test/test_virtualizable.py +++ b/rpython/jit/metainterp/test/test_virtualizable.py @@ -73,7 +73,7 @@ x = xy.inst_x xy.inst_x = x + 1 n -= 1 - promote_virtualizable(xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [20]) assert res == 30 @@ -97,7 +97,7 @@ x = xy.inst_x xy.inst_x = x + 10 n -= 1 - promote_virtualizable(xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') return xy.inst_x assert f(5) == 185 res = self.meta_interp(f, [5]) @@ -118,10 +118,10 @@ x = xy.inst_x if n <= 10: x += 1000 - promote_virtualizable(xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') xy.inst_x = x + 1 n -= 1 - promote_virtualizable(xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [18]) assert res == 10118 @@ -164,7 +164,7 @@ xy.inst_x = x + 1 m = (m+1) & 3 # the loop gets unrolled 4 times n -= 1 - promote_virtualizable(xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') return xy.inst_x def f(n): res = 0 @@ -194,11 +194,11 @@ promote_virtualizable(xy, 'inst_x') xy.inst_x = value + 100 # virtualized away n -= 1 - promote_virtualizable(xy, 'inst_x') + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [20]) assert res == 134 - self.check_simple_loop(setfield_gc=1, getfield_gc=0) + self.check_simple_loop(setfield_gc=1, getfield_gc=0, force_virtualizable=1) self.check_resops(setfield_gc=2, getfield_gc=3) # ------------------------------ @@ -241,11 +241,11 @@ while n > 0: myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) - promote_virtualizable(xy2, 'inst_l1') + promote_virtualizable(xy2, 'inst_l1') promote_virtualizable(xy2, 'inst_l2') xy2.inst_l1[2] += xy2.inst_l2[0] n -= 1 - promote_virtualizable(xy2, 'inst_l1') + promote_virtualizable(xy2, 'inst_l1') return xy2.inst_l1[2] res = self.meta_interp(f, [16]) assert res == 3001 + 16 * 80 @@ -292,7 +292,7 @@ myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) promote_virtualizable(xy2, 'inst_l1') - promote_virtualizable(xy2, 'inst_l2') + promote_virtualizable(xy2, 'inst_l2') xy2.inst_l1[1] += len(xy2.inst_l2) n -= 1 def f(n): @@ -373,7 +373,7 @@ promote_virtualizable(xy2, 'inst_l2') xy2.inst_l2[0] = value + 100 # virtualized away n -= 1 - promote_virtualizable(xy2, 'inst_l2') + promote_virtualizable(xy2, 'inst_l2') return xy2.inst_l2[0] expected = f(20) res = self.meta_interp(f, [20], enable_opts='') @@ -406,8 +406,8 @@ myjitdriver.can_enter_jit(xy2=xy2, n=n) myjitdriver.jit_merge_point(xy2=xy2, n=n) parent = xy2.parent - promote_virtualizable(parent, 'inst_x') - promote_virtualizable(parent, 'inst_l2') + promote_virtualizable(parent, 'inst_x') + promote_virtualizable(parent, 'inst_l2') parent.inst_l2[0] += parent.inst_x n -= 1 def f(n): @@ -473,7 +473,7 @@ def __init__(self, l, s): self.l = l self.s = s - + def f(n, a): frame = Frame([a,a+1,a+2,a+3], 0) x = 0 @@ -560,7 +560,7 @@ def test_external_read(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -592,7 +592,7 @@ def test_external_read_with_exception(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -663,7 +663,7 @@ def test_external_read_sometimes(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -699,7 +699,7 @@ def test_external_read_sometimes_with_virtuals(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class Y: @@ -742,7 +742,7 @@ def test_external_read_sometimes_changing_virtuals(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class Y: @@ -790,7 +790,7 @@ def test_external_read_sometimes_with_exception(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class FooBarError(Exception): @@ -832,7 +832,7 @@ def test_external_read_sometimes_dont_compile_guard(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -868,7 +868,7 @@ def test_external_read_sometimes_recursive(self): jitdriver = JitDriver(greens = [], reds = ['rec', 'frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -919,7 +919,7 @@ def test_external_write_sometimes(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -955,7 +955,7 @@ def test_bridge_forces(self): jitdriver = JitDriver(greens = [], reds = ['frame'], virtualizables = ['frame']) - + class Frame(object): _virtualizable2_ = ['x', 'y'] class SomewhereElse: @@ -1262,7 +1262,7 @@ somewhere_else = SomewhereElse() def jump_back(frame, fail): - myjitdriver.can_enter_jit(frame=frame, fail=fail) + myjitdriver.can_enter_jit(frame=frame, fail=fail) def f(n, fail): frame = Frame(n, 0) @@ -1428,7 +1428,7 @@ OOJitMixin): pass - + class TestLLtype(ExplicitVirtualizableTests, ImplicitVirtualizableTests, LLJitMixin): diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py --- a/rpython/jit/metainterp/virtualizable.py +++ b/rpython/jit/metainterp/virtualizable.py @@ -65,6 +65,12 @@ for name in static_fields] self.array_field_descrs = [cpu.fielddescrof(VTYPE, name) for name in array_fields] + + for descr in self.static_field_descrs: + descr.vinfo = self + for descr in self.array_field_descrs: + descr.vinfo = self + self.static_field_by_descrs = dict( [(descr, i) for (i, descr) in enumerate(self.static_field_descrs)]) self.array_field_by_descrs = dict( From noreply at buildbot.pypy.org Tue Mar 26 01:32:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:32:04 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: make the test check what I want Message-ID: <20130326003204.042771C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62772:5cbac99bcd55 Date: 2013-03-25 17:14 -0700 http://bitbucket.org/pypy/pypy/changeset/5cbac99bcd55/ Log: make the test check what I want diff --git a/rpython/jit/metainterp/test/test_recursive.py b/rpython/jit/metainterp/test/test_recursive.py --- a/rpython/jit/metainterp/test/test_recursive.py +++ b/rpython/jit/metainterp/test/test_recursive.py @@ -33,7 +33,7 @@ myjitdriver = JitDriver(greens=[], reds=['n', 'm']) class Error(Exception): pass - + def f(n): m = n - 2 while True: @@ -246,7 +246,7 @@ class Exc(Exception): pass - + def f(code, n): pc = 0 while pc < len(code): @@ -286,7 +286,7 @@ return "%s %d %s" % (code, pc, code[pc]) myjitdriver = JitDriver(greens=['pc', 'code'], reds=['n'], get_printable_location=p) - + def f(code, n): pc = 0 while pc < len(code): @@ -309,7 +309,7 @@ return n def main(n): set_param(None, 'threshold', 3) - set_param(None, 'trace_eagerness', 5) + set_param(None, 'trace_eagerness', 5) return f("c-l", n) expected = main(100) res = self.meta_interp(main, [100], enable_opts='', inline=True) @@ -328,7 +328,7 @@ if n > 0: return recursive(n - 1) + 1 return 0 - def loop(n): + def loop(n): set_param(myjitdriver, "threshold", 10) pc = 0 while n: @@ -411,8 +411,8 @@ self.i7 = i7 self.i8 = i8 self.i9 = i9 - - + + def loop(n): i = 0 o = A(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) @@ -444,8 +444,8 @@ self.i7 = i7 self.i8 = i8 self.i9 = i9 - - + + def loop(n): i = 0 o = A(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) @@ -467,7 +467,7 @@ res = self.meta_interp(main, [20], failargs_limit=FAILARGS_LIMIT, listops=True) assert not res - self.check_aborted_count(5) + self.check_aborted_count(5) def test_set_param_inlining(self): myjitdriver = JitDriver(greens=[], reds=['n', 'recurse']) @@ -480,7 +480,7 @@ myjitdriver.can_enter_jit(n=n, recurse=recurse) return n TRACE_LIMIT = 66 - + def main(inline): set_param(None, "threshold", 10) set_param(None, 'function_threshold', 60) @@ -502,7 +502,7 @@ return "'%s' at %d: %s" % (code, pc, code[pc]) myjitdriver = JitDriver(greens=['pc', 'code'], reds=['n'], get_printable_location=p) - + def f(code, n): pc = 0 while pc < len(code): @@ -543,7 +543,7 @@ return "%s %d %s" % (code, pc, code[pc]) myjitdriver = JitDriver(greens=['pc', 'code'], reds=['n'], get_printable_location=p) - + def f(code, n): pc = 0 while pc < len(code): @@ -576,7 +576,7 @@ result += f('-c-----------l-', i+100) self.meta_interp(g, [10], backendopt=True) self.check_aborted_count(1) - self.check_resops(call=0, call_assembler=2) + self.check_resops(call=0, call_assembler=2) self.check_jitcell_token_count(2) def test_directly_call_assembler(self): @@ -717,7 +717,7 @@ class MyException(Exception): def __init__(self, x): self.x = x - + driver = JitDriver(greens = ['codeno'], reds = ['i'], get_printable_location = lambda codeno : str(codeno)) @@ -736,7 +736,7 @@ raise MyException(1) self.meta_interp(portal, [2], inline=True) - self.check_history(call_assembler=1) + self.check_history(call_assembler=1) def test_directly_call_assembler_fail_guard(self): driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], @@ -765,11 +765,11 @@ class Thing(object): def __init__(self, val): self.val = val - + class Frame(object): _virtualizable2_ = ['thing'] - - driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], + + driver = JitDriver(greens = ['codeno'], reds = ['i', 's', 'frame'], virtualizables = ['frame'], get_printable_location = lambda codeno : str(codeno)) @@ -781,19 +781,22 @@ def portal(codeno, frame): i = 0 + s = 0 while i < 10: - driver.can_enter_jit(frame=frame, codeno=codeno, i=i) - driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + driver.can_enter_jit(frame=frame, codeno=codeno, i=i, s=s) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i, s=s) nextval = frame.thing.val if codeno == 0: subframe = Frame() subframe.thing = Thing(nextval) nextval = portal(1, subframe) + s += subframe.thing.val frame.thing = Thing(nextval + 1) i += 1 return frame.thing.val res = self.meta_interp(main, [0], inline=True) + self.check_resops(force_virtualizable=2) assert res == main(0) def test_directly_call_assembler_virtualizable_reset_token(self): @@ -803,10 +806,10 @@ class Thing(object): def __init__(self, val): self.val = val - + class Frame(object): _virtualizable2_ = ['thing'] - + driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], virtualizables = ['frame'], get_printable_location = lambda codeno : str(codeno)) @@ -854,10 +857,10 @@ class Thing(object): def __init__(self, val): self.val = val - + class Frame(object): _virtualizable2_ = ['thing'] - + driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], virtualizables = ['frame'], get_printable_location = lambda codeno : str(codeno)) @@ -918,7 +921,7 @@ def main(codeno, n, a): frame = Frame([a, a+1, a+2, a+3], 0) return f(codeno, n, a, frame) - + def f(codeno, n, a, frame): x = 0 while n > 0: @@ -948,10 +951,10 @@ class Thing(object): def __init__(self, val): self.val = val - + class Frame(object): _virtualizable2_ = ['thing'] - + driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], virtualizables = ['frame'], get_printable_location = lambda codeno : str(codeno)) @@ -1195,7 +1198,7 @@ def test_trace_from_start_always(self): from rpython.rlib.nonconst import NonConstant - + driver = JitDriver(greens = ['c'], reds = ['i', 'v']) def portal(c, i, v): @@ -1220,7 +1223,7 @@ def test_trace_from_start_does_not_prevent_inlining(self): driver = JitDriver(greens = ['c', 'bc'], reds = ['i']) - + def portal(bc, c, i): while True: driver.jit_merge_point(c=c, bc=bc, i=i) @@ -1229,7 +1232,7 @@ c += 1 else: return - if c == 10: # bc == 0 + if c == 10: # bc == 0 c = 0 if i >= 100: return From noreply at buildbot.pypy.org Tue Mar 26 01:32:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:32:05 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: write a test Message-ID: <20130326003205.2CEDA1C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62773:de81399b8ba6 Date: 2013-03-25 17:28 -0700 http://bitbucket.org/pypy/pypy/changeset/de81399b8ba6/ Log: write a test diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -348,7 +348,7 @@ i0 = BoxInt() class UntouchableFailDescr(AbstractFailDescr): final_descr = True - + def __setattr__(self, name, value): if (name == 'index' or name == '_carry_around_for_tests' or name == '_TYPE' or name == '_cpu'): @@ -3375,7 +3375,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo) testcases = [(4.0, 2.0), (6.25, 2.5)] for arg, expected in testcases: - res = self.execute_operation(rop.CALL, + res = self.execute_operation(rop.CALL, [funcbox, boxfloat(arg)], 'float', descr=calldescr) assert res.getfloat() == expected @@ -3729,7 +3729,7 @@ # memory assert values[0] == 0 - def test_compile_bridge_while_running(self): + def test_compile_bridge_while_running(self): def func(): bridge = parse(""" [i1, i2, px] @@ -3776,9 +3776,9 @@ func2_ptr = llhelper(FPTR2, func2) calldescr2 = cpu.calldescrof(FUNC2, FUNC2.ARGS, FUNC2.RESULT, EffectInfo.MOST_GENERAL) - + faildescr = BasicFailDescr(0) - + looptoken = JitCellToken() loop = parse(""" [i0, i1, i2] @@ -3794,7 +3794,7 @@ if not isinstance(self.cpu, AbstractLLCPU): py.test.skip("pointless test on non-asm") - + frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) assert len(frame.jf_frame) == frame.jf_frame_info.jfi_frame_depth ref = self.cpu.get_ref_value(frame, 9) @@ -3856,9 +3856,33 @@ 'calldescr': calldescr, 'faildescr': faildescr, 'finaldescr2': BasicFinalDescr(1)}) - + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1, 2, 3) descr = self.cpu.get_latest_descr(frame) assert descr.identifier == 42 assert not self.cpu.grab_exc_value(frame) + + def test_force_virtualizable(self): + + class FakeVinfo(object): + # for llgraph + def clear_vable_token(self, token): + lltype.cast_opaque_ptr(lltype.Ptr(S), token).x = 18 + + S = lltype.GcStruct('x', ('x', lltype.Signed)) + + pdescr = self.cpu.fielddescrof(S, 'x') + pdescr.vinfo = FakeVinfo() + loop = parse(""" + [p0] + force_virtualizable(p0, descr=pdescr) + i1 = getfield_gc(p0, descr=pdescr) + finish(i1) + """, namespace={'pdescr': pdescr}) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + s = lltype.malloc(S) + s.x = 13 + frame = self.cpu.execute_token(looptoken, lltype.cast_opaque_ptr(llmemory.GCREF, s)) + assert self.cpu.get_int_value(frame, 0) == 18 From noreply at buildbot.pypy.org Tue Mar 26 01:32:06 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:32:06 +0100 (CET) Subject: [pypy-commit] pypy default: hopefully fix this test Message-ID: <20130326003206.4F0621C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62774:3b34d83503ce Date: 2013-03-25 17:31 -0700 http://bitbucket.org/pypy/pypy/changeset/3b34d83503ce/ Log: hopefully fix this test diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py --- a/pypy/module/pypyjit/test_pypy_c/test_call.py +++ b/pypy/module/pypyjit/test_pypy_c/test_call.py @@ -339,6 +339,7 @@ loop, = log.loops_by_filename(self.filepath) # the int strategy is used here assert loop.match_by_id('append', """ + guard_not_invalidated(descr=...) i13 = getfield_gc(p8, descr=) i15 = int_add(i13, 1) # Will be killed by the backend @@ -581,7 +582,7 @@ d = {'a': 2, 'b': 3, 'd':4} f(*a, **d) # ID: call i += 1 - return 13 + return 13 """, [1000]) loop, = log.loops_by_id('call') assert loop.match_by_id('call', ''' @@ -602,7 +603,7 @@ while i < stop: f(*a, **d) # ID: call i += 1 - return 13 + return 13 """, [1000]) def test_complex_case_loopconst(self): @@ -617,5 +618,5 @@ while i < stop: f(*a, **d) # ID: call i += 1 - return 13 + return 13 """, [1000]) From noreply at buildbot.pypy.org Tue Mar 26 01:32:07 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:32:07 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130326003207.815241C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62775:5e70f599bd12 Date: 2013-03-25 17:31 -0700 http://bitbucket.org/pypy/pypy/changeset/5e70f599bd12/ Log: merge diff --git a/.tddium.requirements.txt b/.tddium.requirements.txt new file mode 100644 --- /dev/null +++ b/.tddium.requirements.txt @@ -0,0 +1,1 @@ +pytest diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -12,6 +12,8 @@ from rpython.rlib import rerased, jit +UNROLL_CUTOFF = 5 + def _is_str(space, w_key): return space.is_w(space.type(w_key), space.w_str) @@ -35,7 +37,7 @@ an actual dict """ return jit.isvirtual(w_dct) or (jit.isconstant(w_dct) and - w_dct.length() <= jit.UNROLL_CUTOFF) + w_dct.length() <= UNROLL_CUTOFF) class W_DictMultiObject(W_Object): 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 @@ -18,6 +18,7 @@ from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from sys import maxint +UNROLL_CUTOFF = 5 class W_AbstractListObject(W_Object): __slots__ = () @@ -42,7 +43,7 @@ return W_ListObject.from_storage_and_strategy(space, storage, strategy) @jit.look_inside_iff(lambda space, list_w, sizehint: - jit.loop_unrolling_heuristic(list_w, len(list_w))) + jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF)) def get_strategy_from_list_objects(space, list_w, sizehint): if not list_w: if sizehint != -1: @@ -956,7 +957,7 @@ raise NotImplementedError("abstract base class") @jit.look_inside_iff(lambda space, w_list, list_w: - jit.loop_unrolling_heuristic(list_w, len(list_w))) + jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF)) def init_from_list_w(self, w_list, list_w): l = [self.unwrap(w_item) for w_item in list_w] w_list.lstorage = self.erase(l) @@ -1005,7 +1006,7 @@ return self.wrap(r) @jit.look_inside_iff(lambda self, w_list: - jit.loop_unrolling_heuristic(w_list, w_list.length())) + jit.loop_unrolling_heuristic(w_list, w_list.length(), UNROLL_CUTOFF)) def getitems_copy(self, w_list): return [self.wrap(item) for item in self.unerase(w_list.lstorage)] @@ -1014,7 +1015,7 @@ return [self.wrap(item) for item in self.unerase(w_list.lstorage)] @jit.look_inside_iff(lambda self, w_list: - jit.loop_unrolling_heuristic(w_list, w_list.length())) + jit.loop_unrolling_heuristic(w_list, w_list.length(), UNROLL_CUTOFF)) def getitems_fixedsize(self, w_list): return self.getitems_unroll(w_list) @@ -1476,8 +1477,8 @@ return w_list def list_unroll_condition(space, w_list1, w_list2): - return jit.loop_unrolling_heuristic(w_list1, w_list1.length()) or \ - jit.loop_unrolling_heuristic(w_list2, w_list2.length()) + return jit.loop_unrolling_heuristic(w_list1, w_list1.length(), UNROLL_CUTOFF) or \ + jit.loop_unrolling_heuristic(w_list2, w_list2.length(), UNROLL_CUTOFF) @jit.look_inside_iff(list_unroll_condition) def eq__List_List(space, w_list1, w_list2): diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -15,6 +15,8 @@ from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib import rerased, jit +UNROLL_CUTOFF = 5 + class W_BaseSetObject(W_Object): typedef = None @@ -391,7 +393,7 @@ raise NotImplementedError @jit.look_inside_iff(lambda self, list_w: - jit.loop_unrolling_heuristic(list_w, len(list_w))) + jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF)) def get_storage_from_list(self, list_w): setdata = self.get_empty_dict() for w_item in list_w: @@ -399,7 +401,7 @@ return self.erase(setdata) @jit.look_inside_iff(lambda self, items: - jit.loop_unrolling_heuristic(items, len(items))) + jit.loop_unrolling_heuristic(items, len(items), UNROLL_CUTOFF)) def get_storage_from_unwrapped_list(self, items): setdata = self.get_empty_dict() for item in items: @@ -1033,7 +1035,7 @@ _pick_correct_strategy(space, w_set, iterable_w) @jit.look_inside_iff(lambda space, w_set, iterable_w: - jit.loop_unrolling_heuristic(iterable_w, len(iterable_w))) + jit.loop_unrolling_heuristic(iterable_w, len(iterable_w), UNROLL_CUTOFF)) def _pick_correct_strategy(space, w_set, iterable_w): # check for integers for w_item in iterable_w: diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -10,6 +10,7 @@ from rpython.rlib import jit from rpython.tool.sourcetools import func_with_new_name +UNROLL_CUTOFF = 10 class W_AbstractTupleObject(W_Object): __slots__ = () @@ -84,7 +85,7 @@ return space.newtuple(w_tuple.wrappeditems[start:stop]) @jit.look_inside_iff(lambda space, w_tuple, w_obj: - jit.loop_unrolling_heuristic(w_tuple, len(w_tuple.wrappeditems))) + jit.loop_unrolling_heuristic(w_tuple, len(w_tuple.wrappeditems), UNROLL_CUTOFF)) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): @@ -119,8 +120,8 @@ return mul_tuple_times(space, w_tuple, w_times) def tuple_unroll_condition(space, w_tuple1, w_tuple2): - return jit.loop_unrolling_heuristic(w_tuple1, len(w_tuple1.wrappeditems)) or \ - jit.loop_unrolling_heuristic(w_tuple2, len(w_tuple2.wrappeditems)) + return jit.loop_unrolling_heuristic(w_tuple1, len(w_tuple1.wrappeditems), UNROLL_CUTOFF) or \ + jit.loop_unrolling_heuristic(w_tuple2, len(w_tuple2.wrappeditems), UNROLL_CUTOFF) @jit.look_inside_iff(tuple_unroll_condition) def eq__Tuple_Tuple(space, w_tuple1, w_tuple2): @@ -173,7 +174,7 @@ return space.wrap(hash_tuple(space, w_tuple.wrappeditems)) @jit.look_inside_iff(lambda space, wrappeditems: - jit.loop_unrolling_heuristic(wrappeditems, len(wrappeditems))) + jit.loop_unrolling_heuristic(wrappeditems, len(wrappeditems), UNROLL_CUTOFF)) def hash_tuple(space, wrappeditems): # this is the CPython 2.4 algorithm (changed from 2.3) mult = 1000003 diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -206,13 +206,11 @@ return NonConstant(False) isvirtual._annspecialcase_ = "specialize:call_location" -UNROLL_CUTOFF = 5 - @specialize.call_location() -def loop_unrolling_heuristic(lst, size): +def loop_unrolling_heuristic(lst, size, cutoff=2): """ In which cases iterating over items of lst can be unrolled """ - return isvirtual(lst) or (isconstant(size) and size <= UNROLL_CUTOFF) + return isvirtual(lst) or (isconstant(size) and size <= cutoff) class Entry(ExtRegistryEntry): _about_ = hint diff --git a/tddium.yml b/tddium.yml new file mode 100644 --- /dev/null +++ b/tddium.yml @@ -0,0 +1,20 @@ +tddium: + timeout: 1800 + python: + python_version: 2.7 + pip_requirements_file: .tddium.requirements.txt # will go away soon + tests: + - type: pytest + mode: parallel + files: + - pypy/**/test_*.py + - rpython/**/test_*.py + - exclude: pypy/module/test_lib_pypy/ctypes_tests/** # don't run in CPython + - exclude: rpython/jit/backend/cli/** # bitrotted AFAICT + - exclude: rpython/jit/backend/llvm/** # bitrotted AFAICT + # and things requiring a fix in Tddium, omitted to avoid confusion: + - exclude: pypy/tool/pytest/** # we're running upstream pytest + - exclude: rpython/rlib/unicodedata/test/test_ucd.py # need wide build + - exclude: rpython/rlib/test/test_runicode.py # need wide build + - exclude: rpython/rlib/test/test_rsocket.py # not clear why fails + - exclude: pypy/module/cpyext/test/** # multiple failures due to truncated files; not clear why From noreply at buildbot.pypy.org Tue Mar 26 01:48:21 2013 From: noreply at buildbot.pypy.org (Greg Price) Date: Tue, 26 Mar 2013 01:48:21 +0100 (CET) Subject: [pypy-commit] pypy default: Split test_zll_stress Message-ID: <20130326004821.97C381C2F70@cobra.cs.uni-duesseldorf.de> Author: Greg Price Branch: Changeset: r62776:ef755ceb8a55 Date: 2013-03-25 17:46 -0700 http://bitbucket.org/pypy/pypy/changeset/ef755ceb8a55/ Log: Split test_zll_stress diff --git a/rpython/jit/backend/test/test_zll_stress_0.py b/rpython/jit/backend/test/test_zll_stress_0.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_0.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_0(): + zll_stress.do_test_stress(0) diff --git a/rpython/jit/backend/test/test_zll_stress_1.py b/rpython/jit/backend/test/test_zll_stress_1.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_1.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_1(): + zll_stress.do_test_stress(1) diff --git a/rpython/jit/backend/test/test_zll_stress_2.py b/rpython/jit/backend/test/test_zll_stress_2.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_2.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_2(): + zll_stress.do_test_stress(2) diff --git a/rpython/jit/backend/test/test_zll_stress_3.py b/rpython/jit/backend/test/test_zll_stress_3.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_3.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_3(): + zll_stress.do_test_stress(3) diff --git a/rpython/jit/backend/test/test_zll_stress.py b/rpython/jit/backend/test/zll_stress.py rename from rpython/jit/backend/test/test_zll_stress.py rename to rpython/jit/backend/test/zll_stress.py --- a/rpython/jit/backend/test/test_zll_stress.py +++ b/rpython/jit/backend/test/zll_stress.py @@ -5,14 +5,18 @@ CPU = getcpuclass() -iterations = 1000 +total_iterations = 1000 if platform.machine().startswith('arm'): - iterations = 100 + total_iterations = 100 +pieces = 4 +per_piece = total_iterations / pieces -def test_stress(): + +def do_test_stress(piece): cpu = CPU(None, None) cpu.setup_once() r = Random() - for i in range(iterations): - check_random_function(cpu, LLtypeOperationBuilder, r, i, iterations) + r.jumpahead(piece*per_piece) + for i in range(piece*per_piece, (piece+1)*per_piece): + check_random_function(cpu, LLtypeOperationBuilder, r, i, total_iterations) From noreply at buildbot.pypy.org Tue Mar 26 01:50:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:50:37 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: the dumbest possible fix for the backend Message-ID: <20130326005037.BFA8A1C2F70@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62777:f323e4b070c5 Date: 2013-03-25 17:49 -0700 http://bitbucket.org/pypy/pypy/changeset/f323e4b070c5/ Log: the dumbest possible fix for the backend diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -3866,14 +3866,21 @@ def test_force_virtualizable(self): class FakeVinfo(object): - # for llgraph - def clear_vable_token(self, token): - lltype.cast_opaque_ptr(lltype.Ptr(S), token).x = 18 + pass + def clear_vable_token(token): + lltype.cast_opaque_ptr(lltype.Ptr(S), token).x = 18 + + FUNC = lltype.FuncType([llmemory.GCREF], lltype.Void) + clear_vable_ptr = llhelper(lltype.Ptr(FUNC), clear_vable_token) S = lltype.GcStruct('x', ('x', lltype.Signed)) pdescr = self.cpu.fielddescrof(S, 'x') pdescr.vinfo = FakeVinfo() + pdescr.vinfo.clear_vable_token = clear_vable_token + pdescr.vinfo.clear_vable_ptr = clear_vable_ptr + pdescr.vinfo.clear_vable_descr = self.cpu.calldescrof(FUNC, FUNC.ARGS, + FUNC.RESULT, EffectInfo.LEAST_GENERAL) loop = parse(""" [p0] force_virtualizable(p0, descr=pdescr) 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 @@ -16,7 +16,7 @@ from rpython.jit.backend.x86.jump import remap_frame_layout_mixed from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.metainterp.resoperation import rop +from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.jit.backend.llsupport.descr import ArrayDescr from rpython.jit.backend.llsupport.descr import CallDescr from rpython.jit.backend.llsupport.descr import unpack_arraydescr @@ -54,7 +54,7 @@ class X86_64_RegisterManager(X86RegisterManager): # r11 omitted because it's used as scratch all_regs = [ecx, eax, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14, r15] - + no_lower_byte_regs = [] save_around_call_regs = [eax, ecx, edx, esi, edi, r8, r9, r10] @@ -103,7 +103,7 @@ def __init__(self, base_ofs): FrameManager.__init__(self) self.base_ofs = base_ofs - + def frame_pos(self, i, box_type): return FrameLoc(i, get_ebp_ofs(self.base_ofs, i), box_type) @@ -338,7 +338,8 @@ self.assembler.mc.mark_op(op) self.rm.position = i self.xrm.position = i - if op.has_no_side_effect() and op.result not in self.longevity: + if (op.has_no_side_effect() and op.result not in self.longevity + and op.opnum != rop.FORCE_VIRTUALIZABLE): i += 1 self.possibly_free_vars_for_op(op) continue @@ -870,6 +871,16 @@ gc_ll_descr.get_nursery_top_addr(), sizeloc, gcmap) + def consider_force_virtualizable(self, op): + # just do a call for now + vinfo = op.getdescr().vinfo + calldescr = vinfo.clear_vable_descr + assert isinstance(calldescr, CallDescr) + fval = rffi.cast(lltype.Signed, vinfo.clear_vable_ptr) + op = ResOperation(rop.CALL, [ConstInt(fval), op.getarg(0)], None, + descr=calldescr) + self.consider_call(op) + def get_gcmap(self, forbidden_regs=[], noregs=False): frame_depth = self.fm.get_frame_depth() gcmap = allocate_gcmap(self.assembler, frame_depth, JITFRAME_FIXED_SIZE) @@ -1313,7 +1324,7 @@ #jump_op = self.final_jump_op #if jump_op is not None and jump_op.getdescr() is descr: # self._compute_hint_frame_locations_from_descr(descr) - + def consider_keepalive(self, op): pass 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 @@ -160,6 +160,9 @@ EffectInfo.MOST_GENERAL = EffectInfo(None, None, None, None, EffectInfo.EF_RANDOM_EFFECTS, can_invalidate=True) +EffectInfo.LEAST_GENERAL = EffectInfo({}, {}, {}, {}, + EffectInfo.EF_ELIDABLE_CANNOT_RAISE, + can_invalidate=False) def effectinfo_from_writeanalyze(effects, cpu, diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -495,6 +495,8 @@ 'READ_TIMESTAMP/0', 'MARK_OPAQUE_PTR/1b', 'FORCE_VIRTUALIZABLE/1d', # forces a non-standard virtualizable + # this one has no *visible* side effect, since the virtualizable + # must be forced, however we need to execute it anyway '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'SETARRAYITEM_GC/3d', diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py --- a/rpython/jit/metainterp/virtualizable.py +++ b/rpython/jit/metainterp/virtualizable.py @@ -1,3 +1,4 @@ +from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp import history from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem from rpython.jit.metainterp.warmstate import wrap, unwrap @@ -70,7 +71,7 @@ descr.vinfo = self for descr in self.array_field_descrs: descr.vinfo = self - + self.static_field_by_descrs = dict( [(descr, i) for (i, descr) in enumerate(self.static_field_descrs)]) self.array_field_by_descrs = dict( @@ -291,6 +292,13 @@ FUNCPTR, force_virtualizable_if_necessary) rvirtualizable2.replace_force_virtualizable_with_call( all_graphs, self.VTYPEPTR, funcptr) + (_, FUNCPTR) = ts.get_FuncType([llmemory.GCREF], lltype.Void) + self.clear_vable_ptr = self.warmrunnerdesc.helper_func( + FUNCPTR, self.clear_vable_token) + FUNC = FUNCPTR.TO + self.clear_vable_descr = self.cpu.calldescrof(FUNC, FUNC.ARGS, + FUNC.RESULT, + EffectInfo.LEAST_GENERAL) def unwrap_virtualizable_box(self, virtualizable_box): return virtualizable_box.getref(llmemory.GCREF) From noreply at buildbot.pypy.org Tue Mar 26 01:50:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 01:50:39 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: die die die Message-ID: <20130326005039.140F61C2F70@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62778:b798c931b877 Date: 2013-03-25 17:50 -0700 http://bitbucket.org/pypy/pypy/changeset/b798c931b877/ Log: die die die diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2176,7 +2176,6 @@ self.raise_continue_running_normally(live_arg_boxes, jitcell_token) def compile_done_with_this_frame(self, exitbox): - self.gen_store_back_in_virtualizable() # temporarily put a JUMP to a pseudo-loop sd = self.staticdata result_type = self.jitdriver_sd.result_type @@ -2204,7 +2203,6 @@ compile.giveup() def compile_exit_frame_with_exception(self, valuebox): - self.gen_store_back_in_virtualizable() sd = self.staticdata token = sd.loop_tokens_exit_frame_with_exception_ref[0].finishdescr self.history.record(rop.FINISH, [valuebox], None, descr=token) @@ -2431,28 +2429,6 @@ virtualizable) self.virtualizable_boxes.append(virtualizable_box) - def gen_store_back_in_virtualizable(self): - vinfo = self.jitdriver_sd.virtualizable_info - if vinfo is not None: - # xxx only write back the fields really modified - vbox = self.virtualizable_boxes[-1] - for i in range(vinfo.num_static_extra_boxes): - fieldbox = self.virtualizable_boxes[i] - descr = vinfo.static_field_descrs[i] - self.execute_and_record(rop.SETFIELD_GC, descr, vbox, fieldbox) - i = vinfo.num_static_extra_boxes - virtualizable = vinfo.unwrap_virtualizable_box(vbox) - for k in range(vinfo.num_arrays): - descr = vinfo.array_field_descrs[k] - abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox) - descr = vinfo.array_descrs[k] - for j in range(vinfo.get_array_length(virtualizable, k)): - itembox = self.virtualizable_boxes[i] - i += 1 - self.execute_and_record(rop.SETARRAYITEM_GC, descr, - abox, ConstInt(j), itembox) - assert i + 1 == len(self.virtualizable_boxes) - def replace_box(self, oldbox, newbox): assert isinstance(oldbox, Box) for frame in self.framestack: From noreply at buildbot.pypy.org Tue Mar 26 02:09:26 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 26 Mar 2013 02:09:26 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default (phew) Message-ID: <20130326010926.6C9151C2F70@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62779:c769fa58fbef Date: 2013-03-25 18:08 -0700 http://bitbucket.org/pypy/pypy/changeset/c769fa58fbef/ Log: merge default (phew) diff too long, truncating to 2000 out of 23592 lines diff --git a/lib-python/2/collections.py b/lib-python/2/collections.py --- a/lib-python/2/collections.py +++ b/lib-python/2/collections.py @@ -12,6 +12,11 @@ import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from itertools import imap as _imap +try: + from __pypy__ import newdict +except ImportError: + assert '__pypy__' not in _sys.builtin_module_names + newdict = lambda _ : {} try: from thread import get_ident as _get_ident @@ -326,8 +331,11 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = newdict('module') + namespace['OrderedDict'] = OrderedDict + namespace['_property'] = property + namespace['_tuple'] = tuple + namespace['__name__'] = 'namedtuple_%s' % typename try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -34,8 +34,6 @@ import struct import re -from __pypy__.builders import StringBuilder - __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", "Unpickler", "dump", "dumps", "load", "loads"] @@ -1411,24 +1409,11 @@ except ImportError: from StringIO import StringIO - -class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - - def getvalue(self): - return self.builder.build() - - def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib-python/2/sre_parse.py b/lib-python/2/sre_parse.py --- a/lib-python/2/sre_parse.py +++ b/lib-python/2/sre_parse.py @@ -19,8 +19,8 @@ try: from __pypy__ import newdict except ImportError: - def newdict(tp): - return {} + assert '__pypy__' not in sys.builtin_module_names + newdict = lambda _ : {} SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.__self__ is self.instance): res = MethodType(res.__func__, self.proxyobj, res.__self__.__class__) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -33,7 +33,7 @@ modname = os.path.basename(modname) try: checkmodule(modname) - except Exception, e: + except Exception: import traceback, pdb traceback.print_exc() pdb.post_mortem(sys.exc_info()[2]) diff --git a/pypy/bin/dotviewer.py b/pypy/bin/dotviewer.py --- a/pypy/bin/dotviewer.py +++ b/pypy/bin/dotviewer.py @@ -4,6 +4,7 @@ Run with no arguments for help. """ +import os import sys sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))) from dotviewer.dotviewer import main diff --git a/pypy/bin/pyinteractive.py b/pypy/bin/pyinteractive.py --- a/pypy/bin/pyinteractive.py +++ b/pypy/bin/pyinteractive.py @@ -6,14 +6,13 @@ """ -import os, sys +import os +import sys import time sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) -import pypy from pypy.tool import option -from optparse import make_option from pypy.interpreter import main, interactive, error, gateway from rpython.config.config import OptionDescription, BoolOption, StrOption from rpython.config.config import Config, to_optparse diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -61,7 +61,6 @@ def main(): - import sys try: kwds = parse_options(sys.argv[1:]) except AssertionError: diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -188,11 +188,6 @@ BoolOption("withtproxy", "support transparent proxies", default=True), - BoolOption("withsmallint", "use tagged integers", - default=False, - requires=[("objspace.std.withprebuiltint", False), - ("translation.taggedpointers", True)]), - BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -203,9 +198,7 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False, - requires=[("objspace.std.withsmallint", False)]), - # ^^^ because of missing delegate_xx2yy + default=False), BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/config/test/test_makerestdoc.py b/pypy/config/test/test_makerestdoc.py --- a/pypy/config/test/test_makerestdoc.py +++ b/pypy/config/test/test_makerestdoc.py @@ -1,6 +1,7 @@ +import py + from rpython.config.config import * from pypy.config.makerestdoc import make_cmdline_overview - from pypy.tool.rest.rest import process as restcheck tempdir = py.test.ensuretemp('config') @@ -19,7 +20,7 @@ def generate_html(descr): config = Config(descr) txt = descr.make_rest_doc().text() - + result = {"": txt} for path in config.getpaths(include_groups=True): subconf, step = config._cfgimpl_get_home_by_path(path) diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -107,8 +107,7 @@ There is a small-to-medium demo showing the translator and the annotator:: - cd demo - ../rpython/translator/goal/translate.py --view --annotate bpnn.py + python bin/rpython --view --annotate translator/goal/bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,7 +118,7 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../rpython/translator/goal/translate.py bpnn.py + python bin/rpython translator/goal/bpnn.py Translating Full Programs @@ -129,8 +128,7 @@ ``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd rpython/translator/goal - python translate.py targetrpystonedalone + python bin/rpython translator/goal/targetrpystonedalone This will produce the executable "targetrpystonedalone-c". @@ -138,6 +136,17 @@ interpreter`_. There is also an FAQ about how to set up this process for `your own interpreters`_. +There are several environment variables you can find useful while playing with the RPython: + +``PYPY_USESSION_DIR`` + RPython uses temporary session directories to store files that are generated during the + translation process(e.g., translated C files). ``PYPY_USESSION_DIR`` serves as a base directory for these session + dirs. The default value for this variable is the system's temporary dir. + +``PYPY_USESSION_KEEP`` + By default RPython keeps only the last ``PYPY_USESSION_KEEP`` (defaults to 3) session dirs inside ``PYPY_USESSION_DIR``. + Increase this value if you want to preserve C files longer (useful when producing lots of lldebug builds). + .. _`your own interpreters`: faq.html#how-do-i-compile-my-own-interpreters .. _`start reading sources`: diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -13,7 +13,7 @@ implemented. It's helpful to have an understanding of how the `RPython translation toolchain`_ works before digging into the sources. -Almost all JIT specific code is found in pypy/jit subdirectories. Translation +Almost all JIT specific code is found in rpython/jit subdirectories. Translation time code is in the codewriter directory. The metainterp directory holds platform independent code including the the tracer and the optimizer. Code in the backend directory is responsible for generating machine code. @@ -175,7 +175,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf +.. __: https://bitbucket.org/pypy/extradoc/src/tip/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py --- a/pypy/doc/test/test_whatsnew.py +++ b/pypy/doc/test/test_whatsnew.py @@ -1,6 +1,6 @@ import py import pypy -from commands import getoutput +from commands import getoutput, getstatusoutput ROOT = py.path.local(pypy.__file__).dirpath().dirpath() @@ -20,6 +20,9 @@ return startrev, branches def get_merged_branches(path, startrev, endrev): + if getstatusoutput('hg root')[0]: + py.test.skip('no Mercurial repo') + # X = take all the merges which are descendants of startrev and are on default # revset = all the parents of X which are not on default # ===> 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 @@ -20,16 +20,22 @@ .. branch: numpypy-longdouble Long double support for numpypy + .. branch: numpypy-disable-longdouble Since r_longdouble support is missing, disable all longdouble and derivative dtypes using ENABLED_LONG_DOUBLE = False + .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality + .. branch: indexing-by-array Adds indexing by scalar, adds int conversion from scalar and single element array, fixes compress, indexing by an array with a smaller shape and the indexed object. +.. branch: str-dtype-improvement +Allow concatenation of str and numeric arrays + .. branch: signatures Improved RPython typing @@ -48,6 +54,7 @@ .. branch: fix-version-tool .. branch: popen2-removal .. branch: pickle-dumps +.. branch: scalar_get_set .. branch: release-2.0-beta1 @@ -99,3 +106,7 @@ .. branch: pycon2013-doc-fixes Documentation fixes after going through the docs at PyCon 2013 sprint. + +.. branch: extregistry-refactor + +.. branch: remove-list-smm diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.tool.ann_override import PyPyAnnotatorPolicy -from rpython.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE +from rpython.config.config import to_optparse, make_dict, SUPPRESS_USAGE from rpython.config.config import ConflictConfigError from pypy.tool.option import make_objspace from pypy.conftest import pypydir diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -664,7 +664,6 @@ # start a prompt if requested if inspect_requested(): - inteactive = False try: from _pypy_interact import interactive_console success = run_toplevel(interactive_console, mainmodule, quiet) diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1204,7 +1204,7 @@ assert space.eq_w(get_num("-0"), space.wrap(0)) assert space.eq_w(get_num("-0xAAAAAA"), space.wrap(-0xAAAAAAL)) n = get_num(str(-sys.maxint - 1)) - assert space.is_true(space.isinstance(n, space.w_int)) + assert space.isinstance_w(n, space.w_int) for num in ("0o53", "0O53", "0o0000053", "0O00053"): assert space.eq_w(get_num(num), space.wrap(053)) for num in ("0b00101", "0B00101", "0b101", "0B101"): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -549,7 +549,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -566,7 +566,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -632,7 +632,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,27 +1,30 @@ import sys +from rpython.rlib.cache import Cache +from rpython.tool.uid import HUGEVAL_BYTES +from rpython.rlib import jit, types +from rpython.rlib.debug import make_sure_not_resized +from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, + compute_unique_id) +from rpython.rlib.signature import signature +from rpython.rlib.rarithmetic import r_uint + from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, UserDelAction, FrameTraceAction) from pypy.interpreter.error import (OperationError, operationerrfmt, new_exception_class, typed_unwrap_error_msg) from pypy.interpreter.argument import Arguments from pypy.interpreter.miscutils import ThreadLocals -from rpython.rlib.cache import Cache -from rpython.tool.uid import HUGEVAL_BYTES -from rpython.rlib import jit -from rpython.rlib.debug import make_sure_not_resized -from rpython.rlib.objectmodel import we_are_translated, newlist_hint,\ - compute_unique_id -from rpython.rlib.rarithmetic import r_uint -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) -unpackiterable_driver = jit.JitDriver(name = 'unpackiterable', - greens = ['tp'], - reds = ['items', 'w_iterator']) +unpackiterable_driver = jit.JitDriver(name='unpackiterable', + greens=['tp'], + reds=['items', 'w_iterator']) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -212,6 +215,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def float_w(self, space): + raise OperationError(space.w_TypeError, + typed_unwrap_error_msg(space, "float", self)) + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -220,16 +227,26 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def int(self, space): + w_impl = space.lookup(self, '__int__') + if w_impl is None: + typename = space.type(self).getname(space) + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for int(): '%s'", + typename) + w_result = space.get_and_call_function(w_impl, self) -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True + if (space.isinstance_w(w_result, space.w_int) or + space.isinstance_w(w_result, space.w_long)): + return w_result + typename = space.type(w_result).getname(space) + msg = "__int__ returned non-int (type '%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) def __spacebind__(self, space): return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -264,18 +281,13 @@ def __init__(self, space): Cache.__init__(self) self.space = space + def _build(self, key): - val = self.space.enter_cache_building_mode() - try: - return self.build(key) - finally: - self.space.leave_cache_building_mode(val) + return self.build(key) + def _ready(self, result): - val = self.space.enter_cache_building_mode() - try: - return self.ready(result) - finally: - self.space.leave_cache_building_mode(val) + return self.ready(result) + def ready(self, result): pass @@ -340,10 +352,8 @@ if e.match(self, self.w_KeyError): continue raise - modname = self.str_w(w_modname) - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -352,9 +362,8 @@ self.sys.flush_std_files(self) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -426,14 +435,12 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): """NOT_RPYTHON""" - from pypy.tool.lib_pypy import LIB_PYPY try: return self._builtinmodule_list except AttributeError: @@ -580,11 +587,6 @@ """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" - def enter_cache_building_mode(self): - "hook for the flow object space" - def leave_cache_building_mode(self, val): - "hook for the flow object space" - @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." @@ -713,6 +715,7 @@ raise return None + @signature(types.any(), types.bool(), returns=types.instance(W_Root)) def newbool(self, b): if b: return self.w_True @@ -736,52 +739,28 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): - """ - This method should NOT be called unless you are really sure about - it. It is used inside the implementation of end_finally() in - pyopcode.py, and it's there so that it can be overridden by the - FlowObjSpace. - """ - if self.is_w(w_obj, self.w_None): - return True - obj = self.interpclass_w(w_obj) - return isinstance(obj, RequiredClass) - def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable into a real (interpreter-level) list. @@ -945,7 +924,7 @@ """Checks if the given exception type matches 'w_check_class'.""" if self.is_w(w_exc_type, w_check_class): return True # fast path - if self.is_true(self.isinstance(w_check_class, self.w_tuple)): + if self.isinstance_w(w_check_class, self.w_tuple): for w_t in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_t): return True @@ -1041,9 +1020,6 @@ def issequence_w(self, w_obj): return (self.findattr(w_obj, self.wrap("__getitem__")) is not None) - def isinstance_w(self, w_obj, w_type): - return self.is_true(self.isinstance(w_obj, w_type)) - # The code below only works # for the simple case (new-style instance). # These methods are patched with the full logic by the builtins @@ -1055,11 +1031,11 @@ def abstract_isinstance_w(self, w_obj, w_cls): # Equivalent to 'isinstance(obj, cls)'. - return self.is_true(self.isinstance(w_obj, w_cls)) + return self.isinstance_w(w_obj, w_cls) def abstract_isclass_w(self, w_obj): # Equivalent to 'isinstance(obj, type)'. - return self.is_true(self.isinstance(w_obj, self.w_type)) + return self.isinstance_w(w_obj, self.w_type) def abstract_getclass(self, w_obj): # Equivalent to 'obj.__class__'. @@ -1096,7 +1072,7 @@ expression = compiler.compile(expression, '?', 'eval', 0, hidden_applevel=hidden_applevel) else: - raise TypeError, 'space.eval(): expected a string, code or PyCode object' + raise TypeError('space.eval(): expected a string, code or PyCode object') return expression.exec_code(self, w_globals, w_locals) def exec_(self, statement, w_globals, w_locals, hidden_applevel=False, @@ -1110,7 +1086,7 @@ statement = compiler.compile(statement, filename, 'exec', 0, hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): - raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') if not self.is_true(self.contains(w_globals, w_key)): self.setitem(w_globals, w_key, self.wrap(self.builtin)) @@ -1166,7 +1142,7 @@ -> (index, 0, 0) or (start, stop, step) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) @@ -1186,7 +1162,7 @@ -> (index, 0, 0, 1) or (start, stop, step, slice_length) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step, length = w_index_or_slice.indices4(self, @@ -1355,15 +1331,21 @@ def int_w(self, w_obj): return w_obj.int_w(self) + def int(self, w_obj): + return w_obj.int(self) + def uint_w(self, w_obj): return w_obj.uint_w(self) def bigint_w(self, w_obj): return w_obj.bigint_w(self) + def float_w(self, w_obj): + return w_obj.float_w(self) + def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. - if not self.is_true(self.isinstance(w_obj, self.w_str)): + if not self.isinstance_w(w_obj, self.w_str): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) return self.str_w(w_obj) @@ -1383,7 +1365,7 @@ def realunicode_w(self, w_obj): # Like unicode_w, but only works if w_obj is really of type # 'unicode'. - if not self.is_true(self.isinstance(w_obj, self.w_unicode)): + if not self.isinstance_w(w_obj, self.w_unicode): raise OperationError(self.w_TypeError, self.wrap('argument must be a unicode')) return self.unicode_w(w_obj) @@ -1413,7 +1395,7 @@ # This is all interface for gateway.py. def gateway_int_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.int_w(self.int(w_obj)) @@ -1422,19 +1404,19 @@ return self.float_w(self.float(w_obj)) def gateway_r_longlong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_longlong_w(self.int(w_obj)) def gateway_r_uint_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.uint_w(self.int(w_obj)) def gateway_r_ulonglong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_ulonglong_w(self.int(w_obj)) @@ -1549,23 +1531,28 @@ space.exec_(str(source), w_glob, w_glob) return space.getitem(w_glob, space.wrap('anonymous')) + class DummyLock(object): def acquire(self, flag): return True + def release(self): pass + def _freeze_(self): return True + def __enter__(self): pass + def __exit__(self, *args): pass dummy_lock = DummyLock() -## Table describing the regular part of the interface of object spaces, -## namely all methods which only take w_ arguments and return a w_ result -## (if any). Note: keep in sync with rpython.flowspace.operation.Table. +# Table describing the regular part of the interface of object spaces, +# namely all methods which only take w_ arguments and return a w_ result +# (if any). ObjSpace.MethodTable = [ # method name # symbol # number of arguments # special method name(s) @@ -1589,7 +1576,7 @@ ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__bool__']), - ('abs' , 'abs', 1, ['__abs__']), + ('abs', 'abs', 1, ['__abs__']), ('ord', 'ord', 1, []), ('invert', '~', 1, ['__invert__']), ('add', '+', 2, ['__add__', '__radd__']), @@ -1637,12 +1624,12 @@ ('delete', 'delete', 2, ['__delete__']), ('userdel', 'del', 1, ['__del__']), ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py - ] +] ObjSpace.BuiltinModuleTable = [ 'builtins', 'sys', - ] +] ObjSpace.ConstantTable = [ 'None', @@ -1650,7 +1637,7 @@ 'True', 'Ellipsis', 'NotImplemented', - ] +] ObjSpace.ExceptionTable = [ 'ArithmeticError', @@ -1692,7 +1679,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', - ] +] if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] @@ -1705,7 +1692,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1722,7 +1708,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', @@ -1732,4 +1717,4 @@ 'newslice', 'call_args', 'marshal_w', - ] +] diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp @@ -145,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -209,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/callbench/bltn04.py b/pypy/interpreter/callbench/bltn04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn04.py +++ /dev/null @@ -1,40 +0,0 @@ -from sup import run - -def w(N, start): - c = chr - - start() - i = 0 - while i < N: - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - c(65) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltn_instantiate.py b/pypy/interpreter/callbench/bltn_instantiate.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltn_instantiate.py +++ /dev/null @@ -1,22 +0,0 @@ -from sup import run - -def w(N, start): - o = object - start() - i = 0 - while i < N: - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - o() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna1.py b/pypy/interpreter/callbench/bltna1.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna1.py +++ /dev/null @@ -1,28 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - while i < N: - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - l.__init__() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bltna2.py b/pypy/interpreter/callbench/bltna2.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bltna2.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - l = [] - start() - i = 0 - z = l.__init__ - while i < N: - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - z() - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bm14.py b/pypy/interpreter/callbench/bm14.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bm14.py +++ /dev/null @@ -1,51 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f0(self): - pass - def f1(self, a): - pass - def f2(self, a, b): - pass - def f3(self, a, b, c): - pass - def f4(self, a, b, c, d): - pass - - a = A() - f0 = a.f0 - f1 = a.f1 - f2 = a.f2 - f3 = a.f3 - f4 = a.f4 - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f1(1) - f2(1, 2) - f2(1, 2) - f2(1, 2) - f3(1, 2, 3) - f3(1, 2, 3) - f4(1, 2, 3, 4) - - f0() - f0() - f0() - f1(1) - f1(1) - f1(1) - f2(1, 2) - - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmabvararg.py b/pypy/interpreter/callbench/bmabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmabvararg.py +++ /dev/null @@ -1,29 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f(self, a, b, *args): - pass - - a = A() - f = a.f - z = (3, 4, 5) - - start() - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/bmfilter.py b/pypy/interpreter/callbench/bmfilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmfilter.py +++ /dev/null @@ -1,20 +0,0 @@ -from sup import run - -def w(N, start): - x = range(50) - class A(object): - def f1(self, a): - return False - - x = range(50) - a = A() - f1 = a.f1 - flt = filter - - start() - i = 0 - while i < N: - flt(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/bmmore.py b/pypy/interpreter/callbench/bmmore.py deleted file mode 100644 --- a/pypy/interpreter/callbench/bmmore.py +++ /dev/null @@ -1,30 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def f4(self, a, b, c, d): - pass - def f5(self, a, b, c, d, e): - pass - a = A() - f4 = a.f4 - f5 = a.f5 - - start() - i = 0 - while i < N: - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - f5(1, 2, 3, 4, 5) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/compare.py b/pypy/interpreter/callbench/compare.py deleted file mode 100644 --- a/pypy/interpreter/callbench/compare.py +++ /dev/null @@ -1,22 +0,0 @@ -# compare.py - -import sys - -def main(cur, ref): - cur = open(cur, 'rU') - ref = open(ref, 'rU') - try: - while True: - cur_line = cur.next() - ref_line = ref.next() - cur_name, cur_t = cur_line.split() - ref_name, ref_t = ref_line.split() - assert cur_name == ref_name - cur_t = float(cur_t) - ref_t = float(ref_t) - print "%-16s %.06g (x%.02f)" % (cur_name, cur_t, cur_t/ref_t) - except StopIteration: - pass - -if __name__ == '__main__': - main(sys.argv[1], sys.argv[2]) diff --git a/pypy/interpreter/callbench/f04.py b/pypy/interpreter/callbench/f04.py deleted file mode 100644 --- a/pypy/interpreter/callbench/f04.py +++ /dev/null @@ -1,39 +0,0 @@ -from sup import run - -def w(N, start): - def f0(): - pass - def f1(a): - pass - def f2(a, b): - pass - def f3(a, b, c): - pass - def f4(a, b, c, d): - pass - def f5(a, b, c, d, e): - pass - - start() - i = 0 - while i < N: - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - f5(1, 2, 3, 4, 5) - f0() - f0() - f0() - f1(1) - f1(1) - f2(1, 2) - f3(1, 2, 3) - f4(1, 2, 3, 4) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/fabvararg.py b/pypy/interpreter/callbench/fabvararg.py deleted file mode 100644 --- a/pypy/interpreter/callbench/fabvararg.py +++ /dev/null @@ -1,26 +0,0 @@ -from sup import run - -def w(N, start): - def f(a, b, *args): - pass - - z = (3, 4, 5) - start() - - i = 0 - while i < N: - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - f(1, 2, *z) - i+=1 - -run(w, 1000) diff --git a/pypy/interpreter/callbench/ffilter.py b/pypy/interpreter/callbench/ffilter.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffilter.py +++ /dev/null @@ -1,14 +0,0 @@ -from sup import run - -def w(N, start): - def f1(a): - return False - x = range(50) - - start() - i = 0 - while i < N: - filter(f1, x) - i+=1 - -run(w, 200) diff --git a/pypy/interpreter/callbench/ffunccall.py b/pypy/interpreter/callbench/ffunccall.py deleted file mode 100644 --- a/pypy/interpreter/callbench/ffunccall.py +++ /dev/null @@ -1,36 +0,0 @@ -from sup import run - -def w(N, start): - class A(object): - def foo(self, x): - pass - - __add__ = foo - From noreply at buildbot.pypy.org Tue Mar 26 02:11:57 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 26 Mar 2013 02:11:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: kill the rest of our Wrappables Message-ID: <20130326011157.B5B081C2F79@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62780:af69d35c9743 Date: 2013-03-25 18:11 -0700 http://bitbucket.org/pypy/pypy/changeset/af69d35c9743/ Log: kill the rest of our Wrappables diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -4,7 +4,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import GetSetProperty, make_weakref_descr, TypeDef -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.model import W_Object from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stdtypedef import SMM, StdTypeDef @@ -177,7 +177,7 @@ return self.array._charbuf_start() -class ArrayIterator(Wrappable): +class ArrayIterator(W_Root): def __init__(self, array): self.index = 0 self.array = array diff --git a/pypy/module/cpyext/classobject.py b/pypy/module/cpyext/classobject.py --- a/pypy/module/cpyext/classobject.py +++ b/pypy/module/cpyext/classobject.py @@ -1,13 +1,13 @@ from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL from pypy.module.cpyext.pyobject import PyObject -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.function import Method from pypy.interpreter.typedef import TypeDef, interp_attrproperty_w from pypy.interpreter.gateway import interp2app -class InstanceMethod(Wrappable): +class InstanceMethod(W_Root): """The instancemethod facade.""" _immutable_fields_ = ['w_function'] diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -156,7 +156,7 @@ return space.wrap(Lock(space)) -class W_RLock(Wrappable): +class W_RLock(W_Root): def __init__(self, space): self.rlock_count = 0 self.rlock_owner = 0 From noreply at buildbot.pypy.org Tue Mar 26 02:11:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 26 Mar 2013 02:11:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix breakage from default merge Message-ID: <20130326011158.F38A61C2F79@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62781:135678f7f339 Date: 2013-03-25 18:11 -0700 http://bitbucket.org/pypy/pypy/changeset/135678f7f339/ Log: fix breakage from default merge diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py --- a/pypy/module/__builtin__/interp_memoryview.py +++ b/pypy/module/__builtin__/interp_memoryview.py @@ -20,7 +20,7 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): if self.buf is None: - return space.wrap(getattr(operator, name)(self, other)) + return space.wrap(getattr(operator, name)(self, w_other)) if isinstance(w_other, W_MemoryView): # xxx not the most efficient implementation str1 = self.as_str() From noreply at buildbot.pypy.org Tue Mar 26 02:12:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 02:12:49 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: rpython fixes Message-ID: <20130326011249.BC37A1C2F79@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62782:e848a55243cb Date: 2013-03-25 18:12 -0700 http://bitbucket.org/pypy/pypy/changeset/e848a55243cb/ Log: rpython fixes 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 @@ -566,10 +566,6 @@ def bh_read_timestamp(self): return read_timestamp() - def bh_force_virtualizable(self, v, descr): - vinfo = descr.vinfo - vinfo.clear_vable_token(v) - def store_fail_descr(self, deadframe, descr): pass # I *think* diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py --- a/rpython/jit/backend/llsupport/descr.py +++ b/rpython/jit/backend/llsupport/descr.py @@ -76,7 +76,13 @@ FLAG_STRUCT = 'X' FLAG_VOID = 'V' -class FieldDescr(AbstractDescr): +class ArrayOrFieldDescr(AbstractDescr): + vinfo = None + + def get_vinfo(self): + return self.vinfo + +class FieldDescr(ArrayOrFieldDescr): name = '' offset = 0 # help translation field_size = 0 @@ -150,12 +156,13 @@ # ____________________________________________________________ # ArrayDescrs -class ArrayDescr(AbstractDescr): +class ArrayDescr(ArrayOrFieldDescr): tid = 0 basesize = 0 # workaround for the annotator itemsize = 0 lendescr = None flag = '\x00' + vinfo = None def __init__(self, basesize, itemsize, lendescr, flag): self.basesize = basesize 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 @@ -6,7 +6,7 @@ total_compiled_loops = 0 total_compiled_bridges = 0 total_freed_loops = 0 - total_freed_bridges = 0 + total_freed_bridges = 0 # for heaptracker # _all_size_descrs_with_vtable = None @@ -284,6 +284,9 @@ def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length): raise NotImplementedError + def bh_force_virtualizable(self, v, descr): + vinfo = descr.get_vinfo() + vinfo.clear_vable_token(v) class CompiledLoopToken(object): asmmemmgr_blocks = None 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 @@ -873,7 +873,9 @@ def consider_force_virtualizable(self, op): # just do a call for now - vinfo = op.getdescr().vinfo + vinfo = op.getdescr().get_vinfo() + if vinfo is None: + return # for tests calldescr = vinfo.clear_vable_descr assert isinstance(calldescr, CallDescr) fval = rffi.cast(lltype.Signed, vinfo.clear_vable_ptr) 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 @@ -160,7 +160,7 @@ EffectInfo.MOST_GENERAL = EffectInfo(None, None, None, None, EffectInfo.EF_RANDOM_EFFECTS, can_invalidate=True) -EffectInfo.LEAST_GENERAL = EffectInfo({}, {}, {}, {}, +EffectInfo.LEAST_GENERAL = EffectInfo([], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE, can_invalidate=False) 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 @@ -163,6 +163,8 @@ descr_ptr = cpu.ts.cast_to_baseclass(descr_gcref) return cast_base_ptr_to_instance(AbstractDescr, descr_ptr) + def get_vinfo(self): + raise NotImplementedError class AbstractFailDescr(AbstractDescr): index = -1 @@ -175,7 +177,7 @@ class BasicFinalDescr(AbstractFailDescr): final_descr = True - + def __init__(self, identifier=None): self.identifier = identifier # for testing @@ -730,7 +732,7 @@ def repr_of_descr(self): return 'TargetToken(%d)' % compute_unique_id(self) - + class TreeLoop(object): inputargs = None operations = None @@ -827,7 +829,7 @@ seen = dict.fromkeys(inputargs) assert len(seen) == len(inputargs), ( "duplicate Box in the LABEL arguments") - + assert operations[-1].is_final() if operations[-1].getopnum() == rop.JUMP: target = operations[-1].getdescr() @@ -836,7 +838,7 @@ def dump(self): # RPython-friendly - print '%r: inputargs =' % self, self._dump_args(self.inputargs) + print '%r: inputargs =' % self, self._dump_args(self.inputargs) for op in self.operations: args = op.getarglist() print '\t', op.getopname(), self._dump_args(args), \ @@ -952,7 +954,7 @@ def add_jitcell_token(self, token): assert isinstance(token, JitCellToken) self.jitcell_token_wrefs.append(weakref.ref(token)) - + def set_history(self, history): self.operations = history.operations @@ -1045,7 +1047,7 @@ opname = op.getopname() insns[opname] = insns.get(opname, 0) + 1 return self._check_insns(insns, expected, check) - + def check_loops(self, expected=None, everywhere=False, **check): insns = {} for loop in self.get_all_loops(): @@ -1068,7 +1070,7 @@ print import pdb; pdb.set_trace() return - + for insn, expected_count in check.items(): getattr(rop, insn.upper()) # fails if 'rop.INSN' does not exist found = insns.get(insn, 0) diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -711,7 +711,7 @@ if self.metainterp.heapcache.is_nonstandard_virtualizable(box): return True vinfo = self.metainterp.jitdriver_sd.virtualizable_info - if vinfo is not fielddescr.vinfo: + if vinfo is not fielddescr.get_vinfo(): self.metainterp.heapcache.nonstandard_virtualizables_now_known(box) return True eqbox = self.metainterp.execute_and_record(rop.PTR_EQ, None, diff --git a/rpython/jit/metainterp/test/test_virtualizable.py b/rpython/jit/metainterp/test/test_virtualizable.py --- a/rpython/jit/metainterp/test/test_virtualizable.py +++ b/rpython/jit/metainterp/test/test_virtualizable.py @@ -139,11 +139,13 @@ n -= 1 def f(n): xy = self.setup() + promote_virtualizable(xy, 'inst_x') xy.inst_x = 10000 m = 10 while m > 0: g(xy, n) m -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [18]) assert res == 10180 From noreply at buildbot.pypy.org Tue Mar 26 02:32:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 02:32:53 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: I think a correct fix, Explicit tests still fail though, for reasons unknown Message-ID: <20130326013253.204C51C2F79@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62783:b5bf8bd7c088 Date: 2013-03-25 18:32 -0700 http://bitbucket.org/pypy/pypy/changeset/b5bf8bd7c088/ Log: I think a correct fix, Explicit tests still fail though, for reasons unknown diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2177,6 +2177,7 @@ def compile_done_with_this_frame(self, exitbox): # temporarily put a JUMP to a pseudo-loop + self.store_token_in_vable() sd = self.staticdata result_type = self.jitdriver_sd.result_type if result_type == history.VOID: @@ -2202,7 +2203,21 @@ if target_token is not token: compile.giveup() + def store_token_in_vable(self): + vinfo = self.jitdriver_sd.virtualizable_info + if vinfo is None: + return + vbox = self.virtualizable_boxes[-1] + force_token_box = history.BoxPtr() + # in case the force_token has not been recorded, record it here + # to make sure we know the virtualizable can be broken. However, the + # contents of the virtualizable should be generally correct + self.history.record(rop.FORCE_TOKEN, [], force_token_box) + self.history.record(rop.SETFIELD_GC, [vbox, force_token_box], + None, descr=vinfo.vable_token_descr) + def compile_exit_frame_with_exception(self, valuebox): + self.store_token_in_vable() sd = self.staticdata token = sd.loop_tokens_exit_frame_with_exception_ref[0].finishdescr self.history.record(rop.FINISH, [valuebox], None, descr=token) From noreply at buildbot.pypy.org Tue Mar 26 03:20:29 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 03:20:29 +0100 (CET) Subject: [pypy-commit] pypy kill-gen-store-back-in: try to shuffle things around Message-ID: <20130326022029.2ED361C2F70@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-gen-store-back-in Changeset: r62784:0ac13cef895b Date: 2013-03-25 19:20 -0700 http://bitbucket.org/pypy/pypy/changeset/0ac13cef895b/ Log: try to shuffle things around diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -179,7 +179,6 @@ executioncontext.return_trace(self, w_exitvalue) # clean up the exception, might be useful for not # allocating exception objects in some cases - self.last_exception = None got_exception = False finally: executioncontext.leave(self, w_exitvalue, got_exception) diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -74,6 +74,7 @@ next_instr = self.handle_bytecode(co_code, next_instr, ec) is_being_profiled = self.is_being_profiled except ExitFrame: + self.last_exception = None return self.popvalue() def jump_absolute(self, jumpto, ec): From noreply at buildbot.pypy.org Tue Mar 26 04:29:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 04:29:33 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130326032933.A0BAF1C3036@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62786:3e126f37c6e9 Date: 2013-03-25 20:29 -0700 http://bitbucket.org/pypy/pypy/changeset/3e126f37c6e9/ Log: merge diff --git a/rpython/jit/backend/test/test_zll_stress_0.py b/rpython/jit/backend/test/test_zll_stress_0.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_0.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_0(): + zll_stress.do_test_stress(0) diff --git a/rpython/jit/backend/test/test_zll_stress_1.py b/rpython/jit/backend/test/test_zll_stress_1.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_1.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_1(): + zll_stress.do_test_stress(1) diff --git a/rpython/jit/backend/test/test_zll_stress_2.py b/rpython/jit/backend/test/test_zll_stress_2.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_2.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_2(): + zll_stress.do_test_stress(2) diff --git a/rpython/jit/backend/test/test_zll_stress_3.py b/rpython/jit/backend/test/test_zll_stress_3.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/test/test_zll_stress_3.py @@ -0,0 +1,4 @@ +from rpython.jit.backend.test import zll_stress + +def test_stress_3(): + zll_stress.do_test_stress(3) diff --git a/rpython/jit/backend/test/test_zll_stress.py b/rpython/jit/backend/test/zll_stress.py rename from rpython/jit/backend/test/test_zll_stress.py rename to rpython/jit/backend/test/zll_stress.py --- a/rpython/jit/backend/test/test_zll_stress.py +++ b/rpython/jit/backend/test/zll_stress.py @@ -5,14 +5,18 @@ CPU = getcpuclass() -iterations = 1000 +total_iterations = 1000 if platform.machine().startswith('arm'): - iterations = 100 + total_iterations = 100 +pieces = 4 +per_piece = total_iterations / pieces -def test_stress(): + +def do_test_stress(piece): cpu = CPU(None, None) cpu.setup_once() r = Random() - for i in range(iterations): - check_random_function(cpu, LLtypeOperationBuilder, r, i, iterations) + r.jumpahead(piece*per_piece) + for i in range(piece*per_piece, (piece+1)*per_piece): + check_random_function(cpu, LLtypeOperationBuilder, r, i, total_iterations) From noreply at buildbot.pypy.org Tue Mar 26 04:29:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 04:29:32 +0100 (CET) Subject: [pypy-commit] pypy default: it turns out my laptop has 3M of cache and the default of 4M is a bad idea Message-ID: <20130326032932.44E331C2F7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62785:d552e0f54a66 Date: 2013-03-25 20:28 -0700 http://bitbucket.org/pypy/pypy/changeset/d552e0f54a66/ Log: it turns out my laptop has 3M of cache and the default of 4M is a bad idea diff --git a/rpython/memory/gc/env.py b/rpython/memory/gc/env.py --- a/rpython/memory/gc/env.py +++ b/rpython/memory/gc/env.py @@ -270,7 +270,8 @@ def best_nursery_size_for_L2cache(L2cache): # Heuristically, the best nursery size to choose is about half # of the L2 cache. - if L2cache > 0: + if L2cache > 1024 * 1024: # we don't want to have nursery estimated + # on L2 when L3 is present return L2cache // 2 else: return NURSERY_SIZE_UNKNOWN_CACHE diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -348,7 +348,8 @@ # size (needed to handle mallocs just below 'large_objects') but # hacking at the current nursery position in collect_and_reserve(). if newsize <= 0: - newsize = 4*1024*1024 # fixed to 4MB by default + newsize = env.estimate_best_nursery_size() + # 4*1024*1024 # fixed to 4MB by default # (it was env.estimate_best_nursery_size()) if newsize <= 0: newsize = defaultsize @@ -624,7 +625,7 @@ """To call when nursery_free overflows nursery_top. First check if the nursery_top is the real top, otherwise we can just move the top of one cleanup and continue - + Do a minor collection, and possibly also a major collection, and finally reserve 'totalsize' bytes at the start of the now-empty nursery. From noreply at buildbot.pypy.org Tue Mar 26 04:33:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 04:33:30 +0100 (CET) Subject: [pypy-commit] pypy remove-array-smm: remove a few more Message-ID: <20130326033330.E9F671C3035@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: remove-array-smm Changeset: r62787:caac10446fa4 Date: 2013-03-25 20:33 -0700 http://bitbucket.org/pypy/pypy/changeset/caac10446fa4/ Log: remove a few more diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -51,11 +51,6 @@ return a - -array_extend = SMM('extend', 2) - -array_count = SMM('count', 2) -array_index = SMM('index', 2) array_reverse = SMM('reverse', 1) array_remove = SMM('remove', 2) array_pop = SMM('pop', 2, defaults=(-1,)) @@ -92,6 +87,27 @@ """ raise NotImplementedError + def descr_extend(self, space, w_x): + """ extend(array or iterable) + + Append items to the end of the array. + """ + self.extend(w_x) + + def descr_count(self, space, w_val): + """ count(x) + + Return number of occurrences of x in the array. + """ + raise NotImplementedError + + def descr_index(self, space, w_x): + """ index(x) + + Return index of first occurrence of x in the array. + """ + raise NotImplementedError + @staticmethod def register(typeorder): typeorder[W_ArrayBase] = [] @@ -104,6 +120,9 @@ typecode = GetSetProperty(descr_typecode), __weakref__ = make_weakref_descr(W_ArrayBase), append = interpindirect2app(W_ArrayBase.descr_append), + extend = interp2app(W_ArrayBase.descr_extend), + count = interpindirect2app(W_ArrayBase.descr_count), + index = interpindirect2app(W_ArrayBase.descr_index), ) W_ArrayBase.typedef.registermethods(globals()) @@ -357,6 +376,24 @@ self.setlen(self.len + 1) self.buffer[self.len - 1] = x + # List interface + def descr_count(self, space, w_val): + cnt = 0 + for i in range(self.len): + # XXX jitdriver + w_item = self.w_getitem(space, i) + if space.is_true(space.eq(w_item, w_val)): + cnt += 1 + return space.wrap(cnt) + + def descr_index(self, space, w_val): + for i in range(self.len): + w_item = self.w_getitem(space, i) + if space.is_true(space.eq(w_item, w_val)): + return space.wrap(i) + msg = 'array.index(x): x not in list' + raise OperationError(space.w_ValueError, space.wrap(msg)) + # Basic get/set/append/extend methods def len__Array(space, self): @@ -408,26 +445,6 @@ def setslice__Array_ANY_ANY_ANY(space, self, w_i, w_j, w_x): space.setitem(self, space.newslice(w_i, w_j, space.w_None), w_x) - def array_extend__Array_ANY(space, self, w_iterable): - self.extend(w_iterable) - - # List interface - def array_count__Array_ANY(space, self, w_val): - cnt = 0 - for i in range(self.len): - w_item = self.w_getitem(space, i) - if space.is_true(space.eq(w_item, w_val)): - cnt += 1 - return space.wrap(cnt) - - def array_index__Array_ANY(space, self, w_val): - for i in range(self.len): - w_item = self.w_getitem(space, i) - if space.is_true(space.eq(w_item, w_val)): - return space.wrap(i) - msg = 'array.index(x): x not in list' - raise OperationError(space.w_ValueError, space.wrap(msg)) - def array_reverse__Array(space, self): b = self.buffer for i in range(self.len / 2): @@ -448,7 +465,7 @@ return w_val def array_remove__Array_ANY(space, self, w_val): - w_idx = array_index__Array_ANY(space, self, w_val) + w_idx = self.descr_index(space, w_val) array_pop__Array_ANY(space, self, w_idx) def array_insert__Array_ANY_ANY(space, self, w_idx, w_val): From noreply at buildbot.pypy.org Tue Mar 26 04:44:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 04:44:38 +0100 (CET) Subject: [pypy-commit] pypy.org extradoc: add a security link Message-ID: <20130326034438.6FA641C2F7B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r380:3da0c3892bbf Date: 2013-03-25 20:44 -0700 http://bitbucket.org/pypy/pypy.org/changeset/3da0c3892bbf/ Log: add a security link diff --git a/contact.html b/contact.html --- a/contact.html +++ b/contact.html @@ -48,6 +48,7 @@
  • irc: #pypy on irc.freenode.net
  • mailing list: pypy-dev at python.org
  • +
  • for security related issues, non-public funding enquiries etc. please contact pypy@sfconservancy.org
  • the bug tracker
  • more on our dev site.
  • code on bitbucket.
  • diff --git a/py3donate.html b/py3donate.html --- a/py3donate.html +++ b/py3donate.html @@ -74,7 +74,7 @@ at the latest, we will try our best to make PyPy support Python 3 anyway. We however reserve the right to shift any unused funds to other PyPy activities when that date is reached. Of course, since the Conservancy is a -501©(3) charitable organization incorporated in NY, USA, all funds will, +501(c)(3) charitable organization incorporated in NY, USA, all funds will, regardless of their use, be spent in a way that benefits the general public, the advancement of Open Source and Free Software, and in particular the PyPy community and the PyPy codebase.

    diff --git a/source/contact.txt b/source/contact.txt --- a/source/contact.txt +++ b/source/contact.txt @@ -10,6 +10,8 @@ * mailing list: `pypy-dev at python.org`__ +* for security related issues, non-public funding enquiries etc. please contact pypy at sfconservancy.org + * the `bug tracker`_ * more on our `dev site`_. From noreply at buildbot.pypy.org Tue Mar 26 04:44:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 04:44:39 +0100 (CET) Subject: [pypy-commit] pypy.org extradoc: merge Message-ID: <20130326034439.BAD5A1C2F7B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r381:9a92cffaa8d4 Date: 2013-03-25 20:44 -0700 http://bitbucket.org/pypy/pypy.org/changeset/9a92cffaa8d4/ Log: merge diff --git a/archive.html b/archive.html --- a/archive.html +++ b/archive.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/compat.html b/compat.html --- a/compat.html +++ b/compat.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/contact.html b/contact.html --- a/contact.html +++ b/contact.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/download.html b/download.html --- a/download.html +++ b/download.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/features.html b/features.html --- a/features.html +++ b/features.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/howtohelp.html b/howtohelp.html --- a/howtohelp.html +++ b/howtohelp.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/index.html b/index.html --- a/index.html +++ b/index.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/numpydonate.html b/numpydonate.html --- a/numpydonate.html +++ b/numpydonate.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    @@ -65,7 +67,7 @@ at the latest, we will try our best to make PyPy support NumPy anyway. We however reserve the right to shift any unused funds to other PyPy activities when that date is reached. Of course, since the Conservancy is a -501(c)(3) charitable organization incorporated in NY, USA, all funds will, +501©(3) charitable organization incorporated in NY, USA, all funds will, regardless of their use, be spent in a way that benefits the general public, the advancement of Open Source and Free Software, and in particular the PyPy community and the PyPy codebase.

    diff --git a/people.html b/people.html --- a/people.html +++ b/people.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/performance.html b/performance.html --- a/performance.html +++ b/performance.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/py3donate.html b/py3donate.html --- a/py3donate.html +++ b/py3donate.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/source/_layouts/site.genshi b/source/_layouts/site.genshi --- a/source/_layouts/site.genshi +++ b/source/_layouts/site.genshi @@ -68,6 +68,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/sponsor.html b/sponsor.html --- a/sponsor.html +++ b/sponsor.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/success.html b/success.html --- a/success.html +++ b/success.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    diff --git a/tmdonate.html b/tmdonate.html --- a/tmdonate.html +++ b/tmdonate.html @@ -35,6 +35,8 @@
    Follow the conversation on Twitter
    Subscribe to the RSS Feed
    +
    From noreply at buildbot.pypy.org Tue Mar 26 04:47:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Mar 2013 04:47:42 +0100 (CET) Subject: [pypy-commit] pypy.org extradoc: try to fxi icons Message-ID: <20130326034742.389DF1C2F70@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r382:98e8ca696f20 Date: 2013-03-25 20:47 -0700 http://bitbucket.org/pypy/pypy.org/changeset/98e8ca696f20/ Log: try to fxi icons diff --git a/archive.html b/archive.html --- a/archive.html +++ b/archive.html @@ -32,9 +32,8 @@

All modules that are pure python in CPython of course work.

-

Python libraries known to work under PyPy (the list is not exhaustive):

+

Python libraries known to work under PyPy (the list is not exhaustive). +A community maintained compatibility wiki is hosted on bitbucket:

  • ctypes
  • django
  • diff --git a/source/compat.txt b/source/compat.txt --- a/source/compat.txt +++ b/source/compat.txt @@ -19,7 +19,9 @@ C extensions need to be recompiled for PyPy in order to work. Depending on your build system, it might work out of the box or will be slightly harder. -Standard library modules supported by PyPy, in alphabetical order: +Standard library modules supported by PyPy. Note that large parts of python +library are implemented in pure python, so they don't have to be listed +there. Please just check if it imports. If it imports, it should work. * ``__builtin__, __pypy__, _ast, _bisect, _codecs, _collections, _ffi, _hashlib, _io, _locale, _lsprof, _md5, _minimal_curses, _multiprocessing, _random, _rawffi, _sha, _socket, _sre, _ssl, _warnings, _weakref, _winreg, array, binascii, bz2, cStringIO, clr, cmath, cpyext, crypt, errno, exceptions, fcntl, gc, imp, itertools, marshal, math, mmap, operator, oracle, parser, posix, pyexpat, select, signal, struct, symbol, sys, termios, thread, time, token, unicodedata, zipimport, zlib`` @@ -29,7 +31,8 @@ All modules that are pure python in CPython of course work. -Python libraries known to work under PyPy (the list is not exhaustive): +Python libraries known to work under PyPy (the list is not exhaustive). +A community maintained `compatibility wiki`_ is hosted on bitbucket: * ctypes @@ -96,3 +99,5 @@ .. _`CPython C API`: http://docs.python.org/c-api/ .. _`standard library modules`: http://docs.python.org/library/ .. _`our dev site`: http://pypy.readthedocs.org/en/latest/cpython_differences.html +.. _`compatibility wiki`: https://bitbucket.org/pypy/compatibility/wiki/Home + From noreply at buildbot.pypy.org Wed Mar 27 00:31:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 27 Mar 2013 00:31:37 +0100 (CET) Subject: [pypy-commit] pypy default: another arm change after 55a5e932519e Message-ID: <20130326233137.D769C1C0A11@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62819:68e916a5fbd3 Date: 2013-03-26 19:31 -0400 http://bitbucket.org/pypy/pypy/changeset/68e916a5fbd3/ Log: another arm change after 55a5e932519e diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -115,7 +115,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", 'arm'], + ["auto", "x86", "x86-without-sse2", 'armv7'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], From noreply at buildbot.pypy.org Wed Mar 27 00:32:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 27 Mar 2013 00:32:19 +0100 (CET) Subject: [pypy-commit] buildbot default: another arm change after pypy commit 55a5e932519e Message-ID: <20130326233219.60AC31C0A11@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r764:611222104e92 Date: 2013-03-26 19:32 -0400 http://bitbucket.org/pypy/buildbot/changeset/611222104e92/ Log: another arm change after pypy commit 55a5e932519e diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -187,7 +187,7 @@ # ARM own test factories crosstranslationargs = ['--platform=arm', '--gcrootfinder=shadowstack'] -crosstranslationjitargs = ['--jit-backend=arm'] +crosstranslationjitargs = ['--jit-backend=armv7'] # this one needs a larger timeout due to how it is run pypyJitBackendOnlyOwnTestFactoryARM = pypybuilds.Own( cherrypick=':'.join(["jit/backend/arm", From noreply at buildbot.pypy.org Wed Mar 27 00:43:02 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 27 Mar 2013 00:43:02 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: allow const char* returns to be NULL (-> empty string) Message-ID: <20130326234302.92F2B1C0A11@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62820:c74ba167a532 Date: 2013-03-26 13:30 -0700 http://bitbucket.org/pypy/pypy/changeset/c74ba167a532/ Log: allow const char* returns to be NULL (-> empty string) diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py --- a/pypy/module/cppyy/executor.py +++ b/pypy/module/cppyy/executor.py @@ -133,8 +133,10 @@ def execute(self, space, cppmethod, cppthis, num_args, args): lresult = capi.c_call_l(cppmethod, cppthis, num_args, args) ccpresult = rffi.cast(rffi.CCHARP, lresult) - result = rffi.charp2str(ccpresult) # TODO: make it a choice to free - return space.wrap(result) + if ccpresult: + result = rffi.charp2str(ccpresult) # TODO: make it a choice to free + return space.wrap(result) + return space.wrap('') class ConstructorExecutor(FunctionExecutor): diff --git a/pypy/module/cppyy/test/datatypes.cxx b/pypy/module/cppyy/test/datatypes.cxx --- a/pypy/module/cppyy/test/datatypes.cxx +++ b/pypy/module/cppyy/test/datatypes.cxx @@ -183,6 +183,10 @@ double cppyy_test_data::s_double = -707.; cppyy_test_data::what cppyy_test_data::s_enum = cppyy_test_data::kNothing; +//- strings ----------------------------------------------------------------- +const char* cppyy_test_data::get_valid_string(const char* in) { return in; } +const char* cppyy_test_data::get_invalid_string() { return (const char*)0; } + //= global functions ======================================================== long get_pod_address(cppyy_test_data& c) diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h --- a/pypy/module/cppyy/test/datatypes.h +++ b/pypy/module/cppyy/test/datatypes.h @@ -148,6 +148,10 @@ float* pass_void_array_f(void* a) { return pass_array((float*)a); } double* pass_void_array_d(void* a) { return pass_array((double*)a); } +// strings + const char* get_valid_string(const char* in); + const char* get_invalid_string(); + public: // basic types bool m_bool; diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py --- a/pypy/module/cppyy/test/test_datatypes.py +++ b/pypy/module/cppyy/test/test_datatypes.py @@ -459,7 +459,17 @@ assert gbl.kBanana == 29 assert gbl.kCitrus == 34 - def test12_copy_contructor(self): + def test12_string_passing(self): + """Test passing/returning of a const char*""" + + import cppyy + cppyy_test_data = cppyy.gbl.cppyy_test_data + + c = cppyy_test_data() + assert c.get_valid_string('aap') == 'aap' + assert c.get_invalid_string() == '' + + def test13_copy_contructor(self): """Test copy constructor""" import cppyy @@ -475,7 +485,7 @@ for i in range(4): assert t1[i] == t3[i] - def test13_object_returns(self): + def test14_object_returns(self): """Test access to and return of PODs""" import cppyy @@ -502,7 +512,7 @@ assert c.get_pod_ptrref().m_int == 666 assert c.get_pod_ptrref().m_double == 3.14 - def test14_object_arguments(self): + def test15_object_arguments(self): """Test setting and returning of a POD through arguments""" import cppyy @@ -570,7 +580,7 @@ assert p.m_int == 888 assert p.m_double == 3.14 - def test15_respect_privacy(self): + def test16_respect_privacy(self): """Test that privacy settings are respected""" import cppyy @@ -583,7 +593,7 @@ c.destruct() - def test16_object_and_pointer_comparisons(self): + def test17_object_and_pointer_comparisons(self): """Verify object and pointer comparisons""" import cppyy @@ -620,7 +630,7 @@ assert l3 != l5 assert l5 != l3 - def test17_object_validity(self): + def test18_object_validity(self): """Test object validity checking""" from cppyy import gbl @@ -634,7 +644,7 @@ assert not d2 - def test18_buffer_reshaping(self): + def test19_buffer_reshaping(self): """Test usage of buffer sizing""" import cppyy @@ -654,4 +664,3 @@ l = list(arr) for i in range(self.N): assert arr[i] == l[i] - From noreply at buildbot.pypy.org Wed Mar 27 00:43:03 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 27 Mar 2013 00:43:03 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: test that overload order remains unchanged on 'const' Message-ID: <20130326234303.EA84A1C0A11@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r62821:c23edb1d3fd2 Date: 2013-03-26 13:48 -0700 http://bitbucket.org/pypy/pypy/changeset/c23edb1d3fd2/ Log: test that overload order remains unchanged on 'const' diff --git a/pypy/module/cppyy/test/advancedcpp.cxx b/pypy/module/cppyy/test/advancedcpp.cxx --- a/pypy/module/cppyy/test/advancedcpp.cxx +++ b/pypy/module/cppyy/test/advancedcpp.cxx @@ -114,3 +114,11 @@ long my_templated_method_class::get_float_size() { return (long)sizeof(float); } long my_templated_method_class::get_double_size() { return (long)sizeof(double); } long my_templated_method_class::get_self_size() { return (long)sizeof(my_templated_method_class); } + + +// overload order testing +int overload_one_way::gime() const { return 1; } +std::string overload_one_way::gime() { return "aap"; } + +std::string overload_the_other_way::gime() { return "aap"; } +int overload_the_other_way::gime() const { return 1; } diff --git a/pypy/module/cppyy/test/advancedcpp.h b/pypy/module/cppyy/test/advancedcpp.h --- a/pypy/module/cppyy/test/advancedcpp.h +++ b/pypy/module/cppyy/test/advancedcpp.h @@ -1,4 +1,5 @@ #include +#include #include @@ -416,3 +417,17 @@ typedef my_templated_method_class my_typedef_t; template long my_templated_method_class::get_size(); + + +//=========================================================================== +class overload_one_way { // overload order testing +public: + int gime() const; + std::string gime(); +}; + +class overload_the_other_way { +public: + std::string gime(); + int gime() const; +}; diff --git a/pypy/module/cppyy/test/advancedcpp.xml b/pypy/module/cppyy/test/advancedcpp.xml --- a/pypy/module/cppyy/test/advancedcpp.xml +++ b/pypy/module/cppyy/test/advancedcpp.xml @@ -53,4 +53,7 @@ + + + diff --git a/pypy/module/cppyy/test/advancedcpp_LinkDef.h b/pypy/module/cppyy/test/advancedcpp_LinkDef.h --- a/pypy/module/cppyy/test/advancedcpp_LinkDef.h +++ b/pypy/module/cppyy/test/advancedcpp_LinkDef.h @@ -78,4 +78,7 @@ #pragma link C++ class my_templated_method_class; #pragma link C++ typedef my_typedef_t; +#pragma link C++ class overload_one_way; +#pragma link C++ class overload_the_other_way; + #endif diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -629,3 +629,11 @@ assert b.__eq__(a) == True assert a.__eq__(a) == False assert b.__eq__(b) == False + + def test21_overload_order_with_proper_return(self): + """Test return type against proper overload w/ const and covariance""" + + import cppyy + + assert cppyy.gbl.overload_one_way().gime() == 1 + assert cppyy.gbl.overload_the_other_way().gime() == "aap" From noreply at buildbot.pypy.org Wed Mar 27 01:56:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 27 Mar 2013 01:56:07 +0100 (CET) Subject: [pypy-commit] pypy py3k: restore is_w, broken in the last default merge Message-ID: <20130327005607.75D8B1C0A11@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62822:efd59c9bf139 Date: 2013-03-26 17:55 -0700 http://bitbucket.org/pypy/pypy/changeset/efd59c9bf139/ Log: restore is_w, broken in the last default merge diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py --- a/pypy/objspace/std/inttype.py +++ b/pypy/objspace/std/inttype.py @@ -196,7 +196,7 @@ return False if self.user_overridden_class or w_other.user_overridden_class: return self is w_other - return space.int_w(self) == space.int_w(w_other) + return space.bigint_w(self).eq(space.bigint_w(w_other)) def immutable_unique_id(self, space): if self.user_overridden_class: diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -346,3 +346,9 @@ def test_base_overflow(self): raises(ValueError, int, '42', 2**63) + + def test_large_identity(self): + import sys + a = sys.maxsize + 1 + b = sys.maxsize + 2 + assert a is not b From noreply at buildbot.pypy.org Wed Mar 27 03:30:57 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 27 Mar 2013 03:30:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: typetype was folded into typeobject Message-ID: <20130327023057.73FD61C0176@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62823:36f286388b05 Date: 2013-03-26 19:30 -0700 http://bitbucket.org/pypy/pypy/changeset/36f286388b05/ Log: typetype was folded into typeobject diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -116,7 +116,7 @@ if isclass: # w_meta is really a class, so check for a more derived # metaclass, or possible metaclass conflicts - from pypy.objspace.std.typetype import _calculate_metaclass + from pypy.objspace.std.typeobject import _calculate_metaclass w_meta = _calculate_metaclass(space, w_meta, bases_w) try: From noreply at buildbot.pypy.org Wed Mar 27 14:23:26 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 27 Mar 2013 14:23:26 +0100 (CET) Subject: [pypy-commit] pypy refactor-call_release_gil: add a workaround to make test_fficall::test_guard_not_forced_fail passing on the x86 backend; see the comment for details Message-ID: <20130327132326.7986C1C1521@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: refactor-call_release_gil Changeset: r62829:48666ddb2250 Date: 2013-03-27 14:22 +0100 http://bitbucket.org/pypy/pypy/changeset/48666ddb2250/ Log: add a workaround to make test_fficall::test_guard_not_forced_fail passing on the x86 backend; see the comment for details diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -275,6 +275,10 @@ def cast_adr_to_int(x): return rffi.cast(lltype.Signed, x) + @staticmethod + def cast_int_to_ptr(x, TYPE): + return rffi.cast(TYPE, x) + def sizeof(self, S): return get_size_descr(self.gc_ll_descr, S) 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 @@ -1,6 +1,6 @@ import weakref from rpython.rlib.debug import debug_start, debug_print, debug_stop -from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem import lltype, llmemory class CPUTotalTracker(object): total_compiled_loops = 0 @@ -194,6 +194,11 @@ def typedescrof(self, TYPE): raise NotImplementedError + @staticmethod + def cast_int_to_ptr(x, TYPE): + x = llmemory.cast_int_to_adr(x) + return llmemory.cast_adr_to_ptr(x, TYPE) + # ---------- the backend-dependent operations ---------- # lltype specific operations diff --git a/rpython/jit/backend/x86/test/test_fficall.py b/rpython/jit/backend/x86/test/test_fficall.py --- a/rpython/jit/backend/x86/test/test_fficall.py +++ b/rpython/jit/backend/x86/test/test_fficall.py @@ -5,4 +5,19 @@ class TestFfiCall(Jit386Mixin, test_fficall.FfiCallTests): # for the individual tests see # ====> ../../../metainterp/test/test_fficall.py - pass + + def _add_libffi_types_to_ll2types_maybe(self): + # this is needed by test_guard_not_forced_fails, because it produces a + # loop which reads the value of types.* in a variable, then a guard + # fail and we switch to blackhole: the problem is that at this point + # the blackhole interp has a real integer, but it needs to convert it + # back to a lltype pointer (which is handled by ll2ctypes, deeply in + # the logic). The workaround is to teach ll2ctypes in advance which + # are the addresses of the various types.* structures. + # Try to comment this code out and run the test to see how it fails :) + from rpython.rtyper.lltypesystem import rffi, lltype, ll2ctypes + from rpython.rlib.jit_libffi import types + for key, value in types.__dict__.iteritems(): + if isinstance(value, lltype._ptr): + addr = rffi.cast(lltype.Signed, value) + ll2ctypes._int2obj[addr] = value diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -8,8 +8,9 @@ from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck from rpython.rlib.rtimer import read_timestamp from rpython.rlib.unroll import unrolling_iterable -from rpython.rtyper.lltypesystem import lltype, llmemory, rclass +from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P def arguments(*argtypes, **kwds): @@ -1350,35 +1351,19 @@ @arguments("cpu", "i", "i", "i") def bhimpl_libffi_save_result_int(self, cif_description, exchange_buffer, result): - from rpython.rtyper.lltypesystem import llmemory, rffi - from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P ARRAY = lltype.Ptr(rffi.CArray(lltype.Signed)) - - cif_description = llmemory.cast_int_to_adr(cif_description) - cif_description = llmemory.cast_adr_to_ptr(cif_description, - CIF_DESCRIPTION_P) - - exchange_buffer = llmemory.cast_int_to_adr(exchange_buffer) - exchange_buffer = llmemory.cast_adr_to_ptr(exchange_buffer, - rffi.CCHARP) - + cif_description = self.cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) + exchange_buffer = self.cast_int_to_ptr(exchange_buffer, rffi.CCHARP) + # data_out = rffi.ptradd(exchange_buffer, cif_description.exchange_result) rffi.cast(ARRAY, data_out)[0] = result @arguments("cpu", "i", "i", "f") def bhimpl_libffi_save_result_float(self, cif_description, exchange_buffer, result): - from rpython.rtyper.lltypesystem import llmemory, rffi - from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P ARRAY = lltype.Ptr(rffi.CArray(lltype.Float)) - - cif_description = llmemory.cast_int_to_adr(cif_description) - cif_description = llmemory.cast_adr_to_ptr(cif_description, - CIF_DESCRIPTION_P) - - exchange_buffer = llmemory.cast_int_to_adr(exchange_buffer) - exchange_buffer = llmemory.cast_adr_to_ptr(exchange_buffer, - rffi.CCHARP) - + cif_description = self.cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) + exchange_buffer = self.cast_int_to_ptr(exchange_buffer, rffi.CCHARP) + # data_out = rffi.ptradd(exchange_buffer, cif_description.exchange_result) rffi.cast(ARRAY, data_out)[0] = result diff --git a/rpython/jit/metainterp/test/test_fficall.py b/rpython/jit/metainterp/test/test_fficall.py --- a/rpython/jit/metainterp/test/test_fficall.py +++ b/rpython/jit/metainterp/test/test_fficall.py @@ -122,8 +122,13 @@ self._run([types.signed], types.sint8, [456], rffi.cast(rffi.SIGNEDCHAR, -42)) + def _add_libffi_types_to_ll2types_maybe(self): + # not necessary on the llgraph backend, but needed for x86. + # see rpython/jit/backend/x86/test/test_fficall.py + pass def test_guard_not_forced_fails(self): + self._add_libffi_types_to_ll2types_maybe() FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) cif_description = get_description([types.slong], types.slong) From noreply at buildbot.pypy.org Wed Mar 27 15:27:29 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 27 Mar 2013 15:27:29 +0100 (CET) Subject: [pypy-commit] pypy refactor-call_release_gil: add a (no longer failing) test which is the whole point of the branch Message-ID: <20130327142729.A88A91C2FC6@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: refactor-call_release_gil Changeset: r62830:c5cc557a227f Date: 2013-03-27 15:17 +0100 http://bitbucket.org/pypy/pypy/changeset/c5cc557a227f/ Log: add a (no longer failing) test which is the whole point of the branch diff --git a/pypy/module/pypyjit/test_pypy_c/test__ffi.py b/pypy/module/pypyjit/test_pypy_c/test__ffi.py --- a/pypy/module/pypyjit/test_pypy_c/test__ffi.py +++ b/pypy/module/pypyjit/test_pypy_c/test__ffi.py @@ -110,7 +110,6 @@ loops = log.loops_by_id('sleep') assert len(loops) == 1 # make sure that we actually JITted the loop - def test_ctypes_call(self): from rpython.rlib.test.test_clibffi import get_libm_name def main(libm_name): @@ -209,3 +208,65 @@ # so far just check that call_release_gil() is produced. # later, also check that the arguments to call_release_gil() # are constants, and that the numerous raw_mallocs are removed + + def test_cffi_call_guard_not_forced_fails(self): + # this is the test_pypy_c equivalent of + # rpython/jit/metainterp/test/test_fficall::test_guard_not_forced_fails + # + # it requires cffi to be installed for pypy in order to run + def main(): + import sys + try: + import cffi + except ImportError: + sys.stderr.write('SKIP: cannot import cffi\n') + return 0 + + ffi = cffi.FFI() + + ffi.cdef(""" + typedef void (*functype)(int); + int foo(int n, functype func); + """) + + lib = ffi.verify(""" + #include + typedef void (*functype)(int); + + int foo(int n, functype func) { + if (n >= 2000) { + func(n); + } + return n*2; + } + """) + + @ffi.callback("functype") + def mycallback(n): + if n < 5000: + return + # make sure that guard_not_forced fails + d = {} + f = sys._getframe() + while f: + d.update(f.f_locals) + f = f.f_back + + n = 0 + while n < 10000: + res = lib.foo(n, mycallback) # ID: cfficall + # this is the real point of the test: before the + # refactor-call_release_gil branch, the assert failed when + # res == 5000 + assert res == n*2 + n += 1 + return n + + log = self.run(main, [], import_site=True) + assert log.result == 10000 + loop, = log.loops_by_id('cfficall') + assert loop.match_by_id('cfficall', """ + ... + f1 = call_release_gil(..., descr=) + ... + """) From noreply at buildbot.pypy.org Wed Mar 27 15:27:30 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 27 Mar 2013 15:27:30 +0100 (CET) Subject: [pypy-commit] pypy refactor-call_release_gil: close about-to-be-merged branch Message-ID: <20130327142730.EC8211C2FC6@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: refactor-call_release_gil Changeset: r62831:091e8b0f37f8 Date: 2013-03-27 15:17 +0100 http://bitbucket.org/pypy/pypy/changeset/091e8b0f37f8/ Log: close about-to-be-merged branch From noreply at buildbot.pypy.org Wed Mar 27 15:27:32 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 27 Mar 2013 15:27:32 +0100 (CET) Subject: [pypy-commit] pypy default: merge the refactor-call_release_gil branch. This fixes a nasty bug which Message-ID: <20130327142732.8CC321C2FC6@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62832:2c9ecfd8eb43 Date: 2013-03-27 15:27 +0100 http://bitbucket.org/pypy/pypy/changeset/2c9ecfd8eb43/ Log: merge the refactor-call_release_gil branch. This fixes a nasty bug which occoured when JITting the call to a cffi function which calls a callback which causes the failure of guard_not_forced: in that case, during blackholing we got the wrong result from call_release_gil, because it was not passed to fail_args. The two tests which demonstrates the bug are - rpython/jit/metainterp/test/test_fficall.py::test_guard_not_forced_f ails - pypy/module/pypyjit/test_pypy_c/test__ffi.py::test_cffi_call_guard_n ot_forced_fails diff --git a/pypy/module/pypyjit/test_pypy_c/test__ffi.py b/pypy/module/pypyjit/test_pypy_c/test__ffi.py --- a/pypy/module/pypyjit/test_pypy_c/test__ffi.py +++ b/pypy/module/pypyjit/test_pypy_c/test__ffi.py @@ -110,7 +110,6 @@ loops = log.loops_by_id('sleep') assert len(loops) == 1 # make sure that we actually JITted the loop - def test_ctypes_call(self): from rpython.rlib.test.test_clibffi import get_libm_name def main(libm_name): @@ -209,3 +208,65 @@ # so far just check that call_release_gil() is produced. # later, also check that the arguments to call_release_gil() # are constants, and that the numerous raw_mallocs are removed + + def test_cffi_call_guard_not_forced_fails(self): + # this is the test_pypy_c equivalent of + # rpython/jit/metainterp/test/test_fficall::test_guard_not_forced_fails + # + # it requires cffi to be installed for pypy in order to run + def main(): + import sys + try: + import cffi + except ImportError: + sys.stderr.write('SKIP: cannot import cffi\n') + return 0 + + ffi = cffi.FFI() + + ffi.cdef(""" + typedef void (*functype)(int); + int foo(int n, functype func); + """) + + lib = ffi.verify(""" + #include + typedef void (*functype)(int); + + int foo(int n, functype func) { + if (n >= 2000) { + func(n); + } + return n*2; + } + """) + + @ffi.callback("functype") + def mycallback(n): + if n < 5000: + return + # make sure that guard_not_forced fails + d = {} + f = sys._getframe() + while f: + d.update(f.f_locals) + f = f.f_back + + n = 0 + while n < 10000: + res = lib.foo(n, mycallback) # ID: cfficall + # this is the real point of the test: before the + # refactor-call_release_gil branch, the assert failed when + # res == 5000 + assert res == n*2 + n += 1 + return n + + log = self.run(main, [], import_site=True) + assert log.result == 10000 + loop, = log.loops_by_id('cfficall') + assert loop.match_by_id('cfficall', """ + ... + f1 = call_release_gil(..., descr=) + ... + """) 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 @@ -840,10 +840,22 @@ # manipulation here (as a hack, instead of really doing # the aroundstate manipulation ourselves) return self.execute_call_may_force(descr, func, *args) + guard_op = self.lltrace.operations[self.current_index + 1] + assert guard_op.getopnum() == rop.GUARD_NOT_FORCED + self.force_guard_op = guard_op call_args = support.cast_call_args_in_order(descr.ARGS, args) - FUNC = lltype.FuncType(descr.ARGS, descr.RESULT) - func_to_call = rffi.cast(lltype.Ptr(FUNC), func) - result = func_to_call(*call_args) + # + func_adr = llmemory.cast_int_to_adr(func) + if hasattr(func_adr.ptr._obj, '_callable'): + # this is needed e.g. by test_fficall.test_guard_not_forced_fails, + # because to actually force the virtualref we need to llinterp the + # graph, not to directly execute the python function + result = self.cpu.maybe_on_top_of_llinterp(func, call_args, descr.RESULT) + else: + FUNC = lltype.FuncType(descr.ARGS, descr.RESULT) + func_to_call = rffi.cast(lltype.Ptr(FUNC), func) + result = func_to_call(*call_args) + del self.force_guard_op return support.cast_result(descr.RESULT, result) def execute_call_assembler(self, descr, *args): diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -275,6 +275,10 @@ def cast_adr_to_int(x): return rffi.cast(lltype.Signed, x) + @staticmethod + def cast_int_to_ptr(x, TYPE): + return rffi.cast(TYPE, x) + def sizeof(self, S): return get_size_descr(self.gc_ll_descr, S) 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 @@ -1,6 +1,6 @@ import weakref from rpython.rlib.debug import debug_start, debug_print, debug_stop -from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem import lltype, llmemory class CPUTotalTracker(object): total_compiled_loops = 0 @@ -194,6 +194,11 @@ def typedescrof(self, TYPE): raise NotImplementedError + @staticmethod + def cast_int_to_ptr(x, TYPE): + x = llmemory.cast_int_to_adr(x) + return llmemory.cast_adr_to_ptr(x, TYPE) + # ---------- the backend-dependent operations ---------- # lltype specific operations diff --git a/rpython/jit/backend/x86/test/test_fficall.py b/rpython/jit/backend/x86/test/test_fficall.py --- a/rpython/jit/backend/x86/test/test_fficall.py +++ b/rpython/jit/backend/x86/test/test_fficall.py @@ -5,4 +5,19 @@ class TestFfiCall(Jit386Mixin, test_fficall.FfiCallTests): # for the individual tests see # ====> ../../../metainterp/test/test_fficall.py - pass + + def _add_libffi_types_to_ll2types_maybe(self): + # this is needed by test_guard_not_forced_fails, because it produces a + # loop which reads the value of types.* in a variable, then a guard + # fail and we switch to blackhole: the problem is that at this point + # the blackhole interp has a real integer, but it needs to convert it + # back to a lltype pointer (which is handled by ll2ctypes, deeply in + # the logic). The workaround is to teach ll2ctypes in advance which + # are the addresses of the various types.* structures. + # Try to comment this code out and run the test to see how it fails :) + from rpython.rtyper.lltypesystem import rffi, lltype, ll2ctypes + from rpython.rlib.jit_libffi import types + for key, value in types.__dict__.iteritems(): + if isinstance(value, lltype._ptr): + addr = rffi.cast(lltype.Signed, value) + ll2ctypes._int2obj[addr] = value diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -1747,6 +1747,11 @@ assert False, 'unsupported oopspec: %s' % oopspec_name return self._handle_oopspec_call(op, args, oopspecindex, extraeffect) + def rewrite_op_jit_ffi_save_result(self, op): + kind = op.args[0].value + assert kind in ('int', 'float') + return SpaceOperation('libffi_save_result_%s' % kind, op.args[1:], None) + def rewrite_op_jit_force_virtual(self, op): return self._do_builtin_call(op) diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -8,8 +8,9 @@ from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck from rpython.rlib.rtimer import read_timestamp from rpython.rlib.unroll import unrolling_iterable -from rpython.rtyper.lltypesystem import lltype, llmemory, rclass +from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P def arguments(*argtypes, **kwds): @@ -1348,6 +1349,25 @@ def bhimpl_ll_read_timestamp(): return read_timestamp() + @arguments("cpu", "i", "i", "i") + def bhimpl_libffi_save_result_int(self, cif_description, exchange_buffer, result): + ARRAY = lltype.Ptr(rffi.CArray(lltype.Signed)) + cif_description = self.cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) + exchange_buffer = self.cast_int_to_ptr(exchange_buffer, rffi.CCHARP) + # + data_out = rffi.ptradd(exchange_buffer, cif_description.exchange_result) + rffi.cast(ARRAY, data_out)[0] = result + + @arguments("cpu", "i", "i", "f") + def bhimpl_libffi_save_result_float(self, cif_description, exchange_buffer, result): + ARRAY = lltype.Ptr(rffi.CArray(lltype.Float)) + cif_description = self.cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) + exchange_buffer = self.cast_int_to_ptr(exchange_buffer, rffi.CCHARP) + # + data_out = rffi.ptradd(exchange_buffer, cif_description.exchange_result) + rffi.cast(ARRAY, data_out)[0] = result + + # ---------- # helpers to resume running in blackhole mode when a guard failed 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 @@ -775,8 +775,8 @@ def show(self, errmsg=None): "NOT_RPYTHON" - from rpython.jit.metainterp.graphpage import display_loops - display_loops([self], errmsg) + from rpython.jit.metainterp.graphpage import display_procedures + display_procedures([self], errmsg) def check_consistency(self): # for testing "NOT_RPYTHON" diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1185,6 +1185,30 @@ def opimpl_ll_read_timestamp(self): return self.metainterp.execute_and_record(rop.READ_TIMESTAMP, None) + @arguments("box", "box", "box") + def opimpl_libffi_save_result_int(self, box_cif_description, box_exchange_buffer, + box_result): + from rpython.rtyper.lltypesystem import llmemory + from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P + from rpython.jit.backend.llsupport.ffisupport import get_arg_descr + + cif_description = box_cif_description.getint() + cif_description = llmemory.cast_int_to_adr(cif_description) + cif_description = llmemory.cast_adr_to_ptr(cif_description, + CIF_DESCRIPTION_P) + + kind, descr, itemsize = get_arg_descr(self.metainterp.cpu, cif_description.rtype) + + if kind != 'v': + ofs = cif_description.exchange_result + assert ofs % itemsize == 0 # alignment check (result) + self.metainterp.history.record(rop.SETARRAYITEM_RAW, + [box_exchange_buffer, + ConstInt(ofs // itemsize), box_result], + None, descr) + + opimpl_libffi_save_result_float = opimpl_libffi_save_result_int + # ------------------------------ def setup_call(self, argboxes): @@ -2589,27 +2613,15 @@ box_arg, descr) arg_boxes.append(box_arg) # - kind, descr, itemsize = get_arg_descr(self.cpu, cif_description.rtype) - if kind == 'i': - box_result = history.BoxInt() - elif kind == 'f': - box_result = history.BoxFloat() - else: - assert kind == 'v' - box_result = None + box_result = op.result self.history.record(rop.CALL_RELEASE_GIL, [op.getarg(2)] + arg_boxes, box_result, calldescr) # self.history.operations.extend(extra_guards) # - if box_result is not None: - ofs = cif_description.exchange_result - assert ofs % itemsize == 0 # alignment check (result) - self.history.record(rop.SETARRAYITEM_RAW, - [box_exchange_buffer, - ConstInt(ofs // itemsize), box_result], - None, descr) + # note that the result is written back to the exchange_buffer by the + # special op libffi_save_result_{int,float} def direct_call_release_gil(self): op = self.history.operations.pop() diff --git a/rpython/jit/metainterp/test/test_fficall.py b/rpython/jit/metainterp/test/test_fficall.py --- a/rpython/jit/metainterp/test/test_fficall.py +++ b/rpython/jit/metainterp/test/test_fficall.py @@ -1,14 +1,16 @@ - import py +from _pytest.monkeypatch import monkeypatch import ctypes, math from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.test.support import LLJitMixin from rpython.rlib import jit -from rpython.rlib.jit_libffi import types, CIF_DESCRIPTION, FFI_TYPE_PP +from rpython.rlib import jit_libffi +from rpython.rlib.jit_libffi import (types, CIF_DESCRIPTION, FFI_TYPE_PP, + jit_ffi_call, jit_ffi_save_result) from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.rarithmetic import intmask - def get_description(atypes, rtype): p = lltype.malloc(CIF_DESCRIPTION, len(atypes), flavor='raw', immortal=True) @@ -21,6 +23,22 @@ p.atypes[i] = atypes[i] return p +class FakeFFI(object): + """ + Context manager to monkey patch jit_libffi with our custom "libffi-like" + function + """ + + def __init__(self, fake_call_impl_any): + self.fake_call_impl_any = fake_call_impl_any + self.monkey = monkeypatch() + + def __enter__(self, *args): + self.monkey.setattr(jit_libffi, 'jit_ffi_call_impl_any', self.fake_call_impl_any) + + def __exit__(self, *args): + self.monkey.undo() + class FfiCallTests(object): @@ -41,8 +59,7 @@ unroll_avalues = unrolling_iterable(avalues) - @jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") - def fake_call(cif_description, func_addr, exchange_buffer): + def fake_call_impl_any(cif_description, func_addr, exchange_buffer): ofs = 16 for avalue in unroll_avalues: TYPE = rffi.CArray(lltype.typeOf(avalue)) @@ -67,7 +84,7 @@ rffi.cast(lltype.Ptr(TYPE), data)[0] = avalue ofs += 16 - fake_call(cif_description, func_addr, exbuf) + jit_ffi_call(cif_description, func_addr, exbuf) if rvalue is None: res = 654321 @@ -78,14 +95,15 @@ lltype.free(exbuf, flavor='raw') return res - res = f() - assert res == rvalue or (res, rvalue) == (654321, None) - res = self.interp_operations(f, []) - assert res == rvalue or (res, rvalue) == (654321, None) - self.check_operations_history(call_may_force=0, - call_release_gil=1) + with FakeFFI(fake_call_impl_any): + res = f() + assert res == rvalue or (res, rvalue) == (654321, None) + res = self.interp_operations(f, []) + assert res == rvalue or (res, rvalue) == (654321, None) + self.check_operations_history(call_may_force=0, + call_release_gil=1) - def test_simple_call(self): + def test_simple_call_int(self): self._run([types.signed] * 2, types.signed, [456, 789], -42) def test_many_arguments(self): @@ -104,6 +122,91 @@ self._run([types.signed], types.sint8, [456], rffi.cast(rffi.SIGNEDCHAR, -42)) + def _add_libffi_types_to_ll2types_maybe(self): + # not necessary on the llgraph backend, but needed for x86. + # see rpython/jit/backend/x86/test/test_fficall.py + pass + + def test_guard_not_forced_fails(self): + self._add_libffi_types_to_ll2types_maybe() + FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) + + cif_description = get_description([types.slong], types.slong) + cif_description.exchange_args[0] = 16 + cif_description.exchange_result = 32 + + ARRAY = lltype.Ptr(rffi.CArray(lltype.Signed)) + + @jit.dont_look_inside + def fn(n): + if n >= 50: + exctx.m = exctx.topframeref().n # forces the frame + return n*2 + + # this function simulates what a real libffi_call does: reading from + # the buffer, calling a function (which can potentially call callbacks + # and force frames) and write back to the buffer + def fake_call_impl_any(cif_description, func_addr, exchange_buffer): + # read the args from the buffer + data_in = rffi.ptradd(exchange_buffer, 16) + n = rffi.cast(ARRAY, data_in)[0] + # + # logic of the function + func_ptr = rffi.cast(lltype.Ptr(FUNC), func_addr) + n = func_ptr(n) + # + # write the result to the buffer + data_out = rffi.ptradd(exchange_buffer, 32) + rffi.cast(ARRAY, data_out)[0] = n + + def do_call(n): + func_ptr = llhelper(lltype.Ptr(FUNC), fn) + exbuf = lltype.malloc(rffi.CCHARP.TO, 48, flavor='raw', zero=True) + data_in = rffi.ptradd(exbuf, 16) + rffi.cast(ARRAY, data_in)[0] = n + jit_ffi_call(cif_description, func_ptr, exbuf) + data_out = rffi.ptradd(exbuf, 32) + res = rffi.cast(ARRAY, data_out)[0] + lltype.free(exbuf, flavor='raw') + return res + + # + # + class XY: + pass + class ExCtx: + pass + exctx = ExCtx() + myjitdriver = jit.JitDriver(greens = [], reds = ['n']) + def f(): + n = 0 + while n < 100: + myjitdriver.jit_merge_point(n=n) + xy = XY() + xy.n = n + exctx.topframeref = vref = jit.virtual_ref(xy) + res = do_call(n) # this is equivalent of a cffi call which + # sometimes forces a frame + + # when n==50, fn() will force the frame, so guard_not_forced + # fails and we enter blackholing: this test makes sure that + # the result of call_release_gil is kept alive before the + # libffi_save_result, and that the corresponding box is passed + # in the fail_args. Before the fix, the result of + # call_release_gil was simply lost and when guard_not_forced + # failed, and the value of "res" was unpredictable. + # See commit b84ff38f34bd and subsequents. + assert res == n*2 + jit.virtual_ref_finish(vref, xy) + exctx.topframeref = jit.vref_None + n += 1 + return n + + with FakeFFI(fake_call_impl_any): + assert f() == 100 + res = self.meta_interp(f, []) + assert res == 100 + class TestFfiCall(FfiCallTests, LLJitMixin): def test_jit_ffi_vref(self): diff --git a/rpython/rlib/jit_libffi.py b/rpython/rlib/jit_libffi.py --- a/rpython/rlib/jit_libffi.py +++ b/rpython/rlib/jit_libffi.py @@ -1,6 +1,8 @@ from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rlib import clibffi, jit +from rpython.rlib.nonconst import NonConstant FFI_CIF = clibffi.FFI_CIFP.TO @@ -65,11 +67,79 @@ return rffi.cast(lltype.Signed, res) - at jit.oopspec("libffi_call(cif_description, func_addr, exchange_buffer)") +# ============================= +# jit_ffi_call and its helpers +# ============================= + +## Problem: jit_ffi_call is turned into call_release_gil by pyjitpl. Before +## the refactor-call_release_gil branch, the resulting code looked like this: +## +## buffer = ... +## i0 = call_release_gil(...) +## guard_not_forced() +## setarray_item_raw(buffer, ..., i0) +## +## The problem is that the result box i0 was generated freshly inside pyjitpl, +## and the codewriter did not know about its liveness: the result was that i0 +## was not in the fail_args of guard_not_forced. See +## test_fficall::test_guard_not_forced_fails for a more detalied explanation +## of the problem. +## +## The solution is to create a new separate operation libffi_save_result whose +## job is to write the result in the exchange_buffer: during normal execution +## this is a no-op because the buffer is already filled by libffi, but during +## jitting the behavior is to actually write into the buffer. +## +## The result is that now the jitcode looks like this: +## +## %i0 = libffi_call_int(...) +## -live- +## libffi_save_result_int(..., %i0) +## +## the "-live-" is the key, because it make sure that the value is not lost if +## guard_not_forced fails. + + def jit_ffi_call(cif_description, func_addr, exchange_buffer): """Wrapper around ffi_call(). Must receive a CIF_DESCRIPTION_P that describes the layout of the 'exchange_buffer'. """ + if cif_description.rtype == types.void: + jit_ffi_call_impl_void(cif_description, func_addr, exchange_buffer) + elif cif_description.rtype == types.double: + result = jit_ffi_call_impl_float(cif_description, func_addr, exchange_buffer) + jit_ffi_save_result('float', cif_description, exchange_buffer, result) + else: + result = jit_ffi_call_impl_int(cif_description, func_addr, exchange_buffer) + jit_ffi_save_result('int', cif_description, exchange_buffer, result) + + +# we must return a NonConstant else we get the constant -1 as the result of +# the flowgraph, and the codewriter does not produce a box for the +# result. Note that when not-jitted, the result is unused, but when jitted the +# box of the result contains the actual value returned by the C function. + + at jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") +def jit_ffi_call_impl_int(cif_description, func_addr, exchange_buffer): + jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) + return NonConstant(-1) + + at jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") +def jit_ffi_call_impl_float(cif_description, func_addr, exchange_buffer): + jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) + return NonConstant(-1.0) + + at jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") +def jit_ffi_call_impl_void(cif_description, func_addr, exchange_buffer): + jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) + return None + +def jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer): + """ + This is the function which actually calls libffi. All the rest if just + infrastructure to convince the JIT to pass a typed result box to + jit_ffi_save_result + """ buffer_array = rffi.cast(rffi.VOIDPP, exchange_buffer) for i in range(cif_description.nargs): data = rffi.ptradd(exchange_buffer, cif_description.exchange_args[i]) @@ -79,6 +149,31 @@ clibffi.c_ffi_call(cif_description.cif, func_addr, rffi.cast(rffi.VOIDP, resultdata), buffer_array) + return -1 + + + +def jit_ffi_save_result(kind, cif_description, exchange_buffer, result): + """ + This is a no-op during normal execution, but actually fills the buffer + when jitted + """ + pass + +class Entry(ExtRegistryEntry): + _about_ = jit_ffi_save_result + + def compute_result_annotation(self, kind_s, *args_s): + from rpython.annotator import model as annmodel + assert isinstance(kind_s, annmodel.SomeString) + assert kind_s.const in ('int', 'float') + + def specialize_call(self, hop): + hop.exception_cannot_occur() + vlist = hop.inputargs(lltype.Void, *hop.args_r[1:]) + return hop.genop('jit_ffi_save_result', vlist, + resulttype=lltype.Void) + # ____________________________________________________________ diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -456,6 +456,7 @@ 'jit_is_virtual': LLOp(canrun=True), 'jit_force_quasi_immutable': LLOp(canrun=True), 'jit_record_known_class' : LLOp(canrun=True), + 'jit_ffi_save_result': LLOp(canrun=True), 'get_exception_addr': LLOp(), 'get_exc_value_addr': LLOp(), 'do_malloc_fixedsize_clear':LLOp(canmallocgc=True), diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -597,6 +597,9 @@ def op_jit_record_known_class(x, y): pass +def op_jit_ffi_save_result(*args): + pass + def op_get_group_member(TYPE, grpptr, memberoffset): from rpython.rtyper.lltypesystem import llgroup assert isinstance(memberoffset, llgroup.GroupMemberOffset) diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -843,6 +843,9 @@ def OP_JIT_FORCE_QUASI_IMMUTABLE(self, op): return '/* JIT_FORCE_QUASI_IMMUTABLE %s */' % op + def OP_JIT_FFI_SAVE_RESULT(self, op): + return '/* JIT_FFI_SAVE_RESULT %s */' % op + def OP_GET_GROUP_MEMBER(self, op): typename = self.db.gettype(op.result.concretetype) return '%s = (%s)_OP_GET_GROUP_MEMBER(%s, %s);' % ( diff --git a/rpython/translator/cli/opcodes.py b/rpython/translator/cli/opcodes.py --- a/rpython/translator/cli/opcodes.py +++ b/rpython/translator/cli/opcodes.py @@ -99,6 +99,7 @@ 'jit_force_virtual': DoNothing, 'jit_force_quasi_immutable':Ignore, 'jit_is_virtual': [PushPrimitive(ootype.Bool, False)], + 'jit_ffi_save_result': Ignore, } # __________ numeric operations __________ diff --git a/rpython/translator/jvm/opcodes.py b/rpython/translator/jvm/opcodes.py --- a/rpython/translator/jvm/opcodes.py +++ b/rpython/translator/jvm/opcodes.py @@ -102,6 +102,7 @@ 'jit_force_virtual': DoNothing, 'jit_force_quasi_immutable': Ignore, 'jit_is_virtual': PushPrimitive(ootype.Bool, False), + 'jit_ffi_save_result': Ignore, 'debug_assert': [], # TODO: implement? 'debug_start_traceback': Ignore, From noreply at buildbot.pypy.org Wed Mar 27 15:52:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 15:52:34 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Support the new finalizer interface in Boehm too. Message-ID: <20130327145234.9AC421C2FC7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62833:9ef6bb8aa5c2 Date: 2013-03-27 15:50 +0100 http://bitbucket.org/pypy/pypy/changeset/9ef6bb8aa5c2/ Log: Support the new finalizer interface in Boehm too. diff --git a/rpython/memory/gctransform/boehm.py b/rpython/memory/gctransform/boehm.py --- a/rpython/memory/gctransform/boehm.py +++ b/rpython/memory/gctransform/boehm.py @@ -9,12 +9,12 @@ class BoehmGCTransformer(GCTransformer): malloc_zero_filled = True - FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void)) + DESTRUCTOR_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void)) HDR = lltype.Struct("header", ("hash", lltype.Signed)) def __init__(self, translator, inline=False): super(BoehmGCTransformer, self).__init__(translator, inline=inline) - self.finalizer_funcptrs = {} + self.destructor_funcptrs = {} atomic_mh = mallocHelpers() atomic_mh.allocate = lambda size: llop.boehm_malloc_atomic(llmemory.Address, size) @@ -66,10 +66,15 @@ v_raw = hop.genop("direct_call", [funcptr, c_size], resulttype=llmemory.Address) - finalizer_ptr = self.finalizer_funcptr_for_type(TYPE) - if finalizer_ptr: - c_finalizer_ptr = Constant(finalizer_ptr, self.FINALIZER_PTR) - hop.genop("boehm_register_finalizer", [v_raw, c_finalizer_ptr]) + destructor_ptr = self.destructor_funcptr_for_type(TYPE) + if destructor_ptr: + from rpython.rtyper.annlowlevel import base_ptr_lltype + c_destructor_ptr = Constant(destructor_ptr, self.DESTRUCTOR_PTR) + v_llfn = hop.genop('cast_ptr_to_adr', [c_destructor_ptr], + resulttype=llmemory.Address) + v_self = hop.genop('cast_adr_to_ptr', [v_raw], + resulttype=base_ptr_lltype()) + hop.genop("gc_register_finalizer", [v_self, v_llfn]) return v_raw def gct_fv_gc_malloc_varsize(self, hop, flags, TYPE, v_length, c_const_size, c_item_size, @@ -87,9 +92,9 @@ resulttype=llmemory.Address) return v_raw - def finalizer_funcptr_for_type(self, TYPE): - if TYPE in self.finalizer_funcptrs: - return self.finalizer_funcptrs[TYPE] + def destructor_funcptr_for_type(self, TYPE): + if TYPE in self.destructor_funcptrs: + return self.destructor_funcptrs[TYPE] rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): @@ -102,16 +107,17 @@ if destrptr: EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value typename = TYPE.__name__ - def ll_finalizer(addr): + def ll_destructor(addr): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) llop.gc_restore_exception(lltype.Void, exc_instance) - fptr = self.annotate_finalizer(ll_finalizer, [llmemory.Address], lltype.Void) + fptr = self.annotate_finalizer(ll_destructor, [llmemory.Address], + lltype.Void) else: - fptr = lltype.nullptr(self.FINALIZER_PTR.TO) + fptr = lltype.nullptr(self.DESTRUCTOR_PTR.TO) - self.finalizer_funcptrs[TYPE] = fptr + self.destructor_funcptrs[TYPE] = fptr return fptr def gct_weakref_create(self, hop): diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -148,7 +148,7 @@ finalizer = llmemory.cast_adr_to_ptr(finalizer, self.FINALIZER) try: finalizer(obj) - except rgc.FinalizeLater: + except rgc._FinalizeLater: return False except Exception: debug_print("WARNING: unhandled exception from finalizer", @@ -166,7 +166,7 @@ llinterp.eval_graph(finalizer.ptr._obj.graph, [obj], recursive=True) except LLException, e: - if ''.join(e.args[0].name) == 'FinalizeLater\x00': + if ''.join(e.args[0].name) == '_FinalizeLater\x00': return False raise RuntimeError( "a finalizer raised an exception, shouldn't happen") diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py --- a/rpython/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -264,7 +264,7 @@ b.num_finalized += 1 debug_print("call to finalizer() number", b.num_finalized) if (b.num_finalized % 3) == 0: - raise rgc.FinalizeLater + raise rgc._FinalizeLater def f(x): a = A() rgc.register_finalizer(a.finalizer) diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -6,6 +6,7 @@ from rpython.rlib import jit from rpython.rlib.objectmodel import we_are_translated, enforceargs, specialize +from rpython.rlib.objectmodel import CDefinedIntSymbolic from rpython.rlib.nonconst import NonConstant from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory @@ -270,7 +271,7 @@ # ____________________________________________________________ -class FinalizeLater(Exception): +class _FinalizeLater(Exception): pass _finalizer_queue = collections.deque() @@ -286,6 +287,12 @@ progress_through_finalizer_queue() delattr(g, '__disable_del') +gc_supports_finalize_later = CDefinedIntSymbolic('GC_SUPPORTS_FINALIZE_LATER', + default=1) +def finalize_later(): + if gc_supports_finalize_later: + raise _FinalizeLater + def register_finalizer(method): "NOT_RPYTHON" # Cheat, cheat. When method() is called, its 'self' will actually be @@ -336,7 +343,7 @@ obj, func = _finalizer_queue.popleft() try: func(obj) - except FinalizeLater: + except _FinalizeLater: _finalizer_queue.appendleft((obj, func)) break except Exception, e: diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py --- a/rpython/rlib/test/test_rgc.py +++ b/rpython/rlib/test/test_rgc.py @@ -258,7 +258,7 @@ def finalize(self): if len(seen) < 3: seen.append((self.x, self.y)) - raise rgc.FinalizeLater + raise rgc._FinalizeLater seen.append(True) p = Point(40, 2) rgc.register_finalizer(p.finalize) diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -981,9 +981,6 @@ op_boehm_malloc = op_boehm_malloc_atomic = op_raw_malloc - def op_boehm_register_finalizer(self, p, finalizer): - pass - def op_boehm_disappearing_link(self, link, obj): pass diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -413,7 +413,6 @@ 'boehm_malloc': LLOp(), 'boehm_malloc_atomic': LLOp(), - 'boehm_register_finalizer': LLOp(), 'boehm_disappearing_link': LLOp(), 'raw_malloc': LLOp(), 'raw_malloc_usage': LLOp(sideeffects=False), diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -600,10 +600,6 @@ return 'OP_BOEHM_ZERO_MALLOC(%s, %s, void*, 1, 0);' % (self.expr(op.args[0]), self.expr(op.result)) - def OP_BOEHM_REGISTER_FINALIZER(self, op): - return 'GC_REGISTER_FINALIZER(%s, (GC_finalization_proc)%s, NULL, NULL, NULL);' \ - % (self.expr(op.args[0]), self.expr(op.args[1])) - def OP_RAW_MALLOC(self, op): eresult = self.expr(op.result) esize = self.expr(op.args[0]) diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h --- a/rpython/translator/c/src/mem.h +++ b/rpython/translator/c/src/mem.h @@ -91,6 +91,10 @@ #endif /* RPY_ASSERT */ + +#define GC_SUPPORTS_FINALIZE_LATER 1 + + /* for Boehm GC */ #ifdef PYPY_USING_BOEHM_GC @@ -123,6 +127,10 @@ #define OP_GC__DISABLE_FINALIZERS(r) boehm_gc_finalizer_lock++ #define OP_GC__ENABLE_FINALIZERS(r) (boehm_gc_finalizer_lock--, \ boehm_gc_finalizer_notifier()) +#define OP_GC_REGISTER_FINALIZER(x, y, r) \ + GC_REGISTER_FINALIZER(x, (GC_finalization_proc)y, NULL, NULL, NULL) +#undef GC_SUPPORTS_FINALIZE_LATER +#define GC_SUPPORTS_FINALIZE_LATER 0 #endif /* PYPY_USING_BOEHM_GC */ @@ -133,6 +141,9 @@ #define OP_BOEHM_DISAPPEARING_LINK(link, obj, r) /* nothing */ #define OP_GC__DISABLE_FINALIZERS(r) /* nothing */ #define OP_GC__ENABLE_FINALIZERS(r) /* nothing */ +#define OP_GC_REGISTER_FINALIZER(x, y, r) /* nothing */ +#undef GC_SUPPORTS_FINALIZE_LATER +#define GC_SUPPORTS_FINALIZE_LATER 0 #endif /************************************************************/ diff --git a/rpython/translator/c/test/test_boehm.py b/rpython/translator/c/test/test_boehm.py --- a/rpython/translator/c/test/test_boehm.py +++ b/rpython/translator/c/test/test_boehm.py @@ -136,9 +136,9 @@ assert 0 < res1 <= 10 assert 0 < res2 <= 5 - def test_del_raises(self): + def test_finalizer_raises(self): class A(object): - def __del__(self): + def finalizer(self): s.dels += 1 raise Exception class State: @@ -164,6 +164,35 @@ # it might be the test's fault though. assert res > 0 + def test_finalizer_raises(self): + class A(object): + def finalizer(self): + s.dels += 1 + class State: + pass + s = State() + s.dels = 0 + def g(): + a = A() + rgc.register_finalizer(a.finalizer) + assert not rgc.gc_supports_finalize_later + def f(): + s.dels = 0 + for i in range(10): + g() + llop.gc__collect(lltype.Void) + return s.dels + fn = self.getcompiled(f) + # we can't demand that boehm has collected all of the objects, + # even with the gc__collect call. calling the compiled + # function twice seems to help, though. + res = 0 + res += fn() + res += fn() + # if res is still 0, then we haven't tested anything so fail. + # it might be the test's fault though. + assert res > 0 + def test_memory_error_varsize(self): N = int(2**31-1) A = lltype.GcArray(lltype.Char) diff --git a/rpython/translator/c/test/test_newgc.py b/rpython/translator/c/test/test_newgc.py --- a/rpython/translator/c/test/test_newgc.py +++ b/rpython/translator/c/test/test_newgc.py @@ -413,8 +413,9 @@ def finalizer(self): b.num_deleted += 1 if b.num_deleted == 3: - raise rgc.FinalizeLater + rgc.finalize_later() def f(): + assert rgc.gc_supports_finalize_later A() i = 0 while i < 5: From noreply at buildbot.pypy.org Wed Mar 27 17:49:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 17:49:22 +0100 (CET) Subject: [pypy-commit] pypy default: Run -A tests even if they require translation options (specified without Message-ID: <20130327164922.19D6A1C304A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62836:0397468104b6 Date: 2013-03-27 17:50 +0100 http://bitbucket.org/pypy/pypy/changeset/0397468104b6/ Log: Run -A tests even if they require translation options (specified without the "translation." prefix, e.g. in pypy/module/_continuation/support.py: "continuation=True") diff --git a/pypy/tool/pytest/objspace.py b/pypy/tool/pytest/objspace.py --- a/pypy/tool/pytest/objspace.py +++ b/pypy/tool/pytest/objspace.py @@ -63,6 +63,8 @@ continue if info is None: py.test.skip("cannot runappdirect this test on top of CPython") + if ('translation.' + key) in info: + key = 'translation.' + key has = info.get(key, None) if has != value: #print sys.pypy_translation_info From noreply at buildbot.pypy.org Wed Mar 27 20:07:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 20:07:14 +0100 (CET) Subject: [pypy-commit] pypy gc-del: Progress Message-ID: <20130327190714.643861C2FDA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del Changeset: r62837:5185bfcb30aa Date: 2013-03-27 16:45 +0100 http://bitbucket.org/pypy/pypy/changeset/5185bfcb30aa/ Log: Progress diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py --- a/pypy/interpreter/test/test_typedef.py +++ b/pypy/interpreter/test/test_typedef.py @@ -74,10 +74,10 @@ sources = [] for hasdict in [False, True]: for wants_slots in [False, True]: - for needsdel in [False, True]: + if 1: # was: for needsdel in [False, True]: for weakrefable in [False, True]: print 'Testing case', hasdict, wants_slots, - print needsdel, weakrefable + print weakrefable slots = [] checks = [] @@ -100,16 +100,7 @@ else: checks.append('') - if needsdel: - methodname = '__del__' - checks.append('X();X();X();' - 'import gc;gc.collect();' - 'assert seen') - else: - methodname = 'spam' - checks.append('assert "Del" not in irepr') - - assert len(checks) == 4 + assert len(checks) == 3 space.appexec([], """(): seen = [] class X(list): diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -153,11 +153,10 @@ for flag1 in (False, True): for flag2 in (False, True): for flag3 in (False, True): - for flag4 in (False, True): - result.append(get_unique_interplevel_subclass( - config, cls, flag1, flag2, flag3, flag4)) + result.append(get_unique_interplevel_subclass( + config, cls, flag1, flag2, flag3)) result = dict.fromkeys(result) - assert len(result) <= 6 + assert len(result) <= 4 return result.keys() def _getusercls(config, cls, wants_dict, wants_slots, weakrefable): @@ -171,8 +170,8 @@ if wants_dict: if wants_slots: # case 3. Parent class is 1. - parentcls = get_unique_interplevel_subclass(config, cls, True, False, - False, True) + parentcls = get_unique_interplevel_subclass(config, cls, + True, False, True) return _usersubclswithfeature(config, parentcls, "slots") else: # case 1 (we need to add weakrefable unless it's already in 'cls') @@ -183,8 +182,8 @@ else: if weakrefable and not typedef.weakrefable: # case 4. Parent class is 2. - parentcls = get_unique_interplevel_subclass(config, cls, False, True, - False, False) + parentcls = get_unique_interplevel_subclass(config, cls, + False, True, False) return _usersubclswithfeature(config, parentcls, "weakref") else: # case 2 (if the base is already weakrefable, case 2 == case 4) diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -354,14 +354,13 @@ # relationship, if any) assert cls in self.model.typeorder, repr(cls) # - if (self.config.objspace.std.withmapdict and cls is W_ObjectObject - and not w_subtype.needsdel): + if self.config.objspace.std.withmapdict and cls is W_ObjectObject: from pypy.objspace.std.mapdict import get_subclass_of_correct_size subcls = get_subclass_of_correct_size(self, cls, w_subtype) else: subcls = get_unique_interplevel_subclass( self.config, cls, w_subtype.hasdict, w_subtype.nslots != 0, - w_subtype.needsdel, w_subtype.weakrefable) + w_subtype.weakrefable) instance = instantiate(subcls) assert isinstance(instance, cls) instance.user_setup(self, w_subtype) diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -94,7 +94,6 @@ _immutable_fields_ = ["flag_heaptype", "flag_cpytype", "flag_abstract?", - 'needsdel', 'weakrefable', 'hasdict', 'nslots', @@ -124,7 +123,6 @@ w_self.dict_w = dict_w w_self.nslots = 0 w_self.hasdict = False - w_self.needsdel = False w_self.weakrefable = False w_self.w_doc = space.w_None w_self.weak_subclasses = [] @@ -255,7 +253,7 @@ # compute a tuple that fully describes the instance layout def get_full_instance_layout(w_self): w_layout = w_self.w_same_layout_as or w_self - return (w_layout, w_self.hasdict, w_self.needsdel, w_self.weakrefable) + return (w_layout, w_self.hasdict, w_self.weakrefable) def compute_default_mro(w_self): return compute_C3_mro(w_self.space, w_self) @@ -658,7 +656,6 @@ hasoldstylebase = True continue w_self.hasdict = w_self.hasdict or w_base.hasdict - w_self.needsdel = w_self.needsdel or w_base.needsdel w_self.weakrefable = w_self.weakrefable or w_base.weakrefable w_self.nslots = w_bestbase.nslots return hasoldstylebase @@ -699,8 +696,6 @@ create_dict_slot(w_self) if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: - w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space From noreply at buildbot.pypy.org Wed Mar 27 20:07:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 20:07:18 +0100 (CET) Subject: [pypy-commit] pypy default: Fix an obscure issue where destructed SHADOWSTACKREFs could still be Message-ID: <20130327190719.547991C2FDA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62838:160bd3211313 Date: 2013-03-27 20:06 +0100 http://bitbucket.org/pypy/pypy/changeset/160bd3211313/ Log: Fix an obscure issue where destructed SHADOWSTACKREFs could still be occasionally traced, leading to crashes. diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -397,7 +397,11 @@ from rpython.rlib import _rffi_stacklet as _c h = shadowstackref.context h = llmemory.cast_adr_to_ptr(h, _c.handle) - llmemory.raw_free(shadowstackref.base) + base = shadowstackref.base + shadowstackref.base = llmemory.NULL + shadowstackref.top = llmemory.NULL + shadowstackref.context = llmemory.NULL + llmemory.raw_free(base) if h: _c.destroy(h) From noreply at buildbot.pypy.org Wed Mar 27 20:54:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 20:54:49 +0100 (CET) Subject: [pypy-commit] cffi default: Issue #67 Message-ID: <20130327195449.5920C1C304A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1199:4fb209f49094 Date: 2013-03-27 20:51 +0100 http://bitbucket.org/cffi/cffi/changeset/4fb209f49094/ Log: Issue #67 Copy the enum's values on the library object returned by dlopen(). diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -358,6 +358,7 @@ if path is None: raise OSError("library not found: %r" % (name,)) backendlib = backend.load_library(path, flags) + copied_enums = [] # def make_accessor(name): key = 'function ' + name @@ -379,6 +380,17 @@ lambda self, value: write_variable(BType, name, value))) return # + if not copied_enums: + for key, tp in ffi._parser._declarations.iteritems(): + if not key.startswith('enum '): + continue + for enumname, enumval in zip(tp.enumerators, tp.enumvalues): + if enumname not in library.__dict__: + library.__dict__[enumname] = enumval + copied_enums.append(True) + if name in library.__dict__: + return + # raise AttributeError(name) # class FFILibrary(object): diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -333,3 +333,12 @@ with open(filename, 'rb') as f: res = f.read() assert res == b'[hello from custom file][some more output]' + + def test_constants_on_lib(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef("""enum foo_e { AA, BB, CC=5, DD };""") + lib = ffi.dlopen(None) + assert lib.AA == 0 + assert lib.BB == 1 + assert lib.CC == 5 + assert lib.DD == 6 From noreply at buildbot.pypy.org Wed Mar 27 20:54:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 20:54:50 +0100 (CET) Subject: [pypy-commit] cffi default: Fix for a potential race condition in multithreaded programs (hard to test). Message-ID: <20130327195450.9F2EB1C304F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1200:37d1044bd114 Date: 2013-03-27 20:54 +0100 http://bitbucket.org/cffi/cffi/changeset/37d1044bd114/ Log: Fix for a potential race condition in multithreaded programs (hard to test). diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -388,9 +388,9 @@ if enumname not in library.__dict__: library.__dict__[enumname] = enumval copied_enums.append(True) - if name in library.__dict__: - return # + if name in library.__dict__: # copied from an enum value just above, + return # or multithread's race condition raise AttributeError(name) # class FFILibrary(object): From noreply at buildbot.pypy.org Wed Mar 27 21:29:06 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 27 Mar 2013 21:29:06 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: merge implementations of Float96 and Float128 Message-ID: <20130327202906.B319F1C3027@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62839:134e6c61bda1 Date: 2013-03-23 01:47 +0000 http://bitbucket.org/pypy/pypy/changeset/134e6c61bda1/ Log: merge implementations of Float96 and Float128 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 @@ -1076,7 +1076,7 @@ def to_builtin_type(self, space, box): real,imag = self.for_computation(self.unbox(box)) - return space.newcomplex(real, imag) + return space.newcomplex(real, imag) def read_bool(self, arr, i, offset): v = self.for_computation(self._read(arr.storage, i, offset)) @@ -1217,7 +1217,7 @@ @raw_binary_op def le(self, v1, v2): - return self._lt(v1, v2) or self._eq(v1, v2) + return self._lt(v1, v2) or self._eq(v1, v2) @raw_binary_op def gt(self, v1, v2): @@ -1225,7 +1225,7 @@ @raw_binary_op def ge(self, v1, v2): - return self._lt(v2, v1) or self._eq(v2, v1) + return self._lt(v2, v1) or self._eq(v2, v1) def _bool(self, v): return bool(v[0]) or bool(v[1]) @@ -1341,7 +1341,7 @@ return rcomplex.c_div((v[0], -v[1]), (a2, 0.)) except ZeroDivisionError: return rfloat.NAN, rfloat.NAN - + # No floor, ceil, trunc in numpy for complex #@simple_unary_op #def floor(self, v): @@ -1562,8 +1562,8 @@ NonNativeComplex128 = Complex128 -if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: - class Float96(BaseType, Float): +if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size > 8: + class Float80(BaseType, Float): _attrs_ = () T = rffi.LONGDOUBLE @@ -1571,7 +1571,7 @@ format_code = "q" def runpack_str(self, s): - assert len(s) == 12 + assert len(s) == self.storage_bytes fval = unpack_float80(s, native_is_bigendian) return self.box(fval) @@ -1580,47 +1580,28 @@ result = StringBuilder(10) pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) + NonNativeFloat80 = Float80 - NonNativeFloat96 = Float96 - class Complex192(ComplexFloating, BaseType): + class Complex160(ComplexFloating, BaseType): _attrs_ = () T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex192Box ComponentBoxType = interp_boxes.W_Float96Box + NonNativeComplex160 = Complex160 - NonNativeComplex192 = Complex192 + if interp_boxes.long_double_size == 12: + Float80.storage_bytes = 12 + Float96 = Float80 + Complex192 = Complex160 + elif interp_boxes.long_double_size == 16: + Float80.storage_bytes = 16 + Float128 = Float80 + Complex256 = Complex160 + else: + raise ImportError("Unsupported size for long double") -elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: - class Float128(BaseType, Float): - _attrs_ = () - - T = rffi.LONGDOUBLE - BoxType = interp_boxes.W_Float128Box - format_code = "q" - - def runpack_str(self, s): - assert len(s) == 16 - fval = unpack_float80(s, native_is_bigendian) - return self.box(fval) - - def byteswap(self, w_v): - value = self.unbox(w_v) - result = StringBuilder(10) - pack_float80(result, value, 10, not native_is_bigendian) - return self.box(unpack_float80(result.build(), native_is_bigendian)) - - NonNativeFloat128 = Float128 - - class Complex256(ComplexFloating, BaseType): - _attrs_ = () - - T = rffi.LONGDOUBLE - BoxType = interp_boxes.W_Complex256Box - ComponentBoxType = interp_boxes.W_Float128Box - - NonNativeComplex256 = Complex256 class BaseStringType(object): _mixin_ = True @@ -1696,7 +1677,7 @@ for j in range(i + 1, self.size): arr.storage[j] = '\x00' return interp_boxes.W_StringBox(arr, 0, arr.dtype) - + class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Wed Mar 27 21:29:08 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 27 Mar 2013 21:29:08 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: merge dtype declarations for longdouble Message-ID: <20130327202908.0F1301C304A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62840:78b3ee37137e Date: 2013-03-23 02:44 +0000 http://bitbucket.org/pypy/pypy/changeset/78b3ee37137e/ Log: merge dtype declarations for longdouble 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 @@ -480,52 +480,37 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: - self.w_float96dtype = W_Dtype( + if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size > 8: + self.w_longdouble = W_Dtype( types.Float96(), num=13, kind=FLOATINGLTR, - name="float96", + name="", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float96Box), aliases=["longdouble", "longfloat"], ) - self.w_complex192dtype = W_ComplexDtype( + self.w_clongdouble = W_ComplexDtype( types.Complex192(), num=16, kind=COMPLEXLTR, - name="complex192", + name="", char="G", w_box_type = space.gettypefor(interp_boxes.W_Complex192Box), alternate_constructors=[space.w_complex], aliases=["clongdouble", "clongfloat"], - float_type = self.w_float96dtype, + float_type = self.w_longdouble, ) - self.w_longdouble = self.w_float96dtype - self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: - self.w_float128dtype = W_Dtype( - types.Float128(), - num=13, - kind=FLOATINGLTR, - name="float128", - char="g", - w_box_type=space.gettypefor(interp_boxes.W_Float128Box), - aliases=["longdouble", "longfloat"], - ) - self.w_complex256dtype = W_ComplexDtype( - types.Complex256(), - num=16, - kind=COMPLEXLTR, - name="complex256", - char="G", - w_box_type = space.gettypefor(interp_boxes.W_Complex256Box), - alternate_constructors=[space.w_complex], - aliases=["clongdouble", "clongfloat"], - float_type = self.w_float128dtype, - ) - self.w_longdouble = self.w_float128dtype - self.w_clongdouble = self.w_complex256dtype + if interp_boxes.long_double_size == 12: + self.w_longdouble.name = "float96" + self.w_float96dtype = self.w_longdouble + self.w_clongdouble.name = "complex192" + self.w_complex192dtype = self.w_clongdouble + elif interp_boxes.long_double_size == 16: + self.w_longdouble.name = "float128" + self.w_float128dtype = self.w_longdouble + self.w_clongdouble.name = "complex256" + self.w_complex256dtype = self.w_clongdouble elif interp_boxes.ENABLED_LONG_DOUBLE: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] From noreply at buildbot.pypy.org Wed Mar 27 21:29:09 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 27 Mar 2013 21:29:09 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: merge implementations of W_Float96Box and W_Float128Box, etc. Message-ID: <20130327202909.50F051C3027@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62841:0d1617b3c655 Date: 2013-03-25 16:02 +0000 http://bitbucket.org/pypy/pypy/changeset/0d1617b3c655/ Log: merge implementations of W_Float96Box and W_Float128Box, etc. diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -79,13 +79,13 @@ ] if long_double_size == 16: long_double_dtypes += [ - ('float128', 'interp_boxes.W_Float128Box'), - ('complex256', 'interp_boxes.W_Complex256Box'), + ('float128', 'interp_boxes.W_LongDoubleBox'), + ('complex256', 'interp_boxes.W_CLongDoubleBox'), ] elif long_double_size == 12: long_double_dtypes += [ - ('float96', 'interp_boxes.W_Float96Box'), - ('complex192', 'interp_boxes.W_Complex192Box'), + ('float96', 'interp_boxes.W_LongDoubleBox'), + ('complex192', 'interp_boxes.W_CLongDoubleBox'), ] for dt, box in long_double_dtypes: interpleveldefs[dt] = box 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 @@ -346,34 +346,34 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if ENABLED_LONG_DOUBLE and long_double_size == 12: - class W_Float96Box(W_FloatingBox, PrimitiveBox): - descr__new__, _get_dtype = new_dtype_getter("float96") +if ENABLED_LONG_DOUBLE and long_double_size > 8: + class W_LongDoubleBox(W_FloatingBox, PrimitiveBox): + @staticmethod + def _get_dtype(space): + from pypy.module.micronumpy.interp_dtype import get_dtype_cache + return get_dtype_cache(space).w_longdouble - W_LongDoubleBox = W_Float96Box + def descr__new__(space, w_subtype, w_value): + dtype = W_LongDoubleBox._get_dtype(space) + return dtype.itemtype.coerce_subtype(space, w_subtype, w_value) - class W_Complex192Box(ComplexBox, W_ComplexFloatingBox): - descr__new__, _get_dtype = new_dtype_getter("complex192") - _COMPONENTS_BOX = W_Float96Box - W_CLongDoubleBox = W_Complex192Box + class W_CLongDoubleBox(ComplexBox, W_ComplexFloatingBox): + @staticmethod + def _get_dtype(space): + from pypy.module.micronumpy.interp_dtype import get_dtype_cache + return get_dtype_cache(space).w_clongdouble -elif ENABLED_LONG_DOUBLE and long_double_size == 16: - class W_Float128Box(W_FloatingBox, PrimitiveBox): - descr__new__, _get_dtype = new_dtype_getter("float128") - W_LongDoubleBox = W_Float128Box - - class W_Complex256Box(ComplexBox, W_ComplexFloatingBox): - descr__new__, _get_dtype = new_dtype_getter("complex256") - _COMPONENTS_BOX = W_Float128Box - - W_CLongDoubleBox = W_Complex256Box + def descr__new__(space, w_subtype, w_value): + dtype = W_CLongDoubleBox._get_dtype(space) + return dtype.itemtype.coerce_subtype(space, w_subtype, w_value) + _COMPONENTS_BOX = W_LongDoubleBox elif ENABLED_LONG_DOUBLE: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box - + W_GenericBox.typedef = TypeDef("generic", __module__ = "numpypy", @@ -539,33 +539,25 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if ENABLED_LONG_DOUBLE and long_double_size == 12: - W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), +if ENABLED_LONG_DOUBLE and long_double_size > 8: + W_LongDoubleBox.typedef = TypeDef("float00", (W_FloatingBox.typedef), __module__ = "numpypy", - __new__ = interp2app(W_Float96Box.descr__new__.im_func), + __new__ = interp2app(W_LongDoubleBox.descr__new__.im_func), ) - W_Complex192Box.typedef = TypeDef("complex192", (W_ComplexFloatingBox.typedef, complex_typedef), + W_CLongDoubleBox.typedef = TypeDef("complex00", (W_ComplexFloatingBox.typedef, complex_typedef), __module__ = "numpypy", - __new__ = interp2app(W_Complex192Box.descr__new__.im_func), + __new__ = interp2app(W_CLongDoubleBox.descr__new__.im_func), real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) - -elif ENABLED_LONG_DOUBLE and long_double_size == 16: - W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), - __module__ = "numpypy", - - __new__ = interp2app(W_Float128Box.descr__new__.im_func), - ) - - W_Complex256Box.typedef = TypeDef("complex256", (W_ComplexFloatingBox.typedef, complex_typedef), - __module__ = "numpypy", - __new__ = interp2app(W_Complex256Box.descr__new__.im_func), - real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), - imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), - ) + if long_double_size == 12: + W_LongDoubleBox.name = "float96" + W_CLongDoubleBox.name = "complex192" + elif long_double_size == 16: + W_LongDoubleBox.name = "float128" + W_CLongDoubleBox.name = "complex256" W_FlexibleBox.typedef = TypeDef("flexible", W_GenericBox.typedef, __module__ = "numpypy", 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 @@ -482,21 +482,21 @@ ) if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size > 8: self.w_longdouble = W_Dtype( - types.Float96(), + types.Float80(), num=13, kind=FLOATINGLTR, name="", char="g", - w_box_type=space.gettypefor(interp_boxes.W_Float96Box), + w_box_type=space.gettypefor(interp_boxes.W_LongDoubleBox), aliases=["longdouble", "longfloat"], ) self.w_clongdouble = W_ComplexDtype( - types.Complex192(), + types.Complex160(), num=16, kind=COMPLEXLTR, name="", char="G", - w_box_type = space.gettypefor(interp_boxes.W_Complex192Box), + w_box_type = space.gettypefor(interp_boxes.W_CLongDoubleBox), alternate_constructors=[space.w_complex], aliases=["clongdouble", "clongfloat"], float_type = self.w_longdouble, 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 @@ -1567,7 +1567,7 @@ _attrs_ = () T = rffi.LONGDOUBLE - BoxType = interp_boxes.W_Float96Box + BoxType = interp_boxes.W_LongDoubleBox format_code = "q" def runpack_str(self, s): @@ -1587,18 +1587,12 @@ _attrs_ = () T = rffi.LONGDOUBLE - BoxType = interp_boxes.W_Complex192Box - ComponentBoxType = interp_boxes.W_Float96Box + BoxType = interp_boxes.W_CLongDoubleBox + ComponentBoxType = interp_boxes.W_LongDoubleBox NonNativeComplex160 = Complex160 - if interp_boxes.long_double_size == 12: - Float80.storage_bytes = 12 - Float96 = Float80 - Complex192 = Complex160 - elif interp_boxes.long_double_size == 16: - Float80.storage_bytes = 16 - Float128 = Float80 - Complex256 = Complex160 + if interp_boxes.long_double_size in (12, 16): + Float80.storage_bytes = interp_boxes.long_double_size else: raise ImportError("Unsupported size for long double") From noreply at buildbot.pypy.org Wed Mar 27 21:29:10 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 27 Mar 2013 21:29:10 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: Don't use convert_{real|imag}_to indirection in W_ComplexFloatingBox Message-ID: <20130327202910.865621C3027@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62842:57de9f69aee0 Date: 2013-03-27 19:31 +0000 http://bitbucket.org/pypy/pypy/changeset/57de9f69aee0/ Log: Don't use convert_{real|imag}_to indirection in W_ComplexFloatingBox 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 @@ -9,6 +9,7 @@ from pypy.objspace.std.complextype import complex_typedef from rpython.rlib.rarithmetic import LONG_BIT from rpython.rtyper.lltypesystem import rffi +from rpython.rlib.objectmodel import specialize from rpython.tool.sourcetools import func_with_new_name from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage @@ -324,15 +325,18 @@ class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () + + @specialize.argtype(0) def descr_get_real(self, space): dtype = self._COMPONENTS_BOX._get_dtype(space) - box = self.convert_real_to(dtype) + box = dtype.box(self.real) assert isinstance(box, self._COMPONENTS_BOX) return space.wrap(box) + @specialize.argtype(0) def descr_get_imag(self, space): dtype = self._COMPONENTS_BOX._get_dtype(space) - box = self.convert_imag_to(dtype) + box = dtype.box(self.imag) assert isinstance(box, self._COMPONENTS_BOX) return space.wrap(box) @@ -549,8 +553,8 @@ W_CLongDoubleBox.typedef = TypeDef("complex00", (W_ComplexFloatingBox.typedef, complex_typedef), __module__ = "numpypy", __new__ = interp2app(W_CLongDoubleBox.descr__new__.im_func), - real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), - imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), + real = GetSetProperty(W_CLongDoubleBox.descr_get_real), + imag = GetSetProperty(W_CLongDoubleBox.descr_get_imag), ) if long_double_size == 12: W_LongDoubleBox.name = "float96" @@ -592,13 +596,13 @@ W_Complex128Box.typedef = TypeDef("complex128", (W_ComplexFloatingBox.typedef, complex_typedef), __module__ = "numpypy", __new__ = interp2app(W_Complex128Box.descr__new__.im_func), - real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), - imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), + real = GetSetProperty(W_Complex128Box.descr_get_real), + imag = GetSetProperty(W_Complex128Box.descr_get_imag), ) W_Complex64Box.typedef = TypeDef("complex64", (W_ComplexFloatingBox.typedef), __module__ = "numpypy", __new__ = interp2app(W_Complex64Box.descr__new__.im_func), - real = GetSetProperty(W_ComplexFloatingBox .descr_get_real), - imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), + real = GetSetProperty(W_Complex64Box.descr_get_real), + imag = GetSetProperty(W_Complex64Box.descr_get_imag), ) From noreply at buildbot.pypy.org Wed Mar 27 21:29:47 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 27 Mar 2013 21:29:47 +0100 (CET) Subject: [pypy-commit] pypy longdouble: false start Message-ID: <20130327202947.7E8D81C3027@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble Changeset: r62843:61977b89cac0 Date: 2013-03-27 20:28 +0000 http://bitbucket.org/pypy/pypy/changeset/61977b89cac0/ Log: false start From noreply at buildbot.pypy.org Wed Mar 27 22:56:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 27 Mar 2013 22:56:14 +0100 (CET) Subject: [pypy-commit] buildbot default: reenable macosx64 nightly Message-ID: <20130327215614.4464A1C3027@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r765:adf1e4813691 Date: 2013-03-27 17:54 -0400 http://bitbucket.org/pypy/buildbot/changeset/adf1e4813691/ Log: reenable macosx64 nightly diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -294,7 +294,7 @@ JITWIN32, # on aurora JITFREEBSD64, # on headless JITFREEBSD964, # on exarkun's freebsd - #JITMACOSX64, # no currently working machine + JITMACOSX64, # on xerxes ], branch=None, hour=0, minute=0), Nightly("nightly-2-00", [ From noreply at buildbot.pypy.org Wed Mar 27 23:14:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 23:14:10 +0100 (CET) Subject: [pypy-commit] pypy default: Attempt to dump a bit more information when hitting this error. Message-ID: <20130327221410.94CF01C2FC6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62844:8613b726b6e5 Date: 2013-03-27 23:13 +0100 http://bitbucket.org/pypy/pypy/changeset/8613b726b6e5/ Log: Attempt to dump a bit more information when hitting this error. diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -879,9 +879,9 @@ for name, defaultval in self._staticdefs: if name.startswith('w_'): assert defaultval is None, ( - "%s: default value for '%s' can only be None; " + "%s: default value for '%s' can only be None, got %r; " "use unwrap_spec(...=WrappedDefault(default))" % ( - self._code.identifier, name)) + self._code.identifier, name, defaultval)) defs_w.append(None) else: defs_w.append(space.wrap(defaultval)) From noreply at buildbot.pypy.org Wed Mar 27 23:33:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Mar 2013 23:33:19 +0100 (CET) Subject: [pypy-commit] pypy default: Copy CPython:ecf0ef85c72a: threading fix for OS/X and FreeBSD. Message-ID: <20130327223319.D6BB81C2FC6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62845:bbcac902d424 Date: 2013-03-27 23:33 +0100 http://bitbucket.org/pypy/pypy/changeset/bbcac902d424/ Log: Copy CPython:ecf0ef85c72a: threading fix for OS/X and FreeBSD. diff --git a/rpython/translator/c/src/thread_pthread.c b/rpython/translator/c/src/thread_pthread.c --- a/rpython/translator/c/src/thread_pthread.c +++ b/rpython/translator/c/src/thread_pthread.c @@ -36,6 +36,18 @@ # ifndef THREAD_STACK_SIZE # define THREAD_STACK_SIZE 0 /* use default stack size */ # endif + +# if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 + /* The default stack size for new threads on OSX is small enough that + * we'll get hard crashes instead of 'maximum recursion depth exceeded' + * exceptions. + * + * The default stack size below is the minimal stack size where a + * simple recursive function doesn't cause a hard crash. + */ +# undef THREAD_STACK_SIZE +# define THREAD_STACK_SIZE 0x400000 +# endif /* for safety, ensure a viable minimum stacksize */ # define THREAD_STACK_MIN 0x8000 /* 32kB */ #else /* !_POSIX_THREAD_ATTR_STACKSIZE */ From noreply at buildbot.pypy.org Wed Mar 27 23:53:20 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 27 Mar 2013 23:53:20 +0100 (CET) Subject: [pypy-commit] pypy py3k: restore checking __int__ on subclasses, simplify Message-ID: <20130327225320.E048C1C2FC6@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62846:d8c011188f3f Date: 2013-03-27 15:52 -0700 http://bitbucket.org/pypy/pypy/changeset/d8c011188f3f/ Log: restore checking __int__ on subclasses, simplify diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py --- a/pypy/objspace/std/longobject.py +++ b/pypy/objspace/std/longobject.py @@ -70,10 +70,10 @@ return self.num.tofloat() def int(self, space): - try: - return space.newint(self.num.toint()) - except OverflowError: - return long_long(space, self) + if (type(self) is not W_LongObject and + space.is_overloaded(self, space.w_int, '__int__')): + return W_Object.int(self, space) + return long_long(space, self) def __repr__(self): return '' % self.num.tolong() From noreply at buildbot.pypy.org Thu Mar 28 00:53:18 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 28 Mar 2013 00:53:18 +0100 (CET) Subject: [pypy-commit] pypy py3k: switch to unicodedata 6.0.0 Message-ID: <20130327235318.A1AA01C2FC6@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62847:3087c96d6434 Date: 2013-03-27 16:52 -0700 http://bitbucket.org/pypy/pypy/changeset/3087c96d6434/ Log: switch to unicodedata 6.0.0 diff --git a/pypy/module/unicodedata/__init__.py b/pypy/module/unicodedata/__init__.py --- a/pypy/module/unicodedata/__init__.py +++ b/pypy/module/unicodedata/__init__.py @@ -3,7 +3,7 @@ # This is the default unicodedb used in various places: # - the unicode type # - the regular expression engine -from rpython.rlib.unicodedata import unicodedb_5_2_0 as unicodedb +from rpython.rlib.unicodedata import unicodedb_6_0_0 as unicodedb # to get information about individual unicode chars look at: # http://www.fileformat.info/info/unicode/char/search.htm @@ -14,7 +14,7 @@ interpleveldefs = { 'unidata_version' : 'space.wrap(interp_ucd.ucd.version)', 'ucd_3_2_0' : 'space.wrap(interp_ucd.ucd_3_2_0)', - 'ucd_5_2_0' : 'space.wrap(interp_ucd.ucd_5_2_0)', + 'ucd_6_0_0' : 'space.wrap(interp_ucd.ucd_6_0_0)', 'ucd' : 'space.wrap(interp_ucd.ucd)', '__doc__' : "space.wrap('unicode character database')", } diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -9,7 +9,7 @@ from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.runicode import MAXUNICODE -from rpython.rlib.unicodedata import unicodedb_5_2_0, unicodedb_3_2_0 +from rpython.rlib.unicodedata import unicodedb_6_0_0, unicodedb_3_2_0 from rpython.rlib.runicode import code_to_unichr, ord_accepts_surrogate import sys @@ -324,5 +324,5 @@ **methods) ucd_3_2_0 = UCD(unicodedb_3_2_0) -ucd_5_2_0 = UCD(unicodedb_5_2_0) -ucd = ucd_5_2_0 +ucd_6_0_0 = UCD(unicodedb_6_0_0) +ucd = ucd_6_0_0 From noreply at buildbot.pypy.org Thu Mar 28 02:33:15 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 02:33:15 +0100 (CET) Subject: [pypy-commit] pypy default: Run -A tests even if they require translation options (specified without Message-ID: <20130328013315.53DB31C2FC6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62848:aacdc4ebd49b Date: 2013-03-27 17:50 +0100 http://bitbucket.org/pypy/pypy/changeset/aacdc4ebd49b/ Log: Run -A tests even if they require translation options (specified without the "translation." prefix, e.g. in pypy/module/_continuation/support.py: "continuation=True") diff --git a/pypy/tool/pytest/objspace.py b/pypy/tool/pytest/objspace.py --- a/pypy/tool/pytest/objspace.py +++ b/pypy/tool/pytest/objspace.py @@ -63,6 +63,8 @@ continue if info is None: py.test.skip("cannot runappdirect this test on top of CPython") + if ('translation.' + key) in info: + key = 'translation.' + key has = info.get(key, None) if has != value: #print sys.pypy_translation_info From noreply at buildbot.pypy.org Thu Mar 28 02:33:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 02:33:16 +0100 (CET) Subject: [pypy-commit] pypy default: Fix an obscure issue where destructed SHADOWSTACKREFs could still be Message-ID: <20130328013316.9921A1C304A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62849:a51c7cc17f48 Date: 2013-03-27 20:06 +0100 http://bitbucket.org/pypy/pypy/changeset/a51c7cc17f48/ Log: Fix an obscure issue where destructed SHADOWSTACKREFs could still be occasionally traced, leading to crashes. diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -397,7 +397,11 @@ from rpython.rlib import _rffi_stacklet as _c h = shadowstackref.context h = llmemory.cast_adr_to_ptr(h, _c.handle) - llmemory.raw_free(shadowstackref.base) + base = shadowstackref.base + shadowstackref.base = llmemory.NULL + shadowstackref.top = llmemory.NULL + shadowstackref.context = llmemory.NULL + llmemory.raw_free(base) if h: _c.destroy(h) From noreply at buildbot.pypy.org Thu Mar 28 02:33:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 02:33:17 +0100 (CET) Subject: [pypy-commit] pypy default: Attempt to dump a bit more information when hitting this error. Message-ID: <20130328013317.CA6051C2FC6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62850:8df907eaa517 Date: 2013-03-27 23:13 +0100 http://bitbucket.org/pypy/pypy/changeset/8df907eaa517/ Log: Attempt to dump a bit more information when hitting this error. diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -879,9 +879,9 @@ for name, defaultval in self._staticdefs: if name.startswith('w_'): assert defaultval is None, ( - "%s: default value for '%s' can only be None; " + "%s: default value for '%s' can only be None, got %r; " "use unwrap_spec(...=WrappedDefault(default))" % ( - self._code.identifier, name)) + self._code.identifier, name, defaultval)) defs_w.append(None) else: defs_w.append(space.wrap(defaultval)) From noreply at buildbot.pypy.org Thu Mar 28 02:33:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 02:33:19 +0100 (CET) Subject: [pypy-commit] pypy default: Copy CPython:ecf0ef85c72a: threading fix for OS/X and FreeBSD. Message-ID: <20130328013319.0E9D41C2FC6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62851:e2b3678c1e08 Date: 2013-03-27 23:33 +0100 http://bitbucket.org/pypy/pypy/changeset/e2b3678c1e08/ Log: Copy CPython:ecf0ef85c72a: threading fix for OS/X and FreeBSD. diff --git a/rpython/translator/c/src/thread_pthread.c b/rpython/translator/c/src/thread_pthread.c --- a/rpython/translator/c/src/thread_pthread.c +++ b/rpython/translator/c/src/thread_pthread.c @@ -36,6 +36,18 @@ # ifndef THREAD_STACK_SIZE # define THREAD_STACK_SIZE 0 /* use default stack size */ # endif + +# if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 + /* The default stack size for new threads on OSX is small enough that + * we'll get hard crashes instead of 'maximum recursion depth exceeded' + * exceptions. + * + * The default stack size below is the minimal stack size where a + * simple recursive function doesn't cause a hard crash. + */ +# undef THREAD_STACK_SIZE +# define THREAD_STACK_SIZE 0x400000 +# endif /* for safety, ensure a viable minimum stacksize */ # define THREAD_STACK_MIN 0x8000 /* 32kB */ #else /* !_POSIX_THREAD_ATTR_STACKSIZE */ From noreply at buildbot.pypy.org Thu Mar 28 02:42:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 28 Mar 2013 02:42:50 +0100 (CET) Subject: [pypy-commit] pypy default: backout merge of refactor-call_release_gil branch, breaks translation w jit Message-ID: <20130328014250.BD7451C2FC6@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r62852:3ef424d4281f Date: 2013-03-27 21:42 -0400 http://bitbucket.org/pypy/pypy/changeset/3ef424d4281f/ Log: backout merge of refactor-call_release_gil branch, breaks translation w jit From noreply at buildbot.pypy.org Thu Mar 28 06:12:31 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 28 Mar 2013 06:12:31 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: dispatch set_imag on the dtype Message-ID: <20130328051231.E79631C2FDA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62853:7141f6c474cd Date: 2013-03-28 05:11 +0000 http://bitbucket.org/pypy/pypy/changeset/7141f6c474cd/ Log: dispatch set_imag on the dtype diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -11,7 +11,6 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ raw_storage_setitem, RAW_STORAGE -from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized @@ -103,7 +102,9 @@ return impl def set_imag(self, space, orig_array, w_value): - tmp = self.get_imag(orig_array) + from pypy.module.micronumpy.interp_dtype import W_ComplexDtype + assert isinstance(self.dtype, W_ComplexDtype) + tmp = self.dtype._writable_imag_array(orig_array) tmp.setslice(space, convert_to_array(space, w_value)) # -------------------- applevel get/setitem ----------------------- @@ -321,6 +322,7 @@ orig_array) def argsort(self, space, w_axis): + from pypy.module.micronumpy.arrayimpl.sort import argsort_array return argsort_array(self, space, w_axis) def base(self): diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -1,3 +1,4 @@ +from rpython.rlib.objectmodel import specialize from pypy.module.micronumpy.arrayimpl import base from pypy.module.micronumpy.base import W_NDimArray, convert_to_array @@ -73,7 +74,7 @@ dtype = self.dtype.float_type or self.dtype if len(w_arr.get_shape()) > 0: raise OperationError(space.w_ValueError, space.wrap( - "could not broadcast input array from shape " + + "could not broadcast input array from shape " + "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) if self.dtype.is_complex_type(): @@ -96,19 +97,21 @@ return scalar def set_imag(self, space, orig_array, w_val): - #Only called on complex dtype - assert self.dtype.is_complex_type() w_arr = convert_to_array(space, w_val) - dtype = self.dtype.float_type - if len(w_arr.get_shape()) > 0: + if not w_arr.is_scalar(): raise OperationError(space.w_ValueError, space.wrap( - "could not broadcast input array from shape " + + "could not broadcast input array from shape " + "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) - self.value = self.dtype.itemtype.composite( - self.value.convert_real_to(dtype), - w_arr.get_scalar_value().convert_to(dtype), - ) + value = w_arr.get_scalar_value() + self._set_imag(value) + + @specialize.argtype(1) + def _set_imag(self, value): + from pypy.module.micronumpy.interp_dtype import W_ComplexDtype + assert isinstance(self.dtype, W_ComplexDtype) + dtype = self.dtype.float_type + self.value.imag = value.convert_to(dtype) def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, 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 @@ -11,6 +11,8 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rlib import jit +from pypy.module.micronumpy.arrayimpl.concrete import SliceArray + UNSIGNEDLTR = "u" SIGNEDLTR = "i" @@ -192,6 +194,16 @@ def is_complex_type(self): return True + def _writable_imag_array(self, w_arr): + """helper for BaseConcreteArray.set_imag""" + impl = w_arr.implementation + strides = impl.get_strides() + backstrides = impl.get_backstrides() + float_type = self.float_type + return SliceArray(impl.start + float_type.get_size(), strides, backstrides, + impl.get_shape(), impl, w_arr, dtype=float_type) + + def dtype_from_list(space, w_lst): lst_w = space.listview(w_lst) fields = {} @@ -252,7 +264,7 @@ def dtype_from_spec(space, name): raise OperationError(space.w_NotImplementedError, space.wrap( - "dtype from spec")) + "dtype from spec")) def descr__new__(space, w_subtype, w_dtype): cache = get_dtype_cache(space) From noreply at buildbot.pypy.org Thu Mar 28 09:47:03 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Mar 2013 09:47:03 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: a blog post Message-ID: <20130328084703.87F821C2FDA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4964:5e2e25cdf77a Date: 2013-03-28 10:46 +0200 http://bitbucket.org/pypy/extradoc/changeset/5e2e25cdf77a/ Log: a blog post diff --git a/blog/draft/so_you_want.rst b/blog/draft/so_you_want.rst new file mode 100644 --- /dev/null +++ b/blog/draft/so_you_want.rst @@ -0,0 +1,88 @@ +So you want to try PyPy? +------------------------ + +Hello. + +During the PyCon trip multiple people asked me how exactly they could run +their stuff on PyPy to get the speedups. Now, in an ideal world, +you would just swap CPython with PyPy, everything would run tons of times +faster and everyone would live happily ever after. However, we don't live in +an ideal world and PyPy does not speed up *everything* you could +potentially run. Chances are that you can run your stuff quite a bit faster, but +it requires quite a bit more R&D than just that. This blog post is an attempt to +explain certain steps that might help. So here we go: + +* Download and install PyPy. 2.0 beta 1 or upcoming 2.0 beta 2 would be a good + candidate; it's not called a beta for stability reasons. + +* Run your tests on PyPy. There is absolutely no need for fast software that + does not work. There might be some failures. Usually they're harmless (e.g. + you forgot to close the file); either fix them or at least inspect them. In + short, make sure stuff works. + +* Inspect your stack. In particular, C extensions, while sometimes working, are + a potential source of instability and slowness. Fortunately, + since the introduction of `cffi`_, the ecosystem of PyPy-compatible software + has been growing. Things I know are written with PyPy in mind: + + * the new version of `PyOpenSSL`_ will support PyPy via cffi + + * `pgsql2cffi`_ is the most actively maintained postgres binding for PyPy, + with pg8000 reported working + + * mysql has a `ctypes based implementation`_ (although a cffi-based one would + be definitely better) + + * PyPy 2.0 beta 2 will come with sqlite-using-cffi + + * `lxml-cffi`_ + + * `uWSGI`_, while working, is almost certainly not the best choice. Try + `tornado`_, `twisted.web`_, `cyclone.io`_, `gunicorn`_ or `gevent`_ + (note: gevent support for PyPy is not quite finished; will write about it + in a separate blog post) + + * consult (and contribute to) `pypy compatibility wiki`_ for details + +* Have benchmarks. If you don't have benchmarks, then performance does not + matter for you. Since PyPy's warm-up time is bad (and yes, we know, we're + working on it), you should leave ample time for warm-ups. Five to ten seconds + of continuous computation should be enough. + +* Try them. If you get lucky, the next step might be to deploy and be happy. + If you're unlucky, profile and try to isolate bottlenecks. They might be in + a specific library or they might be in your code. The better you can isolate + them, the higher your chances of understanding what's going on. + +* Don't take it for granted. PyPy's JIT is very good, but there is a variety + of reasons that it might not work how you expect it to. A lot of times it + starts off slow, but a little optimization can improve the speed as much as + 10x. Since PyPy's runtime is less mature than CPython, there are higher + chances of finding an obscure corner of the standard library that might be + atrociously slow. + +* Most importantly, if you run out of options and you have a reproducible + example, **please report it**. A `pypy-dev`_ email, popping into ``#pypy`` + on ``irc.freenode.net``, or getting hold of me on twitter are good ways. + You can also contact me directly at *fijall at gmail.com* as well. While + it's cool if the example is slow, a lot of problems only show up on large + and convoluted examples. As long as I can reproduce it on my machine or I can + log in somewhere, I am usually happy to help. + +* I typically use a combination of `jitviewer`_, `valgrind`_ and + `lsprofcalltree`_ to try to guess what's going on. These tools are all + useful, but use them with care. They usually require quite a bit of + understanding before being useful. Also sometimes they're just plain useless + and you need to write your own analysis. + +I hope this summary of steps to take is useful. We hear a lot of stories +of people trying PyPy, most of them positive, but some of them negative. +If you just post "PyPy didn't work for me" on your blog, that's +cool too, but you're missing an opportunity. The reasons may vary from +something serious like "this is a bad pattern for PyPy GC" to something +completely hilarious like "oh, I left this ``sys._getframe()`` somewhere +in my hot loops for debugging" or "I used the ``logging`` module which uses +``sys._getframe()`` all over the place". + +Cheers, +fijal From noreply at buildbot.pypy.org Thu Mar 28 11:40:33 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 28 Mar 2013 11:40:33 +0100 (CET) Subject: [pypy-commit] pypy refactor-call_release_gil: fix translation Message-ID: <20130328104033.B24531C0619@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: refactor-call_release_gil Changeset: r62854:71e2d672347d Date: 2013-03-28 11:42 +0100 http://bitbucket.org/pypy/pypy/changeset/71e2d672347d/ Log: fix translation diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -275,8 +275,8 @@ def cast_adr_to_int(x): return rffi.cast(lltype.Signed, x) - @staticmethod - def cast_int_to_ptr(x, TYPE): + @specialize.arg(2) + def cast_int_to_ptr(self, x, TYPE): return rffi.cast(TYPE, x) def sizeof(self, S): From noreply at buildbot.pypy.org Thu Mar 28 12:19:22 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 28 Mar 2013 12:19:22 +0100 (CET) Subject: [pypy-commit] pypy default: fix tesT_whatsnew Message-ID: <20130328111922.E9E771C0705@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r62855:439617ed8d85 Date: 2013-03-28 12:19 +0100 http://bitbucket.org/pypy/pypy/changeset/439617ed8d85/ Log: fix tesT_whatsnew 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 @@ -42,6 +42,10 @@ .. branch: rpython-bytearray Rudimentary support for bytearray in RPython +.. branch: refactor-call_release_gil +Fix a bug which casused cffi to return the wrong result when calling a C +function which calls a Python callback which forces the frames + .. branches we don't care about .. branch: autoreds .. branch: reflex-support From noreply at buildbot.pypy.org Thu Mar 28 14:28:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 14:28:29 +0100 (CET) Subject: [pypy-commit] cffi default: Add a comment Message-ID: <20130328132829.4F1061C304F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1201:80e393584295 Date: 2013-03-28 14:27 +0100 http://bitbucket.org/cffi/cffi/changeset/80e393584295/ Log: Add a comment diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py --- a/cffi/vengine_cpy.py +++ b/cffi/vengine_cpy.py @@ -291,6 +291,8 @@ if tp.ellipsis: self._do_collect_type(tp) else: + # don't call _do_collect_type(tp) in this common case, + # otherwise test_autofilled_struct_as_argument fails for type in tp.args: self._do_collect_type(type) self._do_collect_type(tp.result) From noreply at buildbot.pypy.org Thu Mar 28 15:01:09 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 15:01:09 +0100 (CET) Subject: [pypy-commit] cffi default: A bit hackish, but solves exactly issue #71: ffi.typeof(builtin_function). Message-ID: <20130328140109.D5C231C3087@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1202:760ec4641128 Date: 2013-03-28 14:59 +0100 http://bitbucket.org/cffi/cffi/changeset/760ec4641128/ Log: A bit hackish, but solves exactly issue #71: ffi.typeof(builtin_function). diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -137,8 +137,13 @@ """ if isinstance(cdecl, basestring): return self._typeof(cdecl) - else: + if isinstance(cdecl, self.CData): return self._backend.typeof(cdecl) + if isinstance(cdecl, types.BuiltinFunctionType): + res = _builtin_function_type(cdecl) + if res is not None: + return res + raise TypeError(type(cdecl)) def sizeof(self, cdecl): """Return the size in bytes of the argument. It can be a @@ -415,3 +420,17 @@ pass library = FFILibrary() return library, library.__dict__ + +def _builtin_function_type(func): + # a hack to make at least ffi.typeof(builtin_function) work, + # if the builtin function was obtained by 'vengine_cpy'. + import sys + try: + module = sys.modules[func.__module__] + ffi = module._cffi_original_ffi + types_of_builtin_funcs = module._cffi_types_of_builtin_funcs + tp = types_of_builtin_funcs[func] + except (KeyError, AttributeError, TypeError): + return None + else: + return ffi._get_cached_btype(tp) diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py --- a/cffi/vengine_cpy.py +++ b/cffi/vengine_cpy.py @@ -10,6 +10,7 @@ self.verifier = verifier self.ffi = verifier.ffi self._struct_pending_verification = {} + self._types_of_builtin_functions = {} def patch_extension_kwds(self, kwds): pass @@ -149,6 +150,8 @@ # functions from the module to the 'library' object, and setting # up the FFILibrary class with properties for the global C variables. self._load(module, 'loaded', library=library) + module._cffi_original_ffi = self.ffi + module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions return library def _get_declarations(self): @@ -384,7 +387,9 @@ def _loaded_cpy_function(self, tp, name, module, library): if tp.ellipsis: return - setattr(library, name, getattr(module, name)) + func = getattr(module, name) + setattr(library, name, func) + self._types_of_builtin_functions[func] = tp # ---------- # named structs diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1582,3 +1582,11 @@ py.test.raises(TypeError, lib.seeme2, None) py.test.raises(TypeError, lib.seeme1, 0.0) py.test.raises(TypeError, lib.seeme2, 0.0) + +def test_typeof_function(): + ffi = FFI() + ffi.cdef("int foo(int, char);") + lib = ffi.verify("int foo(int x, char y) { return 42; }") + ctype = ffi.typeof(lib.foo) + assert len(ctype.args) == 2 + assert ctype.result == ffi.typeof("int") From noreply at buildbot.pypy.org Thu Mar 28 20:10:05 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 28 Mar 2013 20:10:05 +0100 (CET) Subject: [pypy-commit] pypy default: fix Message-ID: <20130328191005.D5A321C0619@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62856:47afff488720 Date: 2013-03-28 20:07 +0100 http://bitbucket.org/pypy/pypy/changeset/47afff488720/ Log: fix diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -66,7 +66,7 @@ self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) self.mc.datablockwrapper = self.datablockwrapper - self.mc.is_armv6 = self.cpu.backend_name == 'armv6' + self.mc.is_armv6 = self.cpu.backend_name.startswith('armv6') self.target_tokens_currently_compiling = {} def teardown(self): diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -30,7 +30,7 @@ class AbstractARMv7Builder(object): def __init__(self): - pass + self.is_armv6 = False def align(self): while(self.currpos() % FUNC_ALIGN != 0): From noreply at buildbot.pypy.org Thu Mar 28 21:57:06 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 28 Mar 2013 21:57:06 +0100 (CET) Subject: [pypy-commit] pypy default: kill hack and use cpu autodetection to build instruction builder classes for Message-ID: <20130328205706.8F6E41C304F@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62857:24fd80198c9d Date: 2013-03-28 21:30 +0100 http://bitbucket.org/pypy/pypy/changeset/24fd80198c9d/ Log: kill hack and use cpu autodetection to build instruction builder classes for the corresponding architecture diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -5,7 +5,7 @@ from rpython.jit.backend.arm import conditions as c, registers as r from rpython.jit.backend.arm.arch import (WORD, DOUBLE_WORD, FUNC_ALIGN, JITFRAME_FIXED_SIZE) -from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder +from rpython.jit.backend.arm.codebuilder import InstrBuilder, OverwritingBuilder from rpython.jit.backend.arm.locations import imm, StackLocation from rpython.jit.backend.arm.opassembler import ResOpAssembler from rpython.jit.backend.arm.regalloc import (Regalloc, @@ -59,14 +59,13 @@ if we_are_translated(): self.debug = False self.current_clt = looptoken.compiled_loop_token - self.mc = ARMv7Builder() + self.mc = InstrBuilder() self.pending_guards = [] assert self.datablockwrapper is None allblocks = self.get_asmmemmgr_blocks(looptoken) self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, allblocks) self.mc.datablockwrapper = self.datablockwrapper - self.mc.is_armv6 = self.cpu.backend_name.startswith('armv6') self.target_tokens_currently_compiling = {} def teardown(self): @@ -157,7 +156,7 @@ if not self.cpu.propagate_exception_descr: return # not supported (for tests, or non-translated) # - mc = ARMv7Builder() + mc = InstrBuilder() self._store_and_reset_exception(mc, r.r0) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') # make sure ofs fits into a register @@ -242,7 +241,7 @@ # | my own retaddr | <-- sp # +-----------------------+ # - mc = ARMv7Builder() + mc = InstrBuilder() # save argument registers and return address mc.PUSH([reg.value for reg in r.argument_regs] + [r.ip.value, r.lr.value]) # stack is aligned here @@ -283,7 +282,7 @@ # write barriers. It must save all registers, and optionally # all vfp registers. It takes a single argument which is in r0. # It must keep stack alignment accordingly. - mc = ARMv7Builder() + mc = InstrBuilder() # exc0 = exc1 = None mc.PUSH([r.ip.value, r.lr.value]) # push two words to keep alignment @@ -327,7 +326,7 @@ self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): - mc = ARMv7Builder() + mc = InstrBuilder() self._push_all_regs_to_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') # store the gc pattern @@ -439,7 +438,7 @@ self.load_reg(mc, vfpr, r.fp, ofs) def _build_failure_recovery(self, exc, withfloats=False): - mc = ARMv7Builder() + mc = InstrBuilder() self._push_all_regs_to_jitframe(mc, [], withfloats) if exc: @@ -766,7 +765,7 @@ # f) store the address of the new jitframe in the shadowstack # c) set the gcmap field to 0 in the new jitframe # g) restore registers and return - mc = ARMv7Builder() + mc = InstrBuilder() self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame # and the expected_size pushed in _check_stack_frame @@ -826,7 +825,7 @@ self.target_tokens_currently_compiling = None def _patch_stackadjust(self, adr, allocated_depth): - mc = ARMv7Builder() + mc = InstrBuilder() mc.gen_load_int(r.lr.value, allocated_depth) mc.copy_to_raw_memory(adr) @@ -862,7 +861,7 @@ # patch the guard jumpt to the stub # overwrite the generate NOP with a B_offs to the pos of the # stub - mc = ARMv7Builder() + mc = InstrBuilder() mc.B_offs(relative_offset, c.get_opposite_of(tok.fcond)) mc.copy_to_raw_memory(guard_pos) else: @@ -941,7 +940,7 @@ self.mc.ASR_ri(resloc.value, resloc.value, 16) def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc): - b = ARMv7Builder() + b = InstrBuilder() patch_addr = faildescr._arm_failure_recovery_block assert patch_addr != 0 b.B(bridge_addr) diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -7,6 +7,7 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rtyper.lltypesystem import lltype, rffi, llmemory from rpython.tool.udir import udir +from rpython.jit.backend.detect_cpu import autodetect clear_cache = rffi.llexternal( "__clear_cache", @@ -30,7 +31,7 @@ class AbstractARMv7Builder(object): def __init__(self): - self.is_armv6 = False + pass def align(self): while(self.currpos() % FUNC_ALIGN != 0): @@ -245,25 +246,31 @@ def currpos(self): raise NotImplementedError + max_size_of_gen_load_int = 2 * WORD def gen_load_int(self, r, value, cond=cond.AL): """r is the register number, value is the value to be loaded to the register""" - if self.is_armv6: - from pypy.jit.backend.arm.conditions import AL - if cond != AL or 0 <= value <= 0xFFFF: - self._load_by_shifting(r, value, cond) - else: - self.LDR_ri(r, reg.pc.value) - self.MOV_rr(reg.pc.value, reg.pc.value) - self.write32(value) - else: - bottom = value & 0xFFFF - top = value >> 16 - self.MOVW_ri(r, bottom, cond) - if top: - self.MOVT_ri(r, top, cond) + bottom = value & 0xFFFF + top = value >> 16 + self.MOVW_ri(r, bottom, cond) + if top: + self.MOVT_ri(r, top, cond) - max_size_of_gen_load_int = 2 * WORD + +class AbstractARMv6Builder(AbstractARMv7Builder): + + def __init__(self): + AbstractARMv7Builder.__init__(self) + + def gen_load_int(self, r, value, cond=cond.AL): + from pypy.jit.backend.arm.conditions import AL + if cond != AL or 0 <= value <= 0xFFFF: + self._load_by_shifting(r, value, cond) + else: + self.LDR_ri(r, reg.pc.value) + self.MOV_rr(reg.pc.value, reg.pc.value) + self.write32(value) + ofs_shift = zip(range(8, 25, 8), range(12, 0, -4)) def _load_by_shifting(self, r, value, c=cond.AL): # to be sure it is only called for the correct cases @@ -276,10 +283,15 @@ t = b | (shift << 8) self.ORR_ri(r, r, imm=t, cond=c) +if autodetect().startswith('armv7'): + AbstractBuilder = AbstractARMv7Builder +else: + AbstractBuilder = AbstractARMv6Builder -class OverwritingBuilder(AbstractARMv7Builder): + +class OverwritingBuilder(AbstractBuilder): def __init__(self, cb, start, size): - AbstractARMv7Builder.__init__(self) + AbstractBuilder.__init__(self) self.cb = cb self.index = start self.end = start + size @@ -293,9 +305,9 @@ self.index += 1 -class ARMv7Builder(BlockBuilderMixin, AbstractARMv7Builder): +class InstrBuilder(BlockBuilderMixin, AbstractBuilder): def __init__(self): - AbstractARMv7Builder.__init__(self) + AbstractBuilder.__init__(self) self.init_block_builder() # # ResOperation --> offset in the assembly. @@ -349,4 +361,4 @@ return self.get_relative_pos() -define_instructions(AbstractARMv7Builder) +define_instructions(AbstractBuilder) diff --git a/rpython/jit/backend/arm/helper/assembler.py b/rpython/jit/backend/arm/helper/assembler.py --- a/rpython/jit/backend/arm/helper/assembler.py +++ b/rpython/jit/backend/arm/helper/assembler.py @@ -1,7 +1,7 @@ from __future__ import with_statement from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.arm import registers as r -from rpython.jit.backend.arm.codebuilder import AbstractARMv7Builder +from rpython.jit.backend.arm.codebuilder import InstrBuilder from rpython.jit.metainterp.history import ConstInt, BoxInt, FLOAT from rpython.rlib.rarithmetic import r_uint, r_longlong, intmask from rpython.jit.metainterp.resoperation import rop @@ -34,8 +34,8 @@ return f def gen_emit_op_ri(name, opname): - ri_op = getattr(AbstractARMv7Builder, '%s_ri' % opname) - rr_op = getattr(AbstractARMv7Builder, '%s_rr' % opname) + ri_op = getattr(InstrBuilder, '%s_ri' % opname) + rr_op = getattr(InstrBuilder, '%s_rr' % opname) def f(self, op, arglocs, regalloc, fcond): assert fcond is not None l0, l1, res = arglocs @@ -48,7 +48,7 @@ return f def gen_emit_op_by_helper_call(name, opname): - helper = getattr(AbstractARMv7Builder, opname) + helper = getattr(InstrBuilder, opname) def f(self, op, arglocs, regalloc, fcond): assert fcond is not None if op.result: @@ -97,7 +97,7 @@ return f def gen_emit_float_op(name, opname): - op_rr = getattr(AbstractARMv7Builder, opname) + op_rr = getattr(InstrBuilder, opname) def f(self, op, arglocs, regalloc, fcond): arg1, arg2, result = arglocs op_rr(self.mc, result.value, arg1.value, arg2.value) @@ -105,7 +105,7 @@ f.__name__ = 'emit_op_%s' % name return f def gen_emit_unary_float_op(name, opname): - op_rr = getattr(AbstractARMv7Builder, opname) + op_rr = getattr(InstrBuilder, opname) def f(self, op, arglocs, regalloc, fcond): arg1, result = arglocs op_rr(self.mc, result.value, arg1.value) diff --git a/rpython/jit/backend/arm/helper/regalloc.py b/rpython/jit/backend/arm/helper/regalloc.py --- a/rpython/jit/backend/arm/helper/regalloc.py +++ b/rpython/jit/backend/arm/helper/regalloc.py @@ -1,6 +1,5 @@ from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.arm import registers as r -from rpython.jit.backend.arm.codebuilder import AbstractARMv7Builder from rpython.jit.metainterp.history import ConstInt, BoxInt, Box, FLOAT from rpython.jit.metainterp.history import ConstInt from rpython.rlib.objectmodel import we_are_translated diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -17,7 +17,7 @@ saved_registers, count_reg_args) from rpython.jit.backend.arm.helper.regalloc import check_imm_arg -from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder +from rpython.jit.backend.arm.codebuilder import InstrBuilder, OverwritingBuilder from rpython.jit.backend.arm.jump import remap_frame_layout from rpython.jit.backend.arm.regalloc import TempInt, TempPtr from rpython.jit.backend.arm.locations import imm @@ -1219,7 +1219,7 @@ baseofs = self.cpu.get_baseofs_of_frame_field() newlooptoken.compiled_loop_token.update_frame_info( oldlooptoken.compiled_loop_token, baseofs) - mc = ARMv7Builder() + mc = InstrBuilder() mc.B(target) mc.copy_to_raw_memory(oldadr) 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 @@ -86,10 +86,10 @@ possible then to re-call invalidate_loop() on the same looptoken, which must invalidate all newer GUARD_NOT_INVALIDATED, but not the old one that already has a bridge attached to it.""" - from rpython.jit.backend.arm.codebuilder import ARMv7Builder + from rpython.jit.backend.arm.codebuilder import InstrBuilder for jmp, tgt in looptoken.compiled_loop_token.invalidate_positions: - mc = ARMv7Builder() + mc = InstrBuilder() mc.B_offs(tgt) mc.copy_to_raw_memory(jmp) # positions invalidated diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -4,7 +4,7 @@ from rpython.rtyper.lltypesystem import lltype from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.backend.arm.codebuilder import ARMv7Builder +from rpython.jit.backend.arm.codebuilder import InstrBuilder from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests from rpython.jit.backend.arm.test.test_runner import boxfloat, constfloat @@ -25,9 +25,9 @@ # ../../test/calling_convention_test.py def make_function_returning_stack_pointer(self): - mc = ARMv7Builder() - mc.MOV_rr(r.r0.value, r.sp.value) - mc.MOV_rr(r.pc.value, r.lr.value) + mc = InstrBuilder() + mc.MOV_rr(r.r0.value, r.sp.value) + mc.MOV_rr(r.pc.value, r.lr.value) return mc.materialize(self.cpu.asmmemmgr, []) def get_alignment_requirements(self): diff --git a/rpython/jit/backend/arm/test/test_instr_codebuilder.py b/rpython/jit/backend/arm/test/test_instr_codebuilder.py --- a/rpython/jit/backend/arm/test/test_instr_codebuilder.py +++ b/rpython/jit/backend/arm/test/test_instr_codebuilder.py @@ -8,7 +8,7 @@ requires_arm_as() -class CodeBuilder(codebuilder.ARMv7Builder): +class CodeBuilder(codebuilder.InstrBuilder): def __init__(self): self.buffer = [] From noreply at buildbot.pypy.org Thu Mar 28 21:57:07 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 28 Mar 2013 21:57:07 +0100 (CET) Subject: [pypy-commit] pypy default: fix test Message-ID: <20130328205707.CED691C304F@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62858:7faf78b5d54d Date: 2013-03-28 21:53 +0100 http://bitbucket.org/pypy/pypy/changeset/7faf78b5d54d/ Log: fix test diff --git a/rpython/jit/backend/arm/test/test_assembler.py b/rpython/jit/backend/arm/test/test_assembler.py --- a/rpython/jit/backend/arm/test/test_assembler.py +++ b/rpython/jit/backend/arm/test/test_assembler.py @@ -240,9 +240,11 @@ x = 0x60002224 self.a.gen_func_prolog() self.a.mc.gen_load_int(r.r1.value, x) + self.a.mc.SUB_ri(r.sp.value, r.sp.value, 8) self.a.mc.MOV_ri(r.r3.value, 8) - self.a.mc.STR_rr(r.r1.value, r.fp.value, r.r3.value) - self.a.mc.LDR_ri(r.r0.value, r.fp.value, 8) + self.a.mc.STR_rr(r.r1.value, r.sp.value, r.r3.value) + self.a.mc.LDR_ri(r.r0.value, r.sp.value, 8) + self.a.mc.ADD_ri(r.sp.value, r.sp.value, 8) self.a.gen_func_epilog() assert run_asm(self.a) == x From noreply at buildbot.pypy.org Thu Mar 28 22:06:39 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 28 Mar 2013 22:06:39 +0100 (CET) Subject: [pypy-commit] pypy default: missing import Message-ID: <20130328210639.E56E31C304F@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62859:395c4f9730c3 Date: 2013-03-28 23:05 +0200 http://bitbucket.org/pypy/pypy/changeset/395c4f9730c3/ Log: missing import diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -1,3 +1,5 @@ +import py + from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.history import JitCellToken from rpython.jit.backend.test.calling_convention_test import CallingConvTests, parse From noreply at buildbot.pypy.org Thu Mar 28 22:53:41 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 28 Mar 2013 22:53:41 +0100 (CET) Subject: [pypy-commit] pypy default: (arigo, bivab) on ARMv6 gen_load_int might need more instructions Message-ID: <20130328215341.E39E11C3082@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62860:17a2a287384c Date: 2013-03-28 22:41 +0100 http://bitbucket.org/pypy/pypy/changeset/17a2a287384c/ Log: (arigo, bivab) on ARMv6 gen_load_int might need more instructions diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -271,6 +271,7 @@ self.MOV_rr(reg.pc.value, reg.pc.value) self.write32(value) + max_size_of_gen_load_int = 4 * WORD ofs_shift = zip(range(8, 25, 8), range(12, 0, -4)) def _load_by_shifting(self, r, value, c=cond.AL): # to be sure it is only called for the correct cases From noreply at buildbot.pypy.org Thu Mar 28 22:53:43 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 28 Mar 2013 22:53:43 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130328215343.4D9E81C3082@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62861:aa0705ea2400 Date: 2013-03-28 22:51 +0100 http://bitbucket.org/pypy/pypy/changeset/aa0705ea2400/ Log: merge heads diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -1,3 +1,5 @@ +import py + from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.history import JitCellToken from rpython.jit.backend.test.calling_convention_test import CallingConvTests, parse From noreply at buildbot.pypy.org Thu Mar 28 23:22:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Mar 2013 23:22:39 +0100 (CET) Subject: [pypy-commit] cffi default: A passing test. Message-ID: <20130328222239.67F0C1C3050@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1203:4adde3131e4f Date: 2013-03-28 23:22 +0100 http://bitbucket.org/cffi/cffi/changeset/4adde3131e4f/ Log: A passing test. diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1590,3 +1590,9 @@ ctype = ffi.typeof(lib.foo) assert len(ctype.args) == 2 assert ctype.result == ffi.typeof("int") + +def test_call_with_voidstar_arg(): + ffi = FFI() + ffi.cdef("int f(void *);") + lib = ffi.verify("int f(void *x) { return ((char*)x)[0]; }") + assert lib.f(b"foobar") == ord(b"f") From noreply at buildbot.pypy.org Fri Mar 29 05:13:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 29 Mar 2013 05:13:07 +0100 (CET) Subject: [pypy-commit] pypy py3k: cpython issue8013: replace asctime/ctime system calls with our own impl that Message-ID: <20130329041307.9964D1C0705@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62862:b702bc169189 Date: 2013-03-28 20:55 -0700 http://bitbucket.org/pypy/pypy/changeset/b702bc169189/ Log: cpython issue8013: replace asctime/ctime system calls with our own impl that accommodates a wider array of years diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -167,10 +167,8 @@ TM_P = lltype.Ptr(tm) c_clock = external('clock', [rffi.TIME_TP], clock_t) c_time = external('time', [rffi.TIME_TP], rffi.TIME_T) -c_ctime = external('ctime', [rffi.TIME_TP], rffi.CCHARP) c_gmtime = external('gmtime', [rffi.TIME_TP], TM_P) c_mktime = external('mktime', [TM_P], rffi.TIME_T) -c_asctime = external('asctime', [TM_P], rffi.CCHARP) c_localtime = external('localtime', [rffi.TIME_TP], TM_P) if _POSIX: c_tzset = external('tzset', [], lltype.Void) @@ -496,16 +494,13 @@ not present, current time as returned by localtime() is used.""" seconds = _get_inttime(space, w_seconds) - - t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw') - t_ref[0] = seconds - p = c_ctime(t_ref) - lltype.free(t_ref, flavor='raw') + with lltype.scoped_alloc(rffi.TIME_TP.TO, 1) as t_ref: + t_ref[0] = seconds + p = c_localtime(t_ref) if not p: raise OperationError(space.w_ValueError, - space.wrap("unconvertible time")) - - return space.wrap(rffi.charp2str(p)[:-1]) # get rid of new line + space.wrap("unconvertible time")) + return _asctime(space, p) # by now w_tup is an optional argument (and not *args) # because of the ext. compiler bugs in handling such arguments (*args, **kwds) @@ -516,12 +511,25 @@ When the time tuple is not present, current time as returned by localtime() is used.""" buf_value = _gettmarg(space, w_tup) - p = c_asctime(buf_value) - if not p: - raise OperationError(space.w_ValueError, - space.wrap("unconvertible time")) + return _asctime(space, buf_value) - return space.wrap(rffi.charp2str(p)[:-1]) # get rid of new line +_wday_names = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] +_mon_names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec"] + +def _asctime(space, t_ref): + # Inspired by Open Group reference implementation available at + # http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html + w, getif = space.wrap, rffi.getintfield + args = [w(_wday_names[getif(t_ref, 'c_tm_wday')]), + w(_mon_names[getif(t_ref, 'c_tm_mon')]), + w(getif(t_ref, 'c_tm_mday')), + w(getif(t_ref, 'c_tm_hour')), + w(getif(t_ref, 'c_tm_min')), + w(getif(t_ref, 'c_tm_sec')), + w(getif(t_ref, 'c_tm_year') + 1900)] + return space.mod(w("%.3s %.3s%3d %.2d:%.2d:%.2d %d"), + space.newtuple(args)) def gmtime(space, w_seconds=None): """gmtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min, diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -43,6 +43,15 @@ assert isinstance(res, str) rctime.ctime(rctime.time()) raises(ValueError, rctime.ctime, 1E200) + for year in [-100, 100, 1000, 2000, 10000]: + try: + testval = rctime.mktime((year, 1, 10) + (0,)*6) + except (ValueError, OverflowError): + # If mktime fails, ctime will fail too. This may happen + # on some platforms. + pass + else: + assert rctime.ctime(testval)[20:] == str(year) def test_gmtime(self): import time as rctime @@ -139,6 +148,13 @@ ltime = rctime.localtime() assert rctime.asctime(tuple(ltime)) == rctime.asctime(ltime) + def test_asctime_large_year(self): + import time as rctime + assert rctime.asctime((12345,) + + (0,) * 8) == 'Mon Jan 1 00:00:00 12345' + assert rctime.asctime((123456789,) + + (0,) * 8) == 'Mon Jan 1 00:00:00 123456789' + def test_accept2dyear_access(self): import time as rctime From noreply at buildbot.pypy.org Fri Mar 29 05:13:08 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 29 Mar 2013 05:13:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: have asctime make the same bounds checks as strftime Message-ID: <20130329041308.E6E151C304F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62863:03b22d5b87f0 Date: 2013-03-28 21:09 -0700 http://bitbucket.org/pypy/pypy/changeset/03b22d5b87f0/ Log: have asctime make the same bounds checks as strftime diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -446,7 +446,7 @@ space.w_DeprecationWarning) # tm_wday does not need checking of its upper-bound since taking "% - # 7" in gettmarg() automatically restricts the range. + # 7" in _gettmarg() automatically restricts the range. if rffi.getintfield(glob_buf, 'c_tm_wday') < -1: raise OperationError(space.w_ValueError, space.wrap("day of week out of range")) @@ -461,6 +461,32 @@ return glob_buf +def _checktm(space, t_ref): + """Checks added to make sure strftime() and asctime() do not crash + Python by indexing blindly into some array for a textual + representation by some bad index (fixes bug #897625). No check for + year or wday since handled in _gettmarg().""" + if not 0 <= rffi.getintfield(t_ref, 'c_tm_mon') <= 11: + raise OperationError(space.w_ValueError, + space.wrap("month out of range")) + if not 1 <= rffi.getintfield(t_ref, 'c_tm_mday') <= 31: + raise OperationError(space.w_ValueError, + space.wrap("day of month out of range")) + if not 0 <= rffi.getintfield(t_ref, 'c_tm_hour') <= 23: + raise OperationError(space.w_ValueError, + space.wrap("hour out of range")) + if not 0 <= rffi.getintfield(t_ref, 'c_tm_min') <= 59: + raise OperationError(space.w_ValueError, + space.wrap("minute out of range")) + if not 0 <= rffi.getintfield(t_ref, 'c_tm_sec') <= 61: + raise OperationError(space.w_ValueError, + space.wrap("seconds out of range")) + # tm_wday does not need checking: "% 7" in _gettmarg() automatically + # restricts the range + if not 0 <= rffi.getintfield(t_ref, 'c_tm_yday') <= 365: + raise OperationError(space.w_ValueError, + space.wrap("day of year out of range")) + def time(space): """time() -> floating point number @@ -511,6 +537,7 @@ When the time tuple is not present, current time as returned by localtime() is used.""" buf_value = _gettmarg(space, w_tup) + _checktm(space, buf_value) return _asctime(space, buf_value) _wday_names = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] @@ -611,29 +638,8 @@ See the library reference manual for formatting codes. When the time tuple is not present, current time as returned by localtime() is used.""" buf_value = _gettmarg(space, w_tup) + _checktm(space, buf_value) - # Checks added to make sure strftime() does not crash Python by - # indexing blindly into some array for a textual representation - # by some bad index (fixes bug #897625). - # No check for year since handled in gettmarg(). - if rffi.getintfield(buf_value, 'c_tm_mon') < 0 or rffi.getintfield(buf_value, 'c_tm_mon') > 11: - raise OperationError(space.w_ValueError, - space.wrap("month out of range")) - if rffi.getintfield(buf_value, 'c_tm_mday') < 1 or rffi.getintfield(buf_value, 'c_tm_mday') > 31: - raise OperationError(space.w_ValueError, - space.wrap("day of month out of range")) - if rffi.getintfield(buf_value, 'c_tm_hour') < 0 or rffi.getintfield(buf_value, 'c_tm_hour') > 23: - raise OperationError(space.w_ValueError, - space.wrap("hour out of range")) - if rffi.getintfield(buf_value, 'c_tm_min') < 0 or rffi.getintfield(buf_value, 'c_tm_min') > 59: - raise OperationError(space.w_ValueError, - space.wrap("minute out of range")) - if rffi.getintfield(buf_value, 'c_tm_sec') < 0 or rffi.getintfield(buf_value, 'c_tm_sec') > 61: - raise OperationError(space.w_ValueError, - space.wrap("seconds out of range")) - if rffi.getintfield(buf_value, 'c_tm_yday') < 0 or rffi.getintfield(buf_value, 'c_tm_yday') > 365: - raise OperationError(space.w_ValueError, - space.wrap("day of year out of range")) # Normalize tm_isdst just in case someone foolishly implements %Z # based on the assumption that tm_isdst falls within the range of # [-1, 1] diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -138,6 +138,7 @@ raises(TypeError, rctime.asctime, (1, 2)) raises(TypeError, rctime.asctime, (1, 2, 3, 4, 5, 6, 'f', 8, 9)) raises(TypeError, rctime.asctime, "foo") + raises(ValueError, rctime.asctime, (1900, -1, 1, 0, 0, 0, 0, 1, -1)) res = rctime.asctime() assert isinstance(res, str) rctime.asctime(rctime.localtime()) From noreply at buildbot.pypy.org Fri Mar 29 05:29:47 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 29 Mar 2013 05:29:47 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: kill ComplexFloating.composite() Message-ID: <20130329042947.2DF8A1C304F@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62864:1e26abd5e420 Date: 2013-03-29 04:29 +0000 http://bitbucket.org/pypy/pypy/changeset/1e26abd5e420/ Log: kill ComplexFloating.composite() diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -71,18 +71,24 @@ def set_real(self, space, orig_array, w_val): w_arr = convert_to_array(space, w_val) - dtype = self.dtype.float_type or self.dtype if len(w_arr.get_shape()) > 0: raise OperationError(space.w_ValueError, space.wrap( "could not broadcast input array from shape " + "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) + value = w_arr.get_scalar_value() if self.dtype.is_complex_type(): - self.value = self.dtype.itemtype.composite( - w_arr.get_scalar_value().convert_to(dtype), - self.value.convert_imag_to(dtype)) + self._set_real(self.value, value) else: - self.value = w_arr.get_scalar_value() + self.value = value + + @specialize.argtype(1) + def _set_real(self, box, value): + from pypy.module.micronumpy.interp_dtype import W_ComplexDtype + assert isinstance(self.dtype, W_ComplexDtype) + float_type = self.dtype.float_type + box.set_real(value.convert_to(float_type)) + def get_imag(self, orig_array): if self.dtype.is_complex_type(): @@ -104,14 +110,14 @@ "(%s) into shape ()" % ( ','.join([str(x) for x in w_arr.get_shape()],)))) value = w_arr.get_scalar_value() - self._set_imag(value) + self._set_imag(self.value, value) @specialize.argtype(1) - def _set_imag(self, value): + def _set_imag(self, box, value): from pypy.module.micronumpy.interp_dtype import W_ComplexDtype assert isinstance(self.dtype, W_ComplexDtype) - dtype = self.dtype.float_type - self.value.imag = value.convert_to(dtype) + float_type = self.dtype.float_type + box.set_imag(value.convert_to(float_type)) def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, 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 @@ -65,6 +65,14 @@ def convert_imag_to(self, dtype): return dtype.box(self.imag) + def set_real(self, box): + assert isinstance(box, self._COMPONENTS_BOX) + self.real = box.value + + def set_imag(self, box): + assert isinstance(box, self._COMPONENTS_BOX) + self.imag = box.value + class W_GenericBox(W_Root): _attrs_ = () 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 @@ -1149,14 +1149,6 @@ return rfloat.NAN, rfloat.NAN return rfloat.INFINITY, rfloat.INFINITY - @specialize.argtype(1) - def composite(self, v1, v2): - assert isinstance(v1, self.ComponentBoxType) - assert isinstance(v2, self.ComponentBoxType) - real = v1.value - imag = v2.value - return self.box_complex(real, imag) - @complex_unary_op def pos(self, v): return v From noreply at buildbot.pypy.org Fri Mar 29 05:31:10 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 29 Mar 2013 05:31:10 +0100 (CET) Subject: [pypy-commit] pypy py3k: pass accept2dyear through space.is_true Message-ID: <20130329043110.DBB5E1C304F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62865:b3acd17f6946 Date: 2013-03-28 21:30 -0700 http://bitbucket.org/pypy/pypy/changeset/b3acd17f6946/ Log: pass accept2dyear through space.is_true diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -432,7 +432,7 @@ if y < 1000: w_accept2dyear = _get_module_object(space, "accept2dyear") - accept2dyear = space.int_w(w_accept2dyear) + accept2dyear = space.is_true(w_accept2dyear) if accept2dyear: if 69 <= y <= 99: diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -166,6 +166,17 @@ finally: rctime.accept2dyear = accept2dyear + def test_accept2dyear_bad(self): + import time as rctime + class X: + def __bool__(self): + raise RuntimeError('boo') + orig, rctime.accept2dyear = rctime.accept2dyear, X() + try: + raises(RuntimeError, rctime.asctime, (200,) + (0,) * 8) + finally: + rctime.accept2dyear = orig + def test_struct_time(self): import time as rctime raises(TypeError, rctime.struct_time) From noreply at buildbot.pypy.org Fri Mar 29 06:02:13 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:13 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: branch to make bridge logging more consistent Message-ID: <20130329050213.75B291C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62866:0c8e562b5a4b Date: 2013-03-27 17:56 +0100 http://bitbucket.org/pypy/pypy/changeset/0c8e562b5a4b/ Log: branch to make bridge logging more consistent From noreply at buildbot.pypy.org Fri Mar 29 06:02:14 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:14 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: start integration test of jitlogparser on actual pypy run Message-ID: <20130329050214.CAA3C1C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62867:a4a0613420c4 Date: 2013-03-27 19:39 +0100 http://bitbucket.org/pypy/pypy/changeset/a4a0613420c4/ Log: start integration test of jitlogparser on actual pypy run diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -1,3 +1,8 @@ +import re +import os.path +import tempfile +import subprocess + from pypy.tool.jitlogparser.parser import (SimpleParser, TraceForOpcode, Function, adjust_bridges, import_log, split_trace, Op, @@ -5,6 +10,8 @@ from pypy.tool.jitlogparser.storage import LoopStorage import py, sys from rpython.jit.backend.detect_cpu import autodetect_main_model +from rpython.tool.logparser import extract_category + def parse(input, **kwds): return SimpleParser.parse_from_input(input, **kwds) @@ -372,3 +379,21 @@ f = Function.from_operations(loop.operations, LoopStorage()) assert len(f.chunks) == 2 +def test_import_log_on_pypy(): + ''' Test import_log and parse_log_counts on a log from actual pypy run + ''' + log_filename = tempfile.mktemp() + pypy = '/Users/kostia/programming/pypy/pypy-c' # FIXME + subprocess.check_call([pypy, + os.path.join(os.path.dirname(__file__), 'y.py')], + env={'PYPYLOG': 'jit-log-opt,jit-backend:%s' % log_filename}) + log, loops = import_log(log_filename) + parse_log_counts(extract_category(log, 'jit-backend-count'), loops) + for loop in loops: + loop.force_asm() + if re.search("file '.*lib-python.*'", loop.comment): + # do not care for _optimize_charset or _mk_bitmap + continue + else: + import pdb; pdb.set_trace() + From noreply at buildbot.pypy.org Fri Mar 29 06:02:16 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:16 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: add test program, ignore more lib-python startup stuff Message-ID: <20130329050216.0EDED1C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62868:bf34393b292e Date: 2013-03-28 16:34 +0100 http://bitbucket.org/pypy/pypy/changeset/bf34393b292e/ Log: add test program, ignore more lib-python startup stuff diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -389,9 +389,11 @@ env={'PYPYLOG': 'jit-log-opt,jit-backend:%s' % log_filename}) log, loops = import_log(log_filename) parse_log_counts(extract_category(log, 'jit-backend-count'), loops) + lib_re = re.compile("file '.*lib-python.*'") for loop in loops: loop.force_asm() - if re.search("file '.*lib-python.*'", loop.comment): + if lib_re.search(loop.comment) or \ + lib_re.search(loop.operations[0].repr()): # do not care for _optimize_charset or _mk_bitmap continue else: diff --git a/pypy/tool/jitlogparser/test/y.py b/pypy/tool/jitlogparser/test/y.py new file mode 100644 --- /dev/null +++ b/pypy/tool/jitlogparser/test/y.py @@ -0,0 +1,24 @@ + +def fn_with_bridges(N): + result = 0 + for x in xrange(N): + if x % 3 == 0: + result += 5 + elif x % 5 == 0: + result += 3 + elif is_prime(x): + result += x + elif x == 99: + result *= 2 + return result + + +def is_prime(x): + for y in xrange(2, x): + if x % y == 0: + return False + return True + + +fn_with_bridges(10000) + From noreply at buildbot.pypy.org Fri Mar 29 06:02:20 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:20 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: merge default Message-ID: <20130329050220.DA52F1C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62869:901682da5cad Date: 2013-03-28 16:37 +0100 http://bitbucket.org/pypy/pypy/changeset/901682da5cad/ Log: merge default diff too long, truncating to 2000 out of 16112 lines diff --git a/.tddium.requirements.txt b/.tddium.requirements.txt new file mode 100644 --- /dev/null +++ b/.tddium.requirements.txt @@ -0,0 +1,1 @@ +pytest diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1409,26 +1409,11 @@ except ImportError: from StringIO import StringIO -try: - from __pypy__.builders import StringBuilder -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO -else: - class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - self.getvalue = self.builder.build - def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -97,18 +97,12 @@ from pickle import StringIO -try: - from pickle import StringBuilderFile -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO - PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringBuilderFile() + self.__f = StringIO() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) @@ -126,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -1,69 +1,69 @@ """ -application level support module for transparent proxies. +application level support module for transparent proxies. """ -from __pypy__ import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() origtype = type -def make_proxy(controller, type=_dummy, obj=_dummy): - """ return a tranparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives on - ProxyOperation instance on each such call. - A non-specified type will default to type(obj) - if obj is specified. +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ - if type is _dummy: - if obj is _dummy: - raise TypeError("you must specify a type or an instance obj of it") - type = origtype(obj) + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj of it") + type = origtype(obj) def perform(opname, *args, **kwargs): operation = ProxyOperation(tp, obj, opname, args, kwargs) - return controller(operation) - tp = tproxy(type, perform) - return tp + return controller(operation) + tp = tproxy(type, perform) + return tp class ProxyOperation(object): def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.opname = opname + self.opname = opname self.args = args self.kwargs = kwargs - if obj is not _dummy: - self.obj = obj + if obj is not _dummy: + self.obj = obj def delegate(self): - """ return result from delegating this operation to the - underyling self.obj - which must exist and is usually - provided through the initial make_proxy(..., obj=...) - creation. - """ + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ try: obj = getattr(self, 'obj') - except AttributeError: + except AttributeError: raise TypeError("proxy does not have an underlying 'obj', " "cannot delegate") - objattr = getattr(obj, self.opname) - res = objattr(*self.args, **self.kwargs) - if self.opname == "__getattribute__": + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) + if self.opname == "__getattribute__": if (isinstance(res, MethodType) and res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.obj: + if res is self.obj: res = self.proxyobj - return res + return res def __repr__(self): args = ", ".join([repr(x) for x in self.args]) - args = "<0x%x>, " % id(self.proxyobj) + args + args = "<0x%x>, " % id(self.proxyobj) + args if self.kwargs: - args += ", ".join(["%s=%r" % item + args += ", ".join(["%s=%r" % item for item in self.kwargs.items()]) return "" %( type(self.proxyobj).__name__, self.opname, args) diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -189,11 +189,6 @@ BoolOption("withtproxy", "support transparent proxies", default=True), - BoolOption("withsmallint", "use tagged integers", - default=False, - requires=[("objspace.std.withprebuiltint", False), - ("translation.taggedpointers", True)]), - BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -204,9 +199,7 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False, - requires=[("objspace.std.withsmallint", False)]), - # ^^^ because of missing delegate_xx2yy + default=False), BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/config/test/test_pypyoption.py b/pypy/config/test/test_pypyoption.py --- a/pypy/config/test/test_pypyoption.py +++ b/pypy/config/test/test_pypyoption.py @@ -11,11 +11,11 @@ assert conf.objspace.usemodules.gc - conf.objspace.std.withsmallint = True - assert not conf.objspace.std.withprebuiltint + conf.objspace.std.withmapdict = True + assert conf.objspace.std.withmethodcache conf = get_pypy_config() - conf.objspace.std.withprebuiltint = True - py.test.raises(ConfigError, "conf.objspace.std.withsmallint = True") + conf.objspace.std.withmethodcache = False + py.test.raises(ConfigError, "conf.objspace.std.withmapdict = True") def test_conflicting_gcrootfinder(): conf = get_pypy_config() diff --git a/pypy/doc/config/objspace.std.withsmallint.txt b/pypy/doc/config/objspace.std.withsmallint.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.std.withsmallint.txt +++ /dev/null @@ -1,6 +0,0 @@ -Use "tagged pointers" to represent small enough integer values: Integers that -fit into 31 bits (respective 63 bits on 64 bit machines) are not represented by -boxing them in an instance of ``W_IntObject``. Instead they are represented as a -pointer having the lowest bit set and the rest of the bits used to store the -value of the integer. This gives a small speedup for integer operations as well -as better memory behaviour. diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -8,7 +8,7 @@ implement a pypy module. A typical rpython file is likely to contain many `import` statements:: - from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -19,7 +19,7 @@ - A more direct declarative way to write Typedef:: - class W_Socket(Wrappable): + class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -1,5 +1,5 @@ =================================== -Bytecode Interpreter +Bytecode Interpreter =================================== .. contents:: @@ -9,8 +9,8 @@ Introduction and Overview =============================== -This document describes the implementation of PyPy's -Bytecode Interpreter and related Virtual Machine functionalities. +This document describes the implementation of PyPy's +Bytecode Interpreter and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of CPython's Virtual Machine: It processes code objects parsed and compiled from @@ -32,14 +32,14 @@ translated with the rest of PyPy. Code objects contain -condensed information about their respective functions, class and +condensed information about their respective functions, class and module body source codes. Interpreting such code objects means instantiating and initializing a `Frame class`_ and then -calling its ``frame.eval()`` method. This main entry point -initialize appropriate namespaces and then interprets each +calling its ``frame.eval()`` method. This main entry point +initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to inspection -of the virtual machine's bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -47,103 +47,103 @@ >>> dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) - 6 BINARY_ADD - 7 RETURN_VALUE + 6 BINARY_ADD + 7 RETURN_VALUE CPython and PyPy are stack-based virtual machines, i.e. they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and pushing and pulling black -box objects to and from this value stack. The bytecode interpreter +box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object space`_. In order to implement a conditional branch in a program's execution, however, it needs to gain minimal knowledge about a wrapped object. Thus, each object space has to offer a ``is_true(w_obj)`` operation which returns an -interpreter-level boolean value. +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and application-level`_ code. In short, interpreter-level is executed -directly on the machine and invoking application-level functions -leads to an bytecode interpretation indirection. However, +directly on the machine and invoking application-level functions +leads to an bytecode interpretation indirection. However, special care must be taken regarding exceptions because -application level exceptions are wrapped into ``OperationErrors`` -which are thus distinguished from plain interpreter-level exceptions. +application level exceptions are wrapped into ``OperationErrors`` +which are thus distinguished from plain interpreter-level exceptions. See `application level exceptions`_ for some more information -on ``OperationErrors``. +on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware of whether a particular function invocation +caller to be unaware of whether a particular function invocation leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow transparent invocation of application-level helpers -(``app2interp``) at interpreter-level. +(``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to care for exposing its -basic code, frame, module and function objects to application-level -code. Such runtime introspection and modification abilities are -implemented via `interpreter descriptors`_ (also see Raymond Hettingers -`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level +code. Such runtime introspection and modification abilities are +implemented via `interpreter descriptors`_ (also see Raymond Hettingers +`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `function argument parsing`_. Python as a -language offers flexible ways of providing and receiving arguments -for a particular function invocation. Not only does it take special care +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments +for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code in order to infer the types of all values flowing across function -calls. +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see rather static -program flows with homogeneous name-value assignments on -function invocations. +time`_ in order to let the annotator only see rather static +program flows with homogeneous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass .. _`initialization time`: translation.html#initialization-time -.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level +.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level .. _`wrapped`: coding-guide.html#wrapping-rules .. _`object space`: objspace.html .. _`application level exceptions`: coding-guide.html#applevel-exceptions .. _`here`: coding-guide.html#modules -Bytecode Interpreter Implementation Classes +Bytecode Interpreter Implementation Classes ================================================ -.. _`Frame class`: -.. _`Frame`: +.. _`Frame class`: +.. _`Frame`: Frame classes ----------------- -The concept of Frames is pervasive in executing programs and +The concept of Frames is pervasive in executing programs and on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame -instances hold the following state: +instances hold the following state: -- the local scope holding name-value bindings, usually implemented +- the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects - a blockstack containing (nested) information regarding the - control flow of a function (such as ``while`` and ``try`` constructs) + control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object from and puts results on. - a reference to the *globals* dictionary, containing - module-level name-value bindings + module-level name-value bindings -- debugging information from which a current line-number and - file location can be constructed for tracebacks +- debugging information from which a current line-number and + file location can be constructed for tracebacks Moreover the Frame class itself has a number of methods which implement the actual bytecodes found in a code object. The methods of the ``PyFrame`` @@ -156,104 +156,104 @@ - nested scope support is added to the ``PyFrame`` class in `pypy/interpreter/nestedscope.py`_. -.. _Code: +.. _Code: -Code Class ------------- +Code Class +------------ -PyPy's code objects contain the same information found in CPython's code objects. -They differ from Function_ objects in that they are only immutable representations +PyPy's code objects contain the same information found in CPython's code objects. +They differ from Function_ objects in that they are only immutable representations of source code and don't contain execution state or references to the execution -environment found in `Frames`. Frames and Functions have references +environment found in `Frames`. Frames and Functions have references to a code object. Here is a list of Code attributes: -* ``co_flags`` flags if this code object has nested scopes/generators +* ``co_flags`` flags if this code object has nested scopes/generators * ``co_stacksize`` the maximum depth the stack can reach while executing the code -* ``co_code`` the actual bytecode string - -* ``co_argcount`` number of arguments this code object expects +* ``co_code`` the actual bytecode string + +* ``co_argcount`` number of arguments this code object expects * ``co_varnames`` a tuple of all argument names pass to this code object -* ``co_nlocals`` number of local variables +* ``co_nlocals`` number of local variables * ``co_names`` a tuple of all names used in the code object -* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object -* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes -* ``co_freevars`` a tuple of Cell names from "above" scopes - -* ``co_filename`` source file this code object was compiled from -* ``co_firstlineno`` the first linenumber of the code object in its source file -* ``co_name`` name of the code object (often the function name) -* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes +* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object +* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes +* ``co_freevars`` a tuple of Cell names from "above" scopes + +* ``co_filename`` source file this code object was compiled from +* ``co_firstlineno`` the first linenumber of the code object in its source file +* ``co_name`` name of the code object (often the function name) +* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes In PyPy, code objects also have the responsibility of creating their Frame_ objects via the `'create_frame()`` method. With proper parser and compiler support this would allow to create custom Frame objects extending the execution of functions in various ways. The several Frame_ classes already utilize this flexibility -in order to implement Generators and Nested Scopes. +in order to implement Generators and Nested Scopes. -.. _Function: +.. _Function: Function and Method classes ---------------------------- -The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) -represents a Python function. A ``Function`` carries the following -main attributes: +The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) +represents a Python function. A ``Function`` carries the following +main attributes: -* ``func_doc`` the docstring (or None) -* ``func_name`` the name of the function -* ``func_code`` the Code_ object representing the function source code +* ``func_doc`` the docstring (or None) +* ``func_name`` the name of the function +* ``func_code`` the Code_ object representing the function source code * ``func_defaults`` default values for the function (built at function definition time) -* ``func_dict`` dictionary for additional (user-defined) function attributes -* ``func_globals`` reference to the globals dictionary -* ``func_closure`` a tuple of Cell references +* ``func_dict`` dictionary for additional (user-defined) function attributes +* ``func_globals`` reference to the globals dictionary +* ``func_closure`` a tuple of Cell references ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method object holding a binding to an instance or a class. Finally, ``Functions`` -and ``Methods`` both offer a ``call_args()`` method which executes -the function given an `Arguments`_ class instance. +and ``Methods`` both offer a ``call_args()`` method which executes +the function given an `Arguments`_ class instance. -.. _Arguments: -.. _`function argument parsing`: +.. _Arguments: +.. _`function argument parsing`: -Arguments Class --------------------- +Arguments Class +-------------------- The Argument class (in `pypy/interpreter/argument.py`_) is -responsible for parsing arguments passed to functions. +responsible for parsing arguments passed to functions. Python has rather complex argument-passing concepts: -- positional arguments +- positional arguments -- keyword arguments specified by name +- keyword arguments specified by name - default values for positional arguments, defined at function - definition time + definition time - "star args" allowing a function to accept remaining - positional arguments + positional arguments -- "star keyword args" allow a function to accept additional - arbitrary name-value bindings +- "star keyword args" allow a function to accept additional + arbitrary name-value bindings -Moreover, a Function_ object can get bound to a class or instance +Moreover, a Function_ object can get bound to a class or instance in which case the first argument to the underlying function becomes -the bound object. The ``Arguments`` provides means to allow all -this argument parsing and also cares for error reporting. +the bound object. The ``Arguments`` provides means to allow all +this argument parsing and also cares for error reporting. -.. _`Module`: +.. _`Module`: -Module Class -------------------- +Module Class +------------------- -A ``Module`` instance represents execution state usually constructed +A ``Module`` instance represents execution state usually constructed from executing the module's source file. In addition to such a module's -global ``__dict__`` dictionary it has the following application level -attributes: +global ``__dict__`` dictionary it has the following application level +attributes: * ``__doc__`` the docstring of the module -* ``__file__`` the source filename from which this module was instantiated -* ``__path__`` state used for relative imports +* ``__file__`` the source filename from which this module was instantiated +* ``__path__`` state used for relative imports Apart from the basic Module used for importing application-level files there is a more refined @@ -262,80 +262,80 @@ level and at interpreter level. See the ``__builtin__`` module's `pypy/module/__builtin__/__init__.py`_ file for an example and the higher level `chapter on Modules in the coding -guide`_. +guide`_. .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/ -.. _`chapter on Modules in the coding guide`: coding-guide.html#modules +.. _`chapter on Modules in the coding guide`: coding-guide.html#modules -.. _`Gateway classes`: +.. _`Gateway classes`: -Gateway classes ----------------------- +Gateway classes +---------------------- A unique PyPy property is the ability to easily cross the barrier between interpreted and machine-level code (often referred to as -the difference between `interpreter-level and application-level`_). -Be aware that the according code (in `pypy/interpreter/gateway.py`_) +the difference between `interpreter-level and application-level`_). +Be aware that the according code (in `pypy/interpreter/gateway.py`_) for crossing the barrier in both directions is somewhat involved, mostly due to the fact that the type-inferring annotator needs to keep track of the types of objects flowing -across those barriers. +across those barriers. .. _typedefs: Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to make an interpreter-level function available at -application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. -Such a function usually takes a ``space`` argument and any number +In order to make an interpreter-level function available at +application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. +Such a function usually takes a ``space`` argument and any number of positional arguments. Additionally, such functions can define an ``unwrap_spec`` telling the ``interp2app`` logic how application-level provided arguments should be unwrapped -before the actual interpreter-level function is invoked. -For example, `interpreter descriptors`_ such as the ``Module.__new__`` -method for allocating and constructing a Module instance are -defined with such code:: +before the actual interpreter-level function is invoked. +For example, `interpreter descriptors`_ such as the ``Module.__new__`` +method for allocating and constructing a Module instance are +defined with such code:: Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, unwrap_spec=[ObjSpace, W_Root, Arguments]), __init__ = interp2app(Module.descr_module__init__), # module dictionaries are readonly attributes - __dict__ = GetSetProperty(descr_get_dict, cls=Module), - __doc__ = 'module(name[, doc])\n\nCreate a module object...' + __dict__ = GetSetProperty(descr_get_dict, cls=Module), + __doc__ = 'module(name[, doc])\n\nCreate a module object...' ) -The actual ``Module.descr_module__new__`` interpreter-level method -referenced from the ``__new__`` keyword argument above is defined -like this:: +The actual ``Module.descr_module__new__`` interpreter-level method +referenced from the ``__new__`` keyword argument above is defined +like this:: def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) Module.__init__(module, space, None) return space.wrap(module) -Summarizing, the ``interp2app`` mechanism takes care to route -an application level access or call to an internal interpreter-level +Summarizing, the ``interp2app`` mechanism takes care to route +an application level access or call to an internal interpreter-level object appropriately to the descriptor, providing enough precision -and hints to keep the type-inferring annotator happy. +and hints to keep the type-inferring annotator happy. -Calling into application level code from interpreter-level +Calling into application level code from interpreter-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Application level code is `often preferable`_. Therefore, -we often like to invoke application level code from interpreter-level. +Application level code is `often preferable`_. Therefore, +we often like to invoke application level code from interpreter-level. This is done via the Gateway's ``app2interp`` mechanism -which we usually invoke at definition time in a module. -It generates a hook which looks like an interpreter-level -function accepting a space and an arbitrary number of arguments. -When calling a function at interpreter-level the caller side +which we usually invoke at definition time in a module. +It generates a hook which looks like an interpreter-level +function accepting a space and an arbitrary number of arguments. +When calling a function at interpreter-level the caller side does usually not need to be aware if its invoked function is run through the PyPy interpreter or if it will directly -execute on the machine (after translation). +execute on the machine (after translation). -Here is an example showing how we implement the Metaclass +Here is an example showing how we implement the Metaclass finding algorithm of the Python language in PyPy:: app = gateway.applevel(r''' @@ -359,9 +359,9 @@ find_metaclass = app.interphook('find_metaclass') -The ``find_metaclass`` interpreter-level hook is invoked +The ``find_metaclass`` interpreter-level hook is invoked with five arguments from the ``BUILD_CLASS`` opcode implementation -in `pypy/interpreter/pyopcode.py`_:: +in `pypy/interpreter/pyopcode.py`_:: def BUILD_CLASS(f): w_methodsdict = f.valuestack.pop() @@ -374,32 +374,32 @@ w_bases, w_methodsdict) f.valuestack.push(w_newclass) -Note that at a later point we can rewrite the ``find_metaclass`` -implementation at interpreter-level and we would not have -to modify the calling side at all. +Note that at a later point we can rewrite the ``find_metaclass`` +implementation at interpreter-level and we would not have +to modify the calling side at all. .. _`often preferable`: coding-guide.html#app-preferable -.. _`interpreter descriptors`: +.. _`interpreter descriptors`: -Introspection and Descriptors +Introspection and Descriptors ------------------------------ -Python traditionally has a very far-reaching introspection model +Python traditionally has a very far-reaching introspection model for bytecode interpreter related objects. In PyPy and in CPython read -and write accesses to such objects are routed to descriptors. +and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in -PyPy they are implemented in interpreter-level Python code. +PyPy they are implemented in interpreter-level Python code. All instances of a Function_, Code_, Frame_ or Module_ classes -are also ``Wrappable`` instances which means they can be represented +are also ``W_Root`` instances which means they can be represented at application level. These days, a PyPy object space needs to work with a basic descriptor lookup when it encounters accesses to an interpreter-level object: an object space asks -a wrapped object for its type via a ``getclass`` method and then -calls the type's ``lookup(name)`` function in order to receive a descriptor +a wrapped object for its type via a ``getclass`` method and then +calls the type's ``lookup(name)`` function in order to receive a descriptor function. Most of PyPy's internal object descriptors are defined at the -end of `pypy/interpreter/typedef.py`_. You can use these definitions -as a reference for the exact attributes of interpreter classes visible -at application level. +end of `pypy/interpreter/typedef.py`_. You can use these definitions +as a reference for the exact attributes of interpreter classes visible +at application level. .. include:: _ref.txt diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -175,9 +175,9 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on instances of ``Wrappable`` + strings...) to create a new wrapped object, or on instances of ``W_Root`` to obtain an application-level-visible reference to them. For example, - most classes of the bytecode interpreter subclass ``Wrappable`` and can + most classes of the bytecode interpreter subclass ``W_Root`` and can be directly exposed to app-level in this way - functions, frames, code objects, etc. 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 @@ -42,6 +42,10 @@ .. branch: rpython-bytearray Rudimentary support for bytearray in RPython +.. branch: refactor-call_release_gil +Fix a bug which casused cffi to return the wrong result when calling a C +function which calls a Python callback which forces the frames + .. branches we don't care about .. branch: autoreds .. branch: reflex-support @@ -108,3 +112,5 @@ Documentation fixes after going through the docs at PyCon 2013 sprint. .. branch: extregistry-refactor + +.. branch: remove-list-smm diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -1,5 +1,5 @@ # Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -16,7 +16,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -82,7 +82,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can't store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1144,7 +1144,7 @@ assert space.eq_w(get_num("-0"), space.wrap(0)) assert space.eq_w(get_num("-0xAAAAAAL"), space.wrap(-0xAAAAAAL)) n = get_num(str(-sys.maxint - 1)) - assert space.is_true(space.isinstance(n, space.w_int)) + assert space.isinstance_w(n, space.w_int) for num in ("0o53", "0O53", "0o0000053", "0O00053"): assert space.eq_w(get_num(num), space.wrap(053)) for num in ("0b00101", "0B00101", "0b101", "0B101"): diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -538,7 +538,7 @@ HEAD = """# Generated by tools/asdl_py.py -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter import typedef from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt @@ -555,7 +555,7 @@ return w_obj -class AST(Wrappable): +class AST(W_Root): w_dict = None @@ -621,7 +621,7 @@ pass -class _FieldsWrapper(Wrappable): +class _FieldsWrapper(W_Root): "Hack around the fact we can\'t store tuples on a TypeDef." def __init__(self, fields): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -17,7 +17,7 @@ from pypy.interpreter.miscutils import ThreadLocals -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +__all__ = ['ObjSpace', 'OperationError', 'W_Root'] UINT_MAX_32_BITS = r_uint(4294967295) @@ -211,6 +211,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def float_w(self, space): + raise OperationError(space.w_TypeError, + typed_unwrap_error_msg(space, "float", self)) + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -219,16 +223,26 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def int(self, space): + w_impl = space.lookup(self, '__int__') + if w_impl is None: + typename = space.type(self).getname(space) + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for int(): '%s'", + typename) + w_result = space.get_and_call_function(w_impl, self) -class Wrappable(W_Root): - """A subclass of Wrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" - __slots__ = () - _settled_ = True + if (space.isinstance_w(w_result, space.w_int) or + space.isinstance_w(w_result, space.w_long)): + return w_result + typename = space.type(w_result).getname(space) + msg = "__int__ returned non-int (type '%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) def __spacebind__(self, space): return self + class W_InterpIterable(W_Root): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) @@ -263,18 +277,13 @@ def __init__(self, space): Cache.__init__(self) self.space = space + def _build(self, key): - val = self.space.enter_cache_building_mode() - try: - return self.build(key) - finally: - self.space.leave_cache_building_mode(val) + return self.build(key) + def _ready(self, result): - val = self.space.enter_cache_building_mode() - try: - return self.ready(result) - finally: - self.space.leave_cache_building_mode(val) + return self.ready(result) + def ready(self, result): pass @@ -339,9 +348,8 @@ if e.match(self, self.w_KeyError): continue raise - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and not mod.startup_called: - mod.init(self) + if isinstance(w_mod, Module) and not w_mod.startup_called: + w_mod.init(self) def finish(self): self.wait_for_thread_shutdown() @@ -350,9 +358,8 @@ self.call_function(w_exitfunc) from pypy.interpreter.module import Module for w_mod in self.builtin_modules.values(): - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module) and mod.startup_called: - mod.shutdown(self) + if isinstance(w_mod, Module) and w_mod.startup_called: + w_mod.shutdown(self) def wait_for_thread_shutdown(self): """Wait until threading._shutdown() completes, provided the threading @@ -424,9 +431,8 @@ # And initialize it from pypy.interpreter.module import Module - mod = self.interpclass_w(w_mod) - if isinstance(mod, Module): - mod.init(self) + if isinstance(w_mod, Module): + w_mod.init(self) return w_mod def get_builtinmodule_to_install(self): @@ -566,11 +572,6 @@ """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" - def enter_cache_building_mode(self): - "hook for the flow object space" - def leave_cache_building_mode(self, val): - "hook for the flow object space" - @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." @@ -723,38 +724,26 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - def interpclass_w(self, w_obj): - """ - If w_obj is a wrapped internal interpreter class instance unwrap to it, - otherwise return None. (Can be overridden in specific spaces; you - should generally use the helper space.interp_w() instead.) - """ - if isinstance(w_obj, Wrappable): - return w_obj - return None - def descr_self_interp_w(self, RequiredClass, w_obj): - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): + if not isinstance(w_obj, RequiredClass): raise DescrMismatch() - return obj + return w_obj descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)' def interp_w(self, RequiredClass, w_obj, can_be_None=False): """ Unwrap w_obj, checking that it is an instance of the required internal - interpreter class (a subclass of Wrappable). + interpreter class. """ assert RequiredClass is not None if can_be_None and self.is_none(w_obj): return None - obj = self.interpclass_w(w_obj) - if not isinstance(obj, RequiredClass): # or obj is None + if not isinstance(w_obj, RequiredClass): # or obj is None msg = "'%s' object expected, got '%s' instead" raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self)) - return obj + return w_obj interp_w._annspecialcase_ = 'specialize:arg(1)' def unpackiterable(self, w_iterable, expected_length=-1): @@ -924,7 +913,7 @@ if self.is_w(w_exc_type, w_check_class): return True # fast path (also here to handle string exceptions) try: - if self.is_true(self.isinstance(w_check_class, self.w_tuple)): + if self.isinstance_w(w_check_class, self.w_tuple): for w_t in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_t): return True @@ -1032,8 +1021,7 @@ def is_oldstyle_instance(self, w_obj): # xxx hack hack hack from pypy.module.__builtin__.interp_classobj import W_InstanceObject - obj = self.interpclass_w(w_obj) - return obj is not None and isinstance(obj, W_InstanceObject) + return isinstance(w_obj, W_InstanceObject) def callable(self, w_obj): if self.lookup(w_obj, "__call__") is not None: @@ -1053,9 +1041,6 @@ def issequence_w(self, w_obj): return (self.findattr(w_obj, self.wrap("__getitem__")) is not None) - def isinstance_w(self, w_obj, w_type): - return self.is_true(self.isinstance(w_obj, w_type)) - # The code below only works # for the simple case (new-style instance). # These methods are patched with the full logic by the __builtin__ @@ -1067,11 +1052,11 @@ def abstract_isinstance_w(self, w_obj, w_cls): # Equivalent to 'isinstance(obj, cls)'. - return self.is_true(self.isinstance(w_obj, w_cls)) + return self.isinstance_w(w_obj, w_cls) def abstract_isclass_w(self, w_obj): # Equivalent to 'isinstance(obj, type)'. - return self.is_true(self.isinstance(w_obj, self.w_type)) + return self.isinstance_w(w_obj, self.w_type) def abstract_getclass(self, w_obj): # Equivalent to 'obj.__class__'. @@ -1109,7 +1094,7 @@ expression = compiler.compile(expression, '?', 'eval', 0, hidden_applevel=hidden_applevel) else: - raise TypeError, 'space.eval(): expected a string, code or PyCode object' + raise TypeError('space.eval(): expected a string, code or PyCode object') return expression.exec_code(self, w_globals, w_locals) def exec_(self, statement, w_globals, w_locals, hidden_applevel=False, @@ -1123,7 +1108,7 @@ statement = compiler.compile(statement, filename, 'exec', 0, hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): - raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') if not self.is_true(self.contains(w_globals, w_key)): self.setitem(w_globals, w_key, self.wrap(self.builtin)) @@ -1179,7 +1164,7 @@ -> (index, 0, 0) or (start, stop, step) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) @@ -1199,7 +1184,7 @@ -> (index, 0, 0, 1) or (start, stop, step, slice_length) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step, length = w_index_or_slice.indices4(self, @@ -1327,15 +1312,21 @@ def int_w(self, w_obj): return w_obj.int_w(self) + def int(self, w_obj): + return w_obj.int(self) + def uint_w(self, w_obj): return w_obj.uint_w(self) def bigint_w(self, w_obj): return w_obj.bigint_w(self) + def float_w(self, w_obj): + return w_obj.float_w(self) + def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. - if not self.is_true(self.isinstance(w_obj, self.w_str)): + if not self.isinstance_w(w_obj, self.w_str): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) return self.str_w(w_obj) @@ -1355,7 +1346,7 @@ def realunicode_w(self, w_obj): # Like unicode_w, but only works if w_obj is really of type # 'unicode'. - if not self.is_true(self.isinstance(w_obj, self.w_unicode)): + if not self.isinstance_w(w_obj, self.w_unicode): raise OperationError(self.w_TypeError, self.wrap('argument must be a unicode')) return self.unicode_w(w_obj) @@ -1367,7 +1358,7 @@ # This is all interface for gateway.py. def gateway_int_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.int_w(self.int(w_obj)) @@ -1376,19 +1367,19 @@ return self.float_w(self.float(w_obj)) def gateway_r_longlong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_longlong_w(self.int(w_obj)) def gateway_r_uint_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.uint_w(self.int(w_obj)) def gateway_r_ulonglong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_ulonglong_w(self.int(w_obj)) @@ -1505,23 +1496,28 @@ space.exec_(str(source), w_glob, w_glob) return space.getitem(w_glob, space.wrap('anonymous')) + class DummyLock(object): def acquire(self, flag): return True + def release(self): pass + def _freeze_(self): return True + def __enter__(self): pass + def __exit__(self, *args): pass dummy_lock = DummyLock() -## Table describing the regular part of the interface of object spaces, -## namely all methods which only take w_ arguments and return a w_ result -## (if any). Note: keep in sync with rpython.flowspace.operation.Table. +# Table describing the regular part of the interface of object spaces, +# namely all methods which only take w_ arguments and return a w_ result +# (if any). ObjSpace.MethodTable = [ # method name # symbol # number of arguments # special method name(s) @@ -1548,7 +1544,7 @@ ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), - ('abs' , 'abs', 1, ['__abs__']), + ('abs', 'abs', 1, ['__abs__']), ('hex', 'hex', 1, ['__hex__']), ('oct', 'oct', 1, ['__oct__']), ('ord', 'ord', 1, []), @@ -1601,12 +1597,12 @@ ('delete', 'delete', 2, ['__delete__']), ('userdel', 'del', 1, ['__del__']), ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py - ] +] ObjSpace.BuiltinModuleTable = [ '__builtin__', 'sys', - ] +] ObjSpace.ConstantTable = [ 'None', @@ -1614,7 +1610,7 @@ 'True', 'Ellipsis', 'NotImplemented', - ] +] ObjSpace.ExceptionTable = [ 'ArithmeticError', @@ -1657,7 +1653,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', - ] +] if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] @@ -1670,7 +1666,6 @@ # float_w(w_floatval) -> floatval # uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value) # bigint_w(w_ival or w_long_ival) -> rbigint -#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj # unwrap(w_x) -> x # is_true(w_x) -> True or False # newtuple([w_1, w_2,...]) -> w_tuple @@ -1687,7 +1682,6 @@ 'uint_w', 'bigint_w', 'unicode_w', - 'interpclass_w', 'unwrap', 'is_true', 'is_w', @@ -1697,4 +1691,4 @@ 'newslice', 'call_args', 'marshal_w', - ] +] diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -15,7 +15,7 @@ # free the typecheck that __buffer__() really returned a wrapped Buffer. import operator -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError @@ -23,7 +23,7 @@ from rpython.rlib.rstring import StringBuilder -class Buffer(Wrappable): +class Buffer(W_Root): """Abstract base class for memory views.""" __slots__ = () # no extra slot here @@ -93,12 +93,11 @@ def _make_descr__cmp(name): def descr__cmp(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Buffer): + if not isinstance(w_other, Buffer): return space.w_NotImplemented # xxx not the most efficient implementation str1 = self.as_str() - str2 = other.as_str() + str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) descr__cmp.func_name = name return descr__cmp @@ -145,6 +144,7 @@ for i in range(len(string)): self.setitem(start + i, string[i]) + @unwrap_spec(offset=int, size=int) def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1): # w_subtype can only be exactly 'buffer' for now @@ -209,7 +209,7 @@ __mul__ = interp2app(Buffer.descr_mul), __rmul__ = interp2app(Buffer.descr_mul), __repr__ = interp2app(Buffer.descr_repr), - ) +) Buffer.typedef.acceptable_as_base_class = False # ____________________________________________________________ diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -183,7 +183,7 @@ # w_type = self.w_type w_value = self.get_w_value(space) - while space.is_true(space.isinstance(w_type, space.w_tuple)): + while space.isinstance_w(w_type, space.w_tuple): w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): @@ -198,7 +198,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.is_true(space.isinstance(w_value, space.w_tuple)): + if space.isinstance_w(w_value, space.w_tuple): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -3,10 +3,10 @@ Code and Frame. """ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root -class Code(Wrappable): +class Code(W_Root): """A code is a compiled version of some source code. Abstract base class.""" _immutable_ = True @@ -52,19 +52,20 @@ def funcrun_obj(self, func, w_obj, args): return self.funcrun(func, args.prepend(w_obj)) -class Frame(Wrappable): + +class Frame(W_Root): """A frame is an environment supporting the execution of a code object. Abstract base class.""" def __init__(self, space, w_globals=None): - self.space = space - self.w_globals = w_globals # wrapped dict of globals - self.w_locals = None # wrapped dict of locals + self.space = space + self.w_globals = w_globals # wrapped dict of globals + self.w_locals = None # wrapped dict of locals def run(self): "Abstract method to override. Runs the frame" - raise TypeError, "abstract" - + raise TypeError("abstract") + def getdictscope(self): "Get the locals as a dictionary." self.fast2locals() @@ -86,16 +87,16 @@ def getfastscope(self): "Abstract. Get the fast locals as a list." - raise TypeError, "abstract" + raise TypeError("abstract") def setfastscope(self, scope_w): """Abstract. Initialize the fast locals from a list of values, where the order is according to self.getcode().signature().""" - raise TypeError, "abstract" + raise TypeError("abstract") def getfastscopelength(self): "Abstract. Get the expected number of locals." - raise TypeError, "abstract" + raise TypeError("abstract") def fast2locals(self): # Copy values from the fastlocals to self.w_locals diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -8,20 +8,21 @@ from rpython.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from rpython.rlib import jit + funccallunrolling = unrolling_iterable(range(4)) + @jit.elidable_promote() def _get_immutable_code(func): assert not func.can_change_code return func.code - -class Function(Wrappable): +class Function(W_Root): """A function is a code object captured with some environment: an object space, a dictionary of globals, default arguments, and an arbitrary 'closure' passed to the code object.""" @@ -40,7 +41,7 @@ self.w_doc = None # lazily read from code.getdocstring() self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary - self.closure = closure # normally, list of Cell instances or None + self.closure = closure # normally, list of Cell instances or None self.defs_w = defs_w self.w_func_dict = None # filled out below if needed self.w_module = None @@ -55,11 +56,15 @@ def call_args(self, args): # delegate activation to code - return self.getcode().funcrun(self, args) + w_res = self.getcode().funcrun(self, args) + assert isinstance(w_res, W_Root) + return w_res def call_obj_args(self, w_obj, args): # delegate activation to code - return self.getcode().funcrun_obj(self, w_obj, args) + w_res = self.getcode().funcrun_obj(self, w_obj, args) + assert isinstance(w_res, W_Root) + return w_res def getcode(self): if jit.we_are_jitted(): @@ -202,7 +207,7 @@ def descr_function__new__(space, w_subtype, w_code, w_globals, w_name=None, w_argdefs=None, w_closure=None): code = space.interp_w(Code, w_code) - if not space.is_true(space.isinstance(w_globals, space.w_dict)): + if not space.isinstance_w(w_globals, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("expected dict")) if not space.is_none(w_name): name = space.str_w(w_name) @@ -239,7 +244,6 @@ def descr_function_repr(self): return self.getrepr(self.space, 'function %s' % (self.name,)) - # delicate _all = {'': None} @@ -266,8 +270,8 @@ def descr_function__reduce__(self, space): from pypy.interpreter.gateway import BuiltinCode from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) code = self.code if isinstance(code, BuiltinCode): new_inst = mod.get('builtin_function') @@ -275,7 +279,7 @@ space.newtuple([space.wrap(code.identifier)])]) new_inst = mod.get('func_new') - w = space.wrap + w = space.wrap if self.closure is None: w_closure = space.w_None else: @@ -351,8 +355,8 @@ if space.is_w(w_defaults, space.w_None): self.defs_w = [] return - if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): - raise OperationError( space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None") ) + if not space.isinstance_w(w_defaults, space.w_tuple): + raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) def fdel_func_defaults(self, space): @@ -379,7 +383,6 @@ "to a string object")) raise - def fdel_func_doc(self, space): self.w_doc = space.w_None @@ -418,7 +421,7 @@ def fget_func_closure(self, space): if self.closure is not None: - w_res = space.newtuple( [ space.wrap(i) for i in self.closure ] ) + w_res = space.newtuple([space.wrap(i) for i in self.closure]) else: w_res = space.w_None return w_res @@ -437,7 +440,7 @@ return space.wrap(Method(space, w_function, None, w_cls)) -class Method(Wrappable): +class Method(W_Root): """A method is a function bound to a specific instance or class.""" _immutable_fields_ = ['w_function', 'w_instance', 'w_class'] @@ -548,18 +551,17 @@ def descr_method_eq(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, Method): + if not isinstance(w_other, Method): return space.w_NotImplemented if self.w_instance is None: - if other.w_instance is not None: + if w_other.w_instance is not None: return space.w_False else: - if other.w_instance is None: + if w_other.w_instance is None: return space.w_False - if not space.eq_w(self.w_instance, other.w_instance): + if not space.eq_w(self.w_instance, w_other.w_instance): return space.w_False - return space.eq(self.w_function, other.w_function) + return space.eq(self.w_function, w_other.w_function) def descr_method_hash(self): space = self.space @@ -575,20 +577,22 @@ mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('method_new') w_instance = self.w_instance or space.w_None - function = space.interpclass_w(self.w_function) - if isinstance(function, Function) and isinstance(function.code, BuiltinCode): + w_function = self.w_function + if (isinstance(w_function, Function) and + isinstance(w_function.code, BuiltinCode)): new_inst = mod.get('builtin_method_new') if space.is_w(w_instance, space.w_None): - tup = [self.w_class, space.wrap(function.name)] + tup = [self.w_class, space.wrap(w_function.name)] else: - tup = [w_instance, space.wrap(function.name)] - elif space.is_w( self.w_class, space.w_None ): + tup = [w_instance, space.wrap(w_function.name)] + elif space.is_w(self.w_class, space.w_None): tup = [self.w_function, w_instance] else: tup = [self.w_function, w_instance, self.w_class] return space.newtuple([new_inst, space.newtuple(tup)]) -class StaticMethod(Wrappable): + +class StaticMethod(W_Root): """The staticmethod objects.""" _immutable_fields_ = ['w_function'] @@ -604,7 +608,8 @@ instance.__init__(w_function) return space.wrap(instance) -class ClassMethod(Wrappable): + +class ClassMethod(W_Root): """The classmethod objects.""" _immutable_fields_ = ['w_function'] diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -4,20 +4,23 @@ * BuiltinCode (call interp-level code from app-level) * app2interp (embed an app-level function into an interp-level callable) * interp2app (publish an interp-level object to be visible from app-level) +* interpindirect2app (publish an interp-level object to be visible from + app-level as an indirect call to implementation) """ import sys import os import types +import inspect import py from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments from pypy.interpreter.signature import Signature -from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, - SpaceCache, DescrMismatch) +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, SpaceCache, + DescrMismatch) from pypy.interpreter.error import OperationError from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from rpython.rlib import rstackovf @@ -53,7 +56,7 @@ class UnwrapSpecRecipe(object): "NOT_RPYTHON" - bases_order = [Wrappable, W_Root, ObjSpace, Arguments, object] + bases_order = [W_Root, ObjSpace, Arguments, object] def dispatch(self, el, *args): if isinstance(el, str): @@ -111,13 +114,13 @@ self.orig_arg = iter(original_sig.argnames).next def visit_self(self, cls, app_sig): - self.visit__Wrappable(cls, app_sig) + self.visit__W_Root(cls, app_sig) def checked_space_method(self, typname, app_sig): argname = self.orig_arg() assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typname, argname, self.func)) + "unwrapped %s argument %s of built-in function %r in %r should " + "not start with 'w_'" % (typname, argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname) def visit_index(self, index, app_sig): @@ -147,23 +150,18 @@ def visit_truncatedint_w(self, el, app_sig): self.checked_space_method(el, app_sig) - def visit__Wrappable(self, el, app_sig): - name = el.__name__ - argname = self.orig_arg() - assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (name, argname, self.func)) - app_sig.append(argname) - def visit__ObjSpace(self, el, app_sig): self.orig_arg() def visit__W_Root(self, el, app_sig): - assert el is W_Root, "%s is not W_Root (forgotten to put .im_func in interp2app argument?)" % (el,) argname = self.orig_arg() + if argname == 'self': + assert el is not W_Root + app_sig.append(argname) + return assert argname.startswith('w_'), ( - "argument %s of built-in function %r should " - "start with 'w_'" % (argname, self.func)) + "argument %s of built-in function %r in %r should " + "start with 'w_'" % (argname, self.func.func_name, self.func.func_globals['__name__'])) app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): @@ -211,15 +209,15 @@ self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) - def visit__Wrappable(self, typ): - self.run_args.append("space.interp_w(%s, %s)" % (self.use(typ), - self.scopenext())) - def visit__ObjSpace(self, el): self.run_args.append('space') def visit__W_Root(self, el): - self.run_args.append(self.scopenext()) + if el is not W_Root: + self.run_args.append("space.interp_w(%s, %s)" % (self.use(el), + self.scopenext())) + else: + self.run_args.append(self.scopenext()) def visit__Arguments(self, el): self.miniglobals['Arguments'] = Arguments @@ -348,17 +346,17 @@ self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) - def visit__Wrappable(self, typ): - self.unwrap.append("space.interp_w(%s, %s)" % (self.use(typ), - self.nextarg())) - def visit__ObjSpace(self, el): if self.finger != 0: raise FastFuncNotSupported self.unwrap.append("space") def visit__W_Root(self, el): - self.unwrap.append(self.nextarg()) + if el is not W_Root: + self.unwrap.append("space.interp_w(%s, %s)" % (self.use(el), + self.nextarg())) + else: + self.unwrap.append(self.nextarg()) def visit__Arguments(self, el): raise FastFuncNotSupported @@ -471,6 +469,7 @@ def __init__(self, default_value): self.default_value = default_value + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -536,7 +535,6 @@ # It is a list of types or singleton objects: # baseobjspace.ObjSpace is used to specify the space argument # baseobjspace.W_Root is for wrapped arguments to keep wrapped - # baseobjspace.Wrappable subclasses imply interp_w and a typecheck # argument.Arguments is for a final rest arguments Arguments object # 'args_w' for fixedview applied to rest arguments # 'w_args' for rest arguments passed as wrapped tuple @@ -555,7 +553,7 @@ assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: - assert issubclass(self_type, Wrappable) + assert issubclass(self_type, W_Root) unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type @@ -799,8 +797,33 @@ w_result = space.w_None return w_result +def interpindirect2app(unbound_meth, unwrap_spec=None): + base_cls = unbound_meth.im_class + func = unbound_meth.im_func + args = inspect.getargs(func.func_code) + if args.varargs or args.keywords: + raise TypeError("Varargs and keywords not supported in unwrap_spec") + assert not func.func_defaults + argspec = ', '.join([arg for arg in args.args[1:]]) + func_code = py.code.Source(""" + def f(w_obj, %(args)s): + return w_obj.%(func_name)s(%(args)s) + """ % {'args': argspec, 'func_name': func.func_name}) + d = {} + exec func_code.compile() in d + f = d['f'] + f.__module__ = func.__module__ + # necessary for unique identifiers for pickling + f.func_name = func.func_name + if unwrap_spec is None: + unwrap_spec = {} + else: + assert isinstance(unwrap_spec, dict) + unwrap_spec = unwrap_spec.copy() + unwrap_spec['w_obj'] = base_cls + return interp2app(globals()['unwrap_spec'](**unwrap_spec)(f)) -class interp2app(Wrappable): +class interp2app(W_Root): """Build a gateway that calls 'f' at interp-level.""" # Takes optionally an unwrap_spec, see BuiltinCode @@ -833,7 +856,7 @@ result = cls.instancecache[key] assert result.__class__ is cls return result - self = Wrappable.__new__(cls) + self = W_Root.__new__(cls) cls.instancecache[key] = self self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, self_type=self_type, @@ -856,9 +879,9 @@ for name, defaultval in self._staticdefs: if name.startswith('w_'): assert defaultval is None, ( - "%s: default value for '%s' can only be None; " + "%s: default value for '%s' can only be None, got %r; " "use unwrap_spec(...=WrappedDefault(default))" % ( - self._code.identifier, name)) + self._code.identifier, name, defaultval)) defs_w.append(None) else: defs_w.append(space.wrap(defaultval)) diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -1,10 +1,10 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.pyopcode import LoopBlock from rpython.rlib import jit -class GeneratorIterator(Wrappable): +class GeneratorIterator(W_Root): "An iterator created by a generator." _immutable_fields_ = ['pycode'] @@ -94,7 +94,6 @@ w_val = self.space.w_None return self.throw(w_type, w_val, w_tb) - def throw(self, w_type, w_val, w_tb): from pypy.interpreter.pytraceback import check_traceback space = self.space @@ -164,6 +163,7 @@ jitdriver = jit.JitDriver(greens=['pycode'], reds=['self', 'frame', 'results'], name='unpack_into') + def unpack_into(self, results): """This is a hack for performance: runs the generator and collects all produced items in a list.""" diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -89,13 +89,13 @@ return None else: w_value = loader(space) - func = space.interpclass_w(w_value) # the idea of the following code is that all functions that are # directly in a mixed-module are "builtin", e.g. they get a # special type without a __get__ # note that this is not just all functions that contain a # builtin code object, as e.g. methods of builtin types have to # be normal Functions to get the correct binding behaviour + func = w_value if (isinstance(func, Function) and type(func) is not BuiltinFunction): try: diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -2,11 +2,12 @@ Module objects. """ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import we_are_translated -class Module(Wrappable): + +class Module(W_Root): """A module.""" _immutable_fields_ = ["w_dict?"] @@ -80,7 +81,7 @@ def descr__reduce__(self, space): w_name = space.finditem(self.w_dict, space.wrap('__name__')) if (w_name is None or - not space.is_true(space.isinstance(w_name, space.w_str))): + not space.isinstance_w(w_name, space.w_str)): # maybe raise exception here (XXX this path is untested) return space.w_None w_modules = space.sys.get('modules') diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -3,12 +3,12 @@ from pypy.interpreter import function, pycode, pyframe from pypy.interpreter.astcompiler import consts -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.mixedmodule import MixedModule -class Cell(Wrappable): +class Cell(W_Root): "A simple container for a wrapped value." def __init__(self, w_value=None): @@ -34,18 +34,17 @@ self.w_value = None def descr__cmp__(self, space, w_other): - other = space.interpclass_w(w_other) - if not isinstance(other, Cell): + if not isinstance(w_other, Cell): return space.w_NotImplemented if self.w_value is None: - if other.w_value is None: + if w_other.w_value is None: return space.newint(0) return space.newint(-1) - elif other.w_value is None: + elif w_other.w_value is None: return space.newint(1) - return space.cmp(self.w_value, other.w_value) + return space.cmp(self.w_value, w_other.w_value) def descr__reduce__(self, space): w_mod = space.getbuiltinmodule('_pickle_support') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -232,7 +232,7 @@ def getdocstring(self, space): if self.co_consts_w: # it is probably never empty w_first = self.co_consts_w[0] - if space.is_true(space.isinstance(w_first, space.w_basestring)): + if space.isinstance_w(w_first, space.w_basestring): return w_first return space.w_None @@ -246,20 +246,20 @@ else: consts[num] = self.space.unwrap(w) num += 1 - return new.code( self.co_argcount, - self.co_nlocals, - self.co_stacksize, - self.co_flags, - self.co_code, - tuple(consts), - tuple(self.co_names), - tuple(self.co_varnames), - self.co_filename, - self.co_name, - self.co_firstlineno, - self.co_lnotab, - tuple(self.co_freevars), - tuple(self.co_cellvars) ) + return new.code(self.co_argcount, + self.co_nlocals, + self.co_stacksize, + self.co_flags, + self.co_code, + tuple(consts), + tuple(self.co_names), + tuple(self.co_varnames), + self.co_filename, + self.co_name, + self.co_firstlineno, + self.co_lnotab, + tuple(self.co_freevars), + tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): from pypy.interpreter.pyframe import CPythonFrame @@ -289,29 +289,28 @@ def descr_code__eq__(self, w_other): space = self.space - other = space.interpclass_w(w_other) - if not isinstance(other, PyCode): + if not isinstance(w_other, PyCode): return space.w_False - areEqual = (self.co_name == other.co_name and - self.co_argcount == other.co_argcount and - self.co_nlocals == other.co_nlocals and - self.co_flags == other.co_flags and - self.co_firstlineno == other.co_firstlineno and - self.co_code == other.co_code and - len(self.co_consts_w) == len(other.co_consts_w) and - len(self.co_names_w) == len(other.co_names_w) and - self.co_varnames == other.co_varnames and - self.co_freevars == other.co_freevars and From noreply at buildbot.pypy.org Fri Mar 29 06:02:22 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:22 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: move test to tests_pypy_c Message-ID: <20130329050222.21DBF1C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62870:84b2a0aa576e Date: 2013-03-28 17:46 +0100 http://bitbucket.org/pypy/pypy/changeset/84b2a0aa576e/ Log: move test to tests_pypy_c diff --git a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py new file mode 100644 --- /dev/null +++ b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py @@ -0,0 +1,44 @@ +from rpython.tool.logparser import extract_category + +from pypy.tool.jitlogparser.parser import import_log, parse_log_counts +from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC + + +class TestLogParser(BaseTestPyPyC): + + def test(self): + def fn_with_bridges(N): + def is_prime(x): + for y in xrange(2, x): + if x % y == 0: + return False + return True + result = 0 + for x in xrange(N): + if x % 3 == 0: + result += 5 + elif x % 5 == 0: + result += 3 + elif is_prime(x): + result += x + elif x == 99: + result *= 2 + return result + # + log = self.run(fn_with_bridges, [10000]) + print log + import pdb; pdb.set_trace() + # TODO + log, loops = import_log(log_filename) + parse_log_counts(extract_category(log, 'jit-backend-count'), loops) + lib_re = re.compile("file '.*lib-python.*'") + for loop in loops: + loop.force_asm() + if lib_re.search(loop.comment) or \ + lib_re.search(loop.operations[0].repr()): + # do not care for _optimize_charset or _mk_bitmap + continue + else: + import pdb; pdb.set_trace() + + diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -1,8 +1,3 @@ -import re -import os.path -import tempfile -import subprocess - from pypy.tool.jitlogparser.parser import (SimpleParser, TraceForOpcode, Function, adjust_bridges, import_log, split_trace, Op, @@ -10,7 +5,6 @@ from pypy.tool.jitlogparser.storage import LoopStorage import py, sys from rpython.jit.backend.detect_cpu import autodetect_main_model -from rpython.tool.logparser import extract_category def parse(input, **kwds): @@ -378,24 +372,3 @@ """) f = Function.from_operations(loop.operations, LoopStorage()) assert len(f.chunks) == 2 - -def test_import_log_on_pypy(): - ''' Test import_log and parse_log_counts on a log from actual pypy run - ''' - log_filename = tempfile.mktemp() - pypy = '/Users/kostia/programming/pypy/pypy-c' # FIXME - subprocess.check_call([pypy, - os.path.join(os.path.dirname(__file__), 'y.py')], - env={'PYPYLOG': 'jit-log-opt,jit-backend:%s' % log_filename}) - log, loops = import_log(log_filename) - parse_log_counts(extract_category(log, 'jit-backend-count'), loops) - lib_re = re.compile("file '.*lib-python.*'") - for loop in loops: - loop.force_asm() - if lib_re.search(loop.comment) or \ - lib_re.search(loop.operations[0].repr()): - # do not care for _optimize_charset or _mk_bitmap - continue - else: - import pdb; pdb.set_trace() - diff --git a/pypy/tool/jitlogparser/test/y.py b/pypy/tool/jitlogparser/test/y.py deleted file mode 100644 --- a/pypy/tool/jitlogparser/test/y.py +++ /dev/null @@ -1,24 +0,0 @@ - -def fn_with_bridges(N): - result = 0 - for x in xrange(N): - if x % 3 == 0: - result += 5 - elif x % 5 == 0: - result += 3 - elif is_prime(x): - result += x - elif x == 99: - result *= 2 - return result - - -def is_prime(x): - for y in xrange(2, x): - if x % y == 0: - return False - return True - - -fn_with_bridges(10000) - From noreply at buildbot.pypy.org Fri Mar 29 06:02:23 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:23 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: test parsed log - check that we find bridges and that counts are reasonable Message-ID: <20130329050223.5324A1C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62871:7f27588d5fb0 Date: 2013-03-28 21:23 +0100 http://bitbucket.org/pypy/pypy/changeset/7f27588d5fb0/ Log: test parsed log - check that we find bridges and that counts are reasonable diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -75,6 +75,7 @@ rawtraces = logparser.extract_category(rawlog, 'jit-log-opt-') log = Log(rawtraces) log.result = eval(stdout) + log.logfile = str(logfile) # summaries = logparser.extract_category(rawlog, 'jit-summary') if len(summaries) > 0: diff --git a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py --- a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py +++ b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py @@ -1,10 +1,14 @@ +import re + from rpython.tool.logparser import extract_category -from pypy.tool.jitlogparser.parser import import_log, parse_log_counts +from pypy.tool.jitlogparser.parser import (import_log, parse_log_counts, + mangle_descr) from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC class TestLogParser(BaseTestPyPyC): + log_string = 'jit-log-opt,jit-backend' def test(self): def fn_with_bridges(N): @@ -25,20 +29,48 @@ result *= 2 return result # - log = self.run(fn_with_bridges, [10000]) - print log - import pdb; pdb.set_trace() - # TODO - log, loops = import_log(log_filename) + N = 10000 + _log = self.run(fn_with_bridges, [N]) + log, loops = import_log(_log.logfile) parse_log_counts(extract_category(log, 'jit-backend-count'), loops) + + is_prime_loops = [] + fn_with_bridges_loops = [] + bridges = {} + lib_re = re.compile("file '.*lib-python.*'") for loop in loops: - loop.force_asm() + if hasattr(loop, 'force_asm'): + loop.force_asm() if lib_re.search(loop.comment) or \ lib_re.search(loop.operations[0].repr()): # do not care for _optimize_charset or _mk_bitmap continue + assert loop.count > 0 + if ' is_prime, ' in loop.comment: + is_prime_loops.append(loop) + elif ' fn_with_bridges, ' in loop.comment: + fn_with_bridges_loops.append(loop) else: - import pdb; pdb.set_trace() + assert ' bridge ' in loop.comment + key = mangle_descr(loop.descr) + assert key not in bridges + bridges[key] = loop + by_count = lambda l: -l.count + is_prime_loops.sort(key=by_count) + fn_with_bridges_loops.sort(key=by_count) + + # check that we can find bridges corresponding to " % 3" and " % 5" + mod_bridges = [] + for op in fn_with_bridges_loops[0].operations: + if op.descr is not None: + bridge = bridges.get(mangle_descr(op.descr)) + if bridge is not None: + mod_bridges.append(bridge) + assert len(mod_bridges) == 2 + + # check that counts are reasonable (precise # may change in the future) + assert N - 2000 < sum(l.count for l in fn_with_bridges_loops) < N + diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -447,6 +447,17 @@ num, count = line.split(':', 2) mapping[num].count = int(count) + +def mangle_descr(descr): + if descr.startswith('TargetToken('): + return descr[len('TargetToken('):-1] + if descr.startswith(' Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62872:48d689bbbfda Date: 2013-03-28 21:27 +0100 http://bitbucket.org/pypy/pypy/changeset/48d689bbbfda/ Log: remove spurious diff diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -10,7 +10,6 @@ def parse(input, **kwds): return SimpleParser.parse_from_input(input, **kwds) - def test_parse(): ops = parse(''' [i7] @@ -372,3 +371,4 @@ """) f = Function.from_operations(loop.operations, LoopStorage()) assert len(f.chunks) == 2 + From noreply at buildbot.pypy.org Fri Mar 29 06:02:25 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 29 Mar 2013 06:02:25 +0100 (CET) Subject: [pypy-commit] pypy bridge-logging: remove spurious diff Message-ID: <20130329050225.B81991C0705@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: bridge-logging Changeset: r62873:15280d161e06 Date: 2013-03-28 21:29 +0100 http://bitbucket.org/pypy/pypy/changeset/15280d161e06/ Log: remove spurious diff diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -6,10 +6,10 @@ import py, sys from rpython.jit.backend.detect_cpu import autodetect_main_model - def parse(input, **kwds): return SimpleParser.parse_from_input(input, **kwds) + def test_parse(): ops = parse(''' [i7] @@ -371,4 +371,4 @@ """) f = Function.from_operations(loop.operations, LoopStorage()) assert len(f.chunks) == 2 - + From noreply at buildbot.pypy.org Fri Mar 29 06:02:26 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 29 Mar 2013 06:02:26 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in kostialopuhin/pypy/bridge-logging (pull request #147) Message-ID: <20130329050226.F12291C0705@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r62874:10c464811795 Date: 2013-03-29 07:02 +0200 http://bitbucket.org/pypy/pypy/changeset/10c464811795/ Log: Merged in kostialopuhin/pypy/bridge-logging (pull request #147) Add test for parsing jit log produced from actual pypy diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -75,6 +75,7 @@ rawtraces = logparser.extract_category(rawlog, 'jit-log-opt-') log = Log(rawtraces) log.result = eval(stdout) + log.logfile = str(logfile) # summaries = logparser.extract_category(rawlog, 'jit-summary') if len(summaries) > 0: diff --git a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py new file mode 100644 --- /dev/null +++ b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py @@ -0,0 +1,76 @@ +import re + +from rpython.tool.logparser import extract_category + +from pypy.tool.jitlogparser.parser import (import_log, parse_log_counts, + mangle_descr) +from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC + + +class TestLogParser(BaseTestPyPyC): + log_string = 'jit-log-opt,jit-backend' + + def test(self): + def fn_with_bridges(N): + def is_prime(x): + for y in xrange(2, x): + if x % y == 0: + return False + return True + result = 0 + for x in xrange(N): + if x % 3 == 0: + result += 5 + elif x % 5 == 0: + result += 3 + elif is_prime(x): + result += x + elif x == 99: + result *= 2 + return result + # + N = 10000 + _log = self.run(fn_with_bridges, [N]) + log, loops = import_log(_log.logfile) + parse_log_counts(extract_category(log, 'jit-backend-count'), loops) + + is_prime_loops = [] + fn_with_bridges_loops = [] + bridges = {} + + lib_re = re.compile("file '.*lib-python.*'") + for loop in loops: + if hasattr(loop, 'force_asm'): + loop.force_asm() + if lib_re.search(loop.comment) or \ + lib_re.search(loop.operations[0].repr()): + # do not care for _optimize_charset or _mk_bitmap + continue + assert loop.count > 0 + if ' is_prime, ' in loop.comment: + is_prime_loops.append(loop) + elif ' fn_with_bridges, ' in loop.comment: + fn_with_bridges_loops.append(loop) + else: + assert ' bridge ' in loop.comment + key = mangle_descr(loop.descr) + assert key not in bridges + bridges[key] = loop + + by_count = lambda l: -l.count + is_prime_loops.sort(key=by_count) + fn_with_bridges_loops.sort(key=by_count) + + # check that we can find bridges corresponding to " % 3" and " % 5" + mod_bridges = [] + for op in fn_with_bridges_loops[0].operations: + if op.descr is not None: + bridge = bridges.get(mangle_descr(op.descr)) + if bridge is not None: + mod_bridges.append(bridge) + assert len(mod_bridges) == 2 + + # check that counts are reasonable (precise # may change in the future) + assert N - 2000 < sum(l.count for l in fn_with_bridges_loops) < N + + diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -447,6 +447,17 @@ num, count = line.split(':', 2) mapping[num].count = int(count) + +def mangle_descr(descr): + if descr.startswith('TargetToken('): + return descr[len('TargetToken('):-1] + if descr.startswith(' Author: David Schneider Branch: Changeset: r62875:3bf293c91f96 Date: 2013-03-29 17:57 +0200 http://bitbucket.org/pypy/pypy/changeset/3bf293c91f96/ Log: we need one list per instance diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -278,11 +278,11 @@ no_lower_byte_regs = [] save_around_call_regs = [] frame_reg = None - temp_boxes = [] def __init__(self, longevity, frame_manager=None, assembler=None): self.free_regs = self.all_regs[:] self.longevity = longevity + self.temp_boxes = [] if not we_are_translated(): self.reg_bindings = OrderedDict() else: From noreply at buildbot.pypy.org Fri Mar 29 17:00:00 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 29 Mar 2013 17:00:00 +0100 (CET) Subject: [pypy-commit] pypy default: skipt tests that require floats Message-ID: <20130329160000.80C371C08F6@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62876:61eafab0ddcb Date: 2013-03-29 17:58 +0200 http://bitbucket.org/pypy/pypy/changeset/61eafab0ddcb/ Log: skipt tests that require floats diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py --- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py @@ -515,6 +515,10 @@ # FIXME: Verify that i19 - i23 are removed class TestRegallocFloats(BaseTestRegalloc): + def setup_class(cls): + if not cls.cpu.supports_floats: + py.test.skip("needs float support") + def test_float_add(self): ops = ''' [f0, f1] From noreply at buildbot.pypy.org Fri Mar 29 17:00:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 29 Mar 2013 17:00:47 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Minor clean-ups Message-ID: <20130329160047.14E6F1C0705@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r62877:6a33a670a08a Date: 2013-03-29 16:57 +0100 http://bitbucket.org/pypy/pypy/changeset/6a33a670a08a/ Log: Minor clean-ups diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -257,7 +257,7 @@ header = info[0] f = cStringIO.StringIO() if len(info) > 1: - print >> f, 'Traceback from detected conflict:' + print >> f, 'Detected conflict:' for tb in info[1:]: filename = tb[0] coname = tb[1] diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h --- a/rpython/translator/stm/src_stm/et.h +++ b/rpython/translator/stm/src_stm/et.h @@ -93,7 +93,6 @@ //gcptr Allocate(size_t size, int gctid); _Bool stm_PtrEq(gcptr P1, gcptr P2); -gcptr stm_HashObject(gcptr P); void *stm_DirectReadBarrier(void *); void *stm_DirectReadBarrierFromR(void *, void *, size_t); From noreply at buildbot.pypy.org Fri Mar 29 17:05:55 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 29 Mar 2013 17:05:55 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: Give ComplexFloating item types a reference to their component type, Message-ID: <20130329160555.372AB1C07B6@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62878:b2f10642914a Date: 2013-03-29 14:59 +0000 http://bitbucket.org/pypy/pypy/changeset/b2f10642914a/ Log: Give ComplexFloating item types a reference to their component type, instead of their component's box type. 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 @@ -453,7 +453,7 @@ w_box_type=space.gettypefor(interp_boxes.W_UInt64Box), ) self.w_float32dtype = W_Dtype( - types.Float32(), + types.Float32_instance, num=11, kind=FLOATINGLTR, name="float32", @@ -461,7 +461,7 @@ w_box_type=space.gettypefor(interp_boxes.W_Float32Box), ) self.w_float64dtype = W_Dtype( - types.Float64(), + types.Float64_instance, num=12, kind=FLOATINGLTR, name="float64", @@ -494,7 +494,7 @@ ) if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size > 8: self.w_longdouble = W_Dtype( - types.Float80(), + types.Float80_instance, num=13, kind=FLOATINGLTR, name="", 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 @@ -1003,6 +1003,7 @@ T = rffi.FLOAT BoxType = interp_boxes.W_Float32Box format_code = "f" +Float32_instance = Float32() class NonNativeFloat32(BaseType, NonNativeFloat): _attrs_ = () @@ -1025,6 +1026,7 @@ T = rffi.DOUBLE BoxType = interp_boxes.W_Float64Box format_code = "d" +Float64_instance = Float64() class NonNativeFloat64(BaseType, NonNativeFloat): _attrs_ = () @@ -1097,8 +1099,7 @@ @specialize.argtype(1) def box_component(self, value): - return self.ComponentBoxType( - rffi.cast(self.T, value)) + return self.FloatType.box(value) @specialize.argtype(1, 2) def box_complex(self, real, imag): @@ -1541,7 +1542,7 @@ T = rffi.FLOAT BoxType = interp_boxes.W_Complex64Box - ComponentBoxType = interp_boxes.W_Float32Box + FloatType = Float32_instance NonNativeComplex64 = Complex64 @@ -1550,7 +1551,7 @@ T = rffi.DOUBLE BoxType = interp_boxes.W_Complex128Box - ComponentBoxType = interp_boxes.W_Float64Box + FloatType = Float64_instance NonNativeComplex128 = Complex128 @@ -1572,6 +1573,7 @@ result = StringBuilder(10) pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) + Float80_instance = Float80() NonNativeFloat80 = Float80 @@ -1580,7 +1582,7 @@ T = rffi.LONGDOUBLE BoxType = interp_boxes.W_CLongDoubleBox - ComponentBoxType = interp_boxes.W_LongDoubleBox + FloatType = Float80_instance NonNativeComplex160 = Complex160 if interp_boxes.long_double_size in (12, 16): From noreply at buildbot.pypy.org Fri Mar 29 17:05:56 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 29 Mar 2013 17:05:56 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: Store the unwrappped BoxType on the dtype. Message-ID: <20130329160556.73B3F1C07B6@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62879:a23ba7c93c56 Date: 2013-03-29 16:05 +0000 http://bitbucket.org/pypy/pypy/changeset/a23ba7c93c56/ Log: Store the unwrappped BoxType on the dtype. 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 @@ -50,7 +50,7 @@ class W_Dtype(W_Root): _immutable_fields_ = ["itemtype", "num", "kind"] - def __init__(self, itemtype, num, kind, name, char, w_box_type, + def __init__(self, itemtype, num, kind, name, char, BoxType, alternate_constructors=[], aliases=[], fields=None, fieldnames=None, native=True): self.itemtype = itemtype @@ -58,7 +58,7 @@ self.kind = kind self.name = name self.char = char - self.w_box_type = w_box_type + self.BoxType = BoxType self.alternate_constructors = alternate_constructors self.aliases = aliases self.fields = fields @@ -140,6 +140,9 @@ return space.w_None return space.newtuple([space.wrap(name) for name in self.fieldnames]) + def descr_get_type(self, space): + return space.gettypefor(self.BoxType) + @unwrap_spec(item=str) def descr_getitem(self, space, item): if self.fields is None: @@ -183,10 +186,10 @@ return self.itemtype.get_element_size() class W_ComplexDtype(W_Dtype): - def __init__(self, itemtype, num, kind, name, char, w_box_type, + def __init__(self, itemtype, num, kind, name, char, BoxType, alternate_constructors=[], aliases=[], fields=None, fieldnames=None, native=True, float_type=None): - W_Dtype.__init__(self, itemtype, num, kind, name, char, w_box_type, + W_Dtype.__init__(self, itemtype, num, kind, name, char, BoxType, alternate_constructors=alternate_constructors, aliases=aliases, fields=fields, fieldnames=fieldnames, native=native) self.float_type = float_type @@ -223,7 +226,7 @@ fieldnames.append(fldname) itemtype = types.RecordType(ofs_and_items, offset) return W_Dtype(itemtype, 20, VOIDLTR, "void" + str(8 * itemtype.get_element_size()), - "V", space.gettypefor(interp_boxes.W_VoidBox), fields=fields, + "V", interp_boxes.W_VoidBox, fields=fields, fieldnames=fieldnames) def dtype_from_dict(space, w_dict): @@ -245,11 +248,11 @@ itemtype = types.StringType(size) basename = 'string' num = 18 - w_box_type = space.gettypefor(interp_boxes.W_StringBox) + BoxType = interp_boxes.W_StringBox elif char == 'V': num = 20 basename = 'void' - w_box_type = space.gettypefor(interp_boxes.W_VoidBox) + BoxType = interp_boxes.W_VoidBox raise OperationError(space.w_NotImplementedError, space.wrap( "pure void dtype")) else: @@ -257,10 +260,10 @@ basename = 'unicode' itemtype = types.UnicodeType(size) num = 19 - w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox) + BoxType = interp_boxes.W_UnicodeBox return W_Dtype(itemtype, num, char, basename + str(8 * itemtype.get_element_size()), - char, w_box_type) + char, BoxType) def dtype_from_spec(space, name): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -292,7 +295,7 @@ for dtype in cache.builtin_dtypes: if w_dtype in dtype.alternate_constructors: return dtype - if w_dtype is dtype.w_box_type: + if w_dtype is dtype.descr_get_type(space): return dtype raise OperationError(space.w_TypeError, space.wrap("data type %r not understood" % w_dtype)) @@ -309,7 +312,7 @@ num = interp_attrproperty("num", cls=W_Dtype), kind = interp_attrproperty("kind", cls=W_Dtype), char = interp_attrproperty("char", cls=W_Dtype), - type = interp_attrproperty_w("w_box_type", cls=W_Dtype), + type = GetSetProperty(W_Dtype.descr_get_type), byteorder = GetSetProperty(W_Dtype.descr_get_byteorder), itemsize = GetSetProperty(W_Dtype.descr_get_itemsize), alignment = GetSetProperty(W_Dtype.descr_get_alignment), @@ -334,7 +337,7 @@ kind=STRINGLTR, name='string', char='S' + str(size), - w_box_type = space.gettypefor(interp_boxes.W_StringBox), + BoxType = interp_boxes.W_StringBox, ) def new_unicode_dtype(space, size): @@ -344,7 +347,7 @@ kind=UNICODELTR, name='unicode', char='U' + str(size), - w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox), + BoxType = interp_boxes.W_UnicodeBox, ) @@ -356,7 +359,7 @@ kind=BOOLLTR, name="bool", char="?", - w_box_type=space.gettypefor(interp_boxes.W_BoolBox), + BoxType=interp_boxes.W_BoolBox, alternate_constructors=[space.w_bool], ) self.w_int8dtype = W_Dtype( @@ -365,7 +368,7 @@ kind=SIGNEDLTR, name="int8", char="b", - w_box_type=space.gettypefor(interp_boxes.W_Int8Box) + BoxType=interp_boxes.W_Int8Box ) self.w_uint8dtype = W_Dtype( types.UInt8(), @@ -373,7 +376,7 @@ kind=UNSIGNEDLTR, name="uint8", char="B", - w_box_type=space.gettypefor(interp_boxes.W_UInt8Box), + BoxType=interp_boxes.W_UInt8Box, ) self.w_int16dtype = W_Dtype( types.Int16(), @@ -381,7 +384,7 @@ kind=SIGNEDLTR, name="int16", char="h", - w_box_type=space.gettypefor(interp_boxes.W_Int16Box), + BoxType=interp_boxes.W_Int16Box, ) self.w_uint16dtype = W_Dtype( types.UInt16(), @@ -389,7 +392,7 @@ kind=UNSIGNEDLTR, name="uint16", char="H", - w_box_type=space.gettypefor(interp_boxes.W_UInt16Box), + BoxType=interp_boxes.W_UInt16Box, ) self.w_int32dtype = W_Dtype( types.Int32(), @@ -397,7 +400,7 @@ kind=SIGNEDLTR, name="int32", char="i", - w_box_type=space.gettypefor(interp_boxes.W_Int32Box), + BoxType=interp_boxes.W_Int32Box, ) self.w_uint32dtype = W_Dtype( types.UInt32(), @@ -405,7 +408,7 @@ kind=UNSIGNEDLTR, name="uint32", char="I", - w_box_type=space.gettypefor(interp_boxes.W_UInt32Box), + BoxType=interp_boxes.W_UInt32Box, ) if LONG_BIT == 32: name = "int32" @@ -417,7 +420,7 @@ kind=SIGNEDLTR, name=name, char="l", - w_box_type=space.gettypefor(interp_boxes.W_LongBox), + BoxType=interp_boxes.W_LongBox, alternate_constructors=[space.w_int, space.gettypefor(interp_boxes.W_IntegerBox), space.gettypefor(interp_boxes.W_SignedIntegerBox), @@ -430,7 +433,7 @@ kind=UNSIGNEDLTR, name="u" + name, char="L", - w_box_type=space.gettypefor(interp_boxes.W_ULongBox), + BoxType=interp_boxes.W_ULongBox, alternate_constructors=[ space.gettypefor(interp_boxes.W_UnsignedIntegerBox), ], aliases=['uint'], @@ -441,7 +444,7 @@ kind=SIGNEDLTR, name="int64", char="q", - w_box_type=space.gettypefor(interp_boxes.W_Int64Box), + BoxType=interp_boxes.W_Int64Box, alternate_constructors=[space.w_long], ) self.w_uint64dtype = W_Dtype( @@ -450,7 +453,7 @@ kind=UNSIGNEDLTR, name="uint64", char="Q", - w_box_type=space.gettypefor(interp_boxes.W_UInt64Box), + BoxType=interp_boxes.W_UInt64Box, ) self.w_float32dtype = W_Dtype( types.Float32_instance, @@ -458,7 +461,7 @@ kind=FLOATINGLTR, name="float32", char="f", - w_box_type=space.gettypefor(interp_boxes.W_Float32Box), + BoxType=interp_boxes.W_Float32Box, ) self.w_float64dtype = W_Dtype( types.Float64_instance, @@ -466,7 +469,7 @@ kind=FLOATINGLTR, name="float64", char="d", - w_box_type = space.gettypefor(interp_boxes.W_Float64Box), + BoxType = interp_boxes.W_Float64Box, alternate_constructors=[space.w_float, space.gettypefor(interp_boxes.W_NumberBox), ], @@ -478,7 +481,7 @@ kind=COMPLEXLTR, name="complex64", char="F", - w_box_type = space.gettypefor(interp_boxes.W_Complex64Box), + BoxType = interp_boxes.W_Complex64Box, float_type = self.w_float32dtype, ) self.w_complex128dtype = W_ComplexDtype( @@ -487,7 +490,7 @@ kind=COMPLEXLTR, name="complex128", char="D", - w_box_type = space.gettypefor(interp_boxes.W_Complex128Box), + BoxType = interp_boxes.W_Complex128Box, alternate_constructors=[space.w_complex], aliases=["complex"], float_type = self.w_float64dtype, @@ -499,7 +502,7 @@ kind=FLOATINGLTR, name="", char="g", - w_box_type=space.gettypefor(interp_boxes.W_LongDoubleBox), + BoxType=interp_boxes.W_LongDoubleBox, aliases=["longdouble", "longfloat"], ) self.w_clongdouble = W_ComplexDtype( @@ -508,7 +511,7 @@ kind=COMPLEXLTR, name="", char="G", - w_box_type = space.gettypefor(interp_boxes.W_CLongDoubleBox), + BoxType = interp_boxes.W_CLongDoubleBox, alternate_constructors=[space.w_complex], aliases=["clongdouble", "clongfloat"], float_type = self.w_longdouble, @@ -534,7 +537,7 @@ kind=STRINGLTR, name='string', char='S', - w_box_type = space.gettypefor(interp_boxes.W_StringBox), + BoxType = interp_boxes.W_StringBox, alternate_constructors=[space.w_str], ) self.w_unicodedtype = W_Dtype( @@ -543,7 +546,7 @@ kind=UNICODELTR, name='unicode', char='U', - w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox), + BoxType = interp_boxes.W_UnicodeBox, alternate_constructors=[space.w_unicode], ) self.w_voiddtype = W_Dtype( @@ -552,7 +555,7 @@ kind=VOIDLTR, name='void', char='V', - w_box_type = space.gettypefor(interp_boxes.W_VoidBox), + BoxType = interp_boxes.W_VoidBox, #alternate_constructors=[space.w_buffer], # XXX no buffer in space #alternate_constructors=[space.gettypefor(interp_boxes.W_GenericBox)], @@ -564,7 +567,7 @@ kind=FLOATINGLTR, name="float16", char="e", - w_box_type=space.gettypefor(interp_boxes.W_Float16Box), + BoxType=interp_boxes.W_Float16Box, ) ptr_size = rffi.sizeof(rffi.CCHARP) if ptr_size == 4: @@ -589,7 +592,7 @@ kind=INTPLTR, name='intp', char=INTPLTR, - w_box_type = space.gettypefor(intp_box), + BoxType = intp_box, ) self.w_uintpdtype = W_Dtype( uintp_type, @@ -597,7 +600,7 @@ kind=UINTPLTR, name='uintp', char=UINTPLTR, - w_box_type = space.gettypefor(uintp_box), + BoxType = uintp_box, ) float_dtypes = [self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, @@ -637,7 +640,7 @@ itemtype = getattr(types, 'NonNative' + itemtypename)() self.dtypes_by_name[new_name] = W_Dtype( itemtype, - dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type, + dtype.num, dtype.kind, new_name, dtype.char, dtype.BoxType, native=False) if dtype.kind != dtype.char: can_name = dtype.char @@ -646,7 +649,7 @@ new_name = nonnative_byteorder_prefix + can_name self.dtypes_by_name[new_name] = W_Dtype( itemtype, - dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type, + dtype.num, dtype.kind, new_name, dtype.char, dtype.BoxType, native=False) for alias in dtype.aliases: @@ -723,7 +726,7 @@ w_maxobj = space.wrap(r_ulonglong(1 << (itemsize*8)) - 1) w_minobj = space.wrap(0) items_w = items_w + [w_maxobj, w_minobj] - items_w = items_w + [dtype.w_box_type] + items_w = items_w + [dtype.descr_get_type(space)] space.setitem(w_typeinfo, space.wrap(k), space.newtuple(items_w)) self.w_typeinfo = w_typeinfo From noreply at buildbot.pypy.org Fri Mar 29 17:11:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 29 Mar 2013 17:11:19 +0100 (CET) Subject: [pypy-commit] cffi default: Fix (also for Python 3). Message-ID: <20130329161119.1CFFA1C0705@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1204:c4ddde521b92 Date: 2013-03-29 17:10 +0100 http://bitbucket.org/cffi/cffi/changeset/c4ddde521b92/ Log: Fix (also for Python 3). diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -386,7 +386,7 @@ return # if not copied_enums: - for key, tp in ffi._parser._declarations.iteritems(): + for key, tp in ffi._parser._declarations.items(): if not key.startswith('enum '): continue for enumname, enumval in zip(tp.enumerators, tp.enumvalues): From noreply at buildbot.pypy.org Fri Mar 29 17:46:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 29 Mar 2013 17:46:24 +0100 (CET) Subject: [pypy-commit] cffi default: Test and fix for pull request #11: anonymous enums. Message-ID: <20130329164624.0C3AA1C0183@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1205:5a456356e4ee Date: 2013-03-29 17:46 +0100 http://bitbucket.org/cffi/cffi/changeset/5a456356e4ee/ Log: Test and fix for pull request #11: anonymous enums. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -386,8 +386,9 @@ return # if not copied_enums: + from . import model for key, tp in ffi._parser._declarations.items(): - if not key.startswith('enum '): + if not isinstance(tp, model.EnumType): continue for enumname, enumval in zip(tp.enumerators, tp.enumvalues): if enumname not in library.__dict__: diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -336,9 +336,12 @@ def test_constants_on_lib(self): ffi = FFI(backend=self.Backend()) - ffi.cdef("""enum foo_e { AA, BB, CC=5, DD };""") + ffi.cdef("""enum foo_e { AA, BB, CC=5, DD }; + typedef enum { EE=-5, FF } some_enum_t;""") lib = ffi.dlopen(None) assert lib.AA == 0 assert lib.BB == 1 assert lib.CC == 5 assert lib.DD == 6 + assert lib.EE == -5 + assert lib.FF == -4 From noreply at buildbot.pypy.org Fri Mar 29 17:53:47 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 29 Mar 2013 17:53:47 +0100 (CET) Subject: [pypy-commit] pypy default: use recommended encoding for pushing only one register Message-ID: <20130329165347.5AAD31C0619@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62880:f1505a418fe1 Date: 2013-03-29 18:43 +0200 http://bitbucket.org/pypy/pypy/changeset/f1505a418fe1/ Log: use recommended encoding for pushing only one register diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -42,7 +42,11 @@ def PUSH(self, regs, cond=cond.AL): assert reg.sp.value not in regs - instr = self._encode_reg_list(cond << 28 | 0x92D << 16, regs) + instr = 0 + if len(regs) == 1: + instr = cond << 28 | 0x52D0004 | (regs[0] & 0xF) << 12 + else: + instr = self._encode_reg_list(cond << 28 | 0x92D << 16, regs) self.write32(instr) def VPUSH(self, regs, cond=cond.AL): From noreply at buildbot.pypy.org Fri Mar 29 21:31:41 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 29 Mar 2013 21:31:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: parse time fields as c ints Message-ID: <20130329203141.3D1CC1C0619@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62881:4ce75abda07e Date: 2013-03-29 11:07 -0700 http://bitbucket.org/pypy/pypy/changeset/4ce75abda07e/ Log: parse time fields as c ints diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -404,24 +404,24 @@ "argument must be sequence of " "length 9, not %d", len(tup_w)) - y = space.int_w(tup_w[0]) - tm_mon = space.int_w(tup_w[1]) + y = space.c_int_w(tup_w[0]) + tm_mon = space.c_int_w(tup_w[1]) if tm_mon == 0: tm_mon = 1 - tm_mday = space.int_w(tup_w[2]) + tm_mday = space.c_int_w(tup_w[2]) if tm_mday == 0: tm_mday = 1 - tm_yday = space.int_w(tup_w[7]) + tm_yday = space.c_int_w(tup_w[7]) if tm_yday == 0: tm_yday = 1 rffi.setintfield(glob_buf, 'c_tm_mon', tm_mon) rffi.setintfield(glob_buf, 'c_tm_mday', tm_mday) - rffi.setintfield(glob_buf, 'c_tm_hour', space.int_w(tup_w[3])) - rffi.setintfield(glob_buf, 'c_tm_min', space.int_w(tup_w[4])) - rffi.setintfield(glob_buf, 'c_tm_sec', space.int_w(tup_w[5])) - rffi.setintfield(glob_buf, 'c_tm_wday', space.int_w(tup_w[6])) + rffi.setintfield(glob_buf, 'c_tm_hour', space.c_int_w(tup_w[3])) + rffi.setintfield(glob_buf, 'c_tm_min', space.c_int_w(tup_w[4])) + rffi.setintfield(glob_buf, 'c_tm_sec', space.c_int_w(tup_w[5])) + rffi.setintfield(glob_buf, 'c_tm_wday', space.c_int_w(tup_w[6])) rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday) - rffi.setintfield(glob_buf, 'c_tm_isdst', space.int_w(tup_w[8])) + rffi.setintfield(glob_buf, 'c_tm_isdst', space.c_int_w(tup_w[8])) if _POSIX: if _CYGWIN: pass diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -155,6 +155,11 @@ (0,) * 8) == 'Mon Jan 1 00:00:00 12345' assert rctime.asctime((123456789,) + (0,) * 8) == 'Mon Jan 1 00:00:00 123456789' + sizeof_int = 4 + bigyear = (1 << 8 * sizeof_int - 1) - 1 + asc = rctime.asctime((bigyear, 6, 1) + (0,)*6) + assert asc[-len(str(bigyear)):] == str(bigyear) + raises(OverflowError, rctime.asctime, (bigyear + 1,) + (0,)*8) def test_accept2dyear_access(self): import time as rctime From noreply at buildbot.pypy.org Fri Mar 29 22:46:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 29 Mar 2013 22:46:55 +0100 (CET) Subject: [pypy-commit] jitviewer default: Two changes trying a bit randomly to fix stuff: Message-ID: <20130329214655.647611C0183@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r227:1fadd37bdea6 Date: 2013-03-29 22:46 +0100 http://bitbucket.org/pypy/jitviewer/changeset/1fadd37bdea6/ Log: Two changes trying a bit randomly to fix stuff: * don't just crash when line numbers are out of range * attempt to fix the case of "" code objects that don't have any code on their line 1. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -161,11 +161,14 @@ try: code = self.storage.load_code(loop.filename)[(loop.startlineno, loop.name)] - if code.co_name == '' and code.co_firstlineno == 1: + if code.co_name == '': with open(code.co_filename) as f: - source = CodeRepr(f.read(), code, loop) + source = f.readlines() + striplines = max(code.co_firstlineno - 1, 0) + source = ''.join(source[striplines:]) else: - source = CodeRepr(inspect.getsource(code), code, loop) + source = inspect.getsource(code) + source = CodeRepr(source, code, loop) except (IOError, OSError): source = CodeReprNoFile(loop) d = {'html': flask.render_template('loop.html', diff --git a/_jitviewer/display.py b/_jitviewer/display.py --- a/_jitviewer/display.py +++ b/_jitviewer/display.py @@ -49,4 +49,9 @@ last_lineno = no else: no = last_lineno - self.lines[no - self.firstlineno].chunks.append(chunk) + i = no - self.firstlineno + if i < 0: + i = 0 + while len(self.lines) <= i: + self.lines.append(LineRepr('# missing line', False)) + self.lines[i].chunks.append(chunk) From noreply at buildbot.pypy.org Fri Mar 29 23:42:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 29 Mar 2013 23:42:47 +0100 (CET) Subject: [pypy-commit] cffi default: Fix a warning. Message-ID: <20130329224247.4A0F71C0619@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1206:c6a699d27cab Date: 2013-03-29 23:42 +0100 http://bitbucket.org/cffi/cffi/changeset/c6a699d27cab/ Log: Fix a warning. diff --git a/demo/_curses.py b/demo/_curses.py --- a/demo/_curses.py +++ b/demo/_curses.py @@ -25,7 +25,7 @@ int tigetflag(char *); int tigetnum(char *); char *tigetstr(char *); -char *tparm (char *, ...); +char *tparm (const char *, ...); int cbreak(void); int nocbreak(void); From noreply at buildbot.pypy.org Fri Mar 29 23:52:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 29 Mar 2013 23:52:25 +0100 (CET) Subject: [pypy-commit] pypy curses_cffi: Fixes the warnings -- and in one case the warning is important -- for Message-ID: <20130329225225.312711C07B6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: curses_cffi Changeset: r62882:7ea81f936741 Date: 2013-03-29 23:52 +0100 http://bitbucket.org/pypy/pypy/changeset/7ea81f936741/ Log: Fixes the warnings -- and in one case the warning is important -- for running on Linux. diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -12,7 +12,7 @@ typedef ... SCREEN; typedef unsigned long mmask_t; typedef unsigned char bool; -typedef unsigned int chtype; +typedef unsigned long chtype; typedef chtype attr_t; typedef struct @@ -121,7 +121,7 @@ bool isendwin(void); bool is_linetouched(WINDOW *, int); bool is_wintouched(WINDOW *); -char * keyname(int); +const char * keyname(int); int keypad(WINDOW *, bool); char killchar(void); int leaveok(WINDOW *, bool); @@ -227,7 +227,7 @@ int tigetnum(char *); char * tigetstr(char *); int putp(const char *); -char * tparm(char *, ...); +char * tparm(const char *, ...); int getattrs(const WINDOW *); int getcurx(const WINDOW *); int getcury(const WINDOW *); @@ -245,7 +245,7 @@ int mouseinterval(int); void setsyx(int y, int x); -char *unctrl(chtype); +const char *unctrl(chtype); int use_default_colors(void); int has_key(int); @@ -273,7 +273,7 @@ PANEL *panel_above(const PANEL *); PANEL *panel_below(const PANEL *); int set_panel_userptr(PANEL *, void *); -void *panel_userptr(const PANEL *); +const void *panel_userptr(const PANEL *); int move_panel(PANEL *, int, int); int replace_panel(PANEL *,WINDOW *); int panel_hidden(const PANEL *); From noreply at buildbot.pypy.org Sat Mar 30 04:00:23 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 30 Mar 2013 04:00:23 +0100 (CET) Subject: [pypy-commit] pypy improve-docs-2: starts a doc rework Message-ID: <20130330030023.7298F1C0183@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: improve-docs-2 Changeset: r62883:b664434c47de Date: 2013-03-27 01:16 -0700 http://bitbucket.org/pypy/pypy/changeset/b664434c47de/ Log: starts a doc rework diff --git a/README.rst b/README.rst --- a/README.rst +++ b/README.rst @@ -13,9 +13,9 @@ http://pypy.org/ -The getting-started document will help guide you: +If you want to help developing PyPy, this document might help you: - http://doc.pypy.org/en/latest/getting-started.html + http://doc.pypy.org/ It will also point you to the rest of the documentation which is generated from files in the pypy/doc directory within the source repositories. Enjoy diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -1,9 +1,15 @@ -=============================================================================== -Getting Started with the Translation Toolchain and Development Process -=============================================================================== +============================ +Getting Started with RPython +============================ .. contents:: + +This should really write a word of two about **WHAT** is RPython +XXX +XXX +XXX + .. _`try out the translator`: Trying out the translator 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 @@ -6,7 +6,7 @@ PyPy's Python interpreter is a very compliant Python -interpreter implemented in Python. When translated to C, it passes most of +interpreter implemented in RPython. When compiled, it passes most of `CPythons core language regression tests`_ and comes with many of the extension modules included in the standard library including ``ctypes``. It can run large libraries such as Django_ and Twisted_. There are some small behavioral @@ -146,6 +146,8 @@ Translating using the CLI backend +++++++++++++++++++++++++++++++++ +**Note: the CLI backend is no longer maintained** + To create a standalone .NET executable using the `CLI backend`_:: ./translate.py --backend=cli targetpypystandalone.py diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -1,15 +1,36 @@ -Welcome to PyPy Development -============================================= +Welcome to PyPy +=============== The PyPy project aims at producing a flexible and fast Python_ -implementation. The guiding idea is to translate a Python-level -description of the Python language itself to lower level languages. -Rumors have it that the secret goal is being faster-than-C which is -nonsense, isn't it? `more...`_ +implementation. For the general idea what is pypy, consult the `pypy website`_. +This page documents entry points into the development of the PyPy project. +If you just want to use it, consult the `download`_ page on the PyPy website +and `getting started with pypy`_ document. -Getting into PyPy ... -============================================= +PyPy is written in a language called `RPython`_, which is suitable for +writing dynamic language interpreters (and not much else). +`Starting with RPython`_ should provide a reasonable overview if you want +to learn the language. + +**If you want to contribute to PyPy**, please read `how to contribute`_ first. +PyPy development style is vastly different than most other software projects +and it usually comes as surprise to most people. What is **not** necessary is +having academic knowledge from university about writing compilers. Most of +it does not apply to PyPy at all. + +All of the documentation and source code is available under the MIT license, +unless otherwise specified. Consult `LICENSE`_ + +.. _`download`: http://pypy.org/download.html +.. _`getting started with pypy`: getting-started-python.html +.. _`RPython`: coding-guide.html#RPython +.. _`Starting with RPython`: getting-started-dev.html +.. _`how to contribute`: how-to-contribute.html +.. _`pypy website`: http://pypy.org + +Index of various topics: +======================== * `Getting started`_: how to install and run the PyPy Python interpreter @@ -26,19 +47,28 @@ * `potential project ideas`_: In case you want to get your feet wet... Documentation for the PyPy Python Interpreter -=============================================== +============================================= New features of PyPy's Python Interpreter and Translation Framework: * `Differences between PyPy and CPython`_ - * `What PyPy can do for your objects`_ - * `Continulets and greenlets`_ + * `What PyPy can do for your objects`_ - transparent proxy documentation + * `Continulets and greenlets`_ - documentation about stackless features * `JIT Generation in PyPy`_ + * `JIT hooks`_ * `Sandboxing Python code`_ + * `Garbage collection environment variables`_ Status_ of the project. +.. _`Differences between PyPy and CPython`: cpython_differences.html +.. _`What PyPy can do for your objects`: objspace-proxies.html +.. _`Continulets and greenlets_`: stackless.html +.. _`JIT Generation in PyPy`: jit/index.html +.. _`JIT hooks`: jit-hooks.html +.. _`Sandboxing Python code`: sandbox.html +.. _`Garbage collection environment variables`: gc_info.html Mailing lists, bug tracker, IRC channel ============================================= @@ -83,12 +113,7 @@ Project Documentation ===================================== -PyPy was funded by the EU for several years. See the `web site of the EU -project`_ for more details. - -.. _`web site of the EU project`: http://pypy.org - -architecture_ gives a complete view of PyPy's basic design. +`architecture`_ gives a complete view of PyPy's basic design. `coding guide`_ helps you to write code for PyPy (especially also describes coding in RPython a bit). @@ -112,12 +137,11 @@ `Glossary`_ of PyPy words to help you align your inner self with the PyPy universe. - Status =================================== PyPy can be used to run Python programs on Linux, OS/X, -Windows, on top of .NET, and on top of Java. +Windows. To dig into PyPy it is recommended to try out the current Mercurial default branch, which is always working or mostly working, instead of the latest release, which is `2.0 beta1`__. @@ -176,13 +200,21 @@ `configuration documentation`_ describes the various configuration options that allow you to customize PyPy. +`pypy on windows`_ + +`command line reference`_ + `CLI backend`_ describes the details of the .NET backend. `JIT Generation in PyPy`_ describes how we produce the Python Just-in-time Compiler from our Python interpreter. +`directory cross-reference`_ - +.. _`garbage collector`: garbage_collection.html +.. _`directory cross-reference`: dir-reference.html +.. _`pypy on windows`: windows.html +.. _`command line reference`: commandline_ref.html .. _`FAQ`: faq.html .. _Glossary: glossary.html .. _`PyPy video documentation`: video-index.html @@ -198,7 +230,7 @@ .. _`translation aspects`: translation-aspects.html .. _`configuration documentation`: config/ .. _`coding guide`: coding-guide.html -.. _`architecture`: architecture.html +.. _`Architecture`: architecture.html .. _`getting started`: getting-started.html .. _`bytecode interpreter`: interpreter.html .. _`EU reports`: index-report.html @@ -211,168 +243,14 @@ .. _`Sandboxing Python code`: sandbox.html .. _`LICENSE`: https://bitbucket.org/pypy/pypy/src/default/LICENSE -PyPy directory cross-reference ------------------------------- - -Here is a fully referenced alphabetical two-level deep -directory overview of PyPy: - -================================= ============================================ -Directory explanation/links -================================= ============================================ -`pypy/bin/`_ command-line scripts, mainly - `pypy/bin/pyinteractive.py`_ - -`pypy/config/`_ handles the numerous options for building - and running PyPy - -`pypy/doc/`_ text versions of PyPy developer - documentation - -`pypy/doc/config/`_ documentation for the numerous translation - options - -`pypy/doc/discussion/`_ drafts of ideas and documentation - -``doc/*/`` other specific documentation topics or tools - -`pypy/interpreter/`_ `bytecode interpreter`_ and related objects - (frames, functions, modules,...) - -`pypy/interpreter/pyparser/`_ interpreter-level Python source parser - -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, - via an AST representation - -`pypy/module/`_ contains `mixed modules`_ - implementing core modules with - both application and interpreter level code. - Not all are finished and working. Use - the ``--withmod-xxx`` - or ``--allworkingmodules`` translation - options. - -`pypy/objspace/`_ `object space`_ implementations - -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's - objects and types - -`pypy/tool/`_ various utilities and hacks used - from various places - -`pypy/tool/algo/`_ general-purpose algorithmic and mathematic - tools - -`pypy/tool/pytest/`_ support code for our `testing methods`_ - - -`rpython/annotator/`_ `type inferencing code`_ for - `RPython`_ programs - -`rpython/config/`_ handles the numerous options for RPython - - -`rpython/flowspace/`_ the FlowObjSpace_ implementing - `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ - programs - -`rpython/rtyper/`_ the `RPython Typer`_ - -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for - C-like backends - -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ - for OO backends - -`rpython/memory/`_ the `garbage collector`_ construction - framework - -`rpython/translator/`_ translation_ backends and support code - -`rpython/translator/backendopt/`_ general optimizations that run before a - backend generates code - -`rpython/translator/c/`_ the `GenC backend`_, producing C code - from an - RPython program (generally via the rtyper_) - -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ - (Microsoft CLR or Mono_) - -`pypy/goal/`_ our `main PyPy-translation scripts`_ - live here - -`rpython/translator/jvm/`_ the Java backend - -`rpython/translator/tool/`_ helper tools for translation - -`dotviewer/`_ `graph viewer`_ - -``*/test/`` many directories have a test subdirectory - containing test - modules (see `Testing in PyPy`_) - -``_cache/`` holds cache files from various purposes -================================= ============================================ - -.. _`bytecode interpreter`: interpreter.html -.. _`Testing in PyPy`: coding-guide.html#testing-in-pypy -.. _`mixed modules`: coding-guide.html#mixed-modules -.. _`modules`: coding-guide.html#modules -.. _`basil`: http://people.cs.uchicago.edu/~jriehl/BasilTalk.pdf -.. _`object space`: objspace.html -.. _FlowObjSpace: objspace.html#the-flow-object-space -.. _`transparent proxies`: objspace-proxies.html#tproxy -.. _`Differences between PyPy and CPython`: cpython_differences.html -.. _`What PyPy can do for your objects`: objspace-proxies.html -.. _`Continulets and greenlets`: stackless.html -.. _StdObjSpace: objspace.html#the-standard-object-space -.. _`abstract interpretation`: http://en.wikipedia.org/wiki/Abstract_interpretation -.. _`rpython`: coding-guide.html#rpython -.. _`type inferencing code`: translation.html#the-annotation-pass -.. _`RPython Typer`: translation.html#rpython-typer -.. _`testing methods`: coding-guide.html#testing-in-pypy -.. _`translation`: translation.html -.. _`GenC backend`: translation.html#genc -.. _`CLI backend`: cli-backend.html -.. _`py.py`: getting-started-python.html#the-py.py-interpreter -.. _`translatorshell.py`: getting-started-dev.html#try-out-the-translator -.. _JIT: jit/index.html -.. _`JIT Generation in PyPy`: jit/index.html -.. _`just-in-time compiler generator`: jit/index.html -.. _rtyper: rtyper.html -.. _`low-level type system`: rtyper.html#low-level-type -.. _`object-oriented type system`: rtyper.html#oo-type -.. _`garbage collector`: garbage_collection.html -.. _`main PyPy-translation scripts`: getting-started-python.html#translating-the-pypy-python-interpreter -.. _`.NET`: http://www.microsoft.com/net/ -.. _Mono: http://www.mono-project.com/ -.. _`"standard library"`: rlib.html -.. _`graph viewer`: getting-started-dev.html#try-out-the-translator - - .. The following documentation is important and reasonably up-to-date: .. extradoc: should this be integrated one level up: dcolish? - .. toctree:: :maxdepth: 1 :hidden: - getting-started.rst - getting-started-python.rst - getting-started-dev.rst - windows.rst - faq.rst - commandline_ref.rst - architecture.rst - coding-guide.rst - cpython_differences.rst - garbage_collection.rst - gc_info.rst interpreter.rst objspace.rst __pypy__-module.rst diff --git a/pypy/doc/needswork.txt b/pypy/doc/needswork.txt deleted file mode 100644 --- a/pypy/doc/needswork.txt +++ /dev/null @@ -1,3 +0,0 @@ -.. warning:: - - This documentation needs work (as discussed during the Gothenburg sprint in 2011) diff --git a/pypy/doc/objspace-proxies.rst b/pypy/doc/objspace-proxies.rst --- a/pypy/doc/objspace-proxies.rst +++ b/pypy/doc/objspace-proxies.rst @@ -5,7 +5,6 @@ .. contents:: - Thanks to the `Object Space`_ architecture, any feature that is based on proxying, extending, changing or otherwise controlling the behavior of all objects in a running program is easy to implement on From noreply at buildbot.pypy.org Sat Mar 30 04:00:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 30 Mar 2013 04:00:24 +0100 (CET) Subject: [pypy-commit] pypy improve-docs-2: continue working on improving docs Message-ID: <20130330030024.B8FA01C0183@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: improve-docs-2 Changeset: r62884:75c166d74765 Date: 2013-03-30 04:59 +0200 http://bitbucket.org/pypy/pypy/changeset/75c166d74765/ Log: continue working on improving docs diff --git a/pypy/doc/dir-reference.rst b/pypy/doc/dir-reference.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/dir-reference.rst @@ -0,0 +1,140 @@ +PyPy directory cross-reference +------------------------------ + +Here is a fully referenced alphabetical two-level deep +directory overview of PyPy: + +================================= ============================================ +Directory explanation/links +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ + +`pypy/config/`_ handles the numerous options for building + and running PyPy + +`pypy/doc/`_ text versions of PyPy developer + documentation + +`pypy/doc/config/`_ documentation for the numerous translation + options + +`pypy/doc/discussion/`_ drafts of ideas and documentation + +``doc/*/`` other specific documentation topics or tools + +`pypy/interpreter/`_ `bytecode interpreter`_ and related objects + (frames, functions, modules,...) + +`pypy/interpreter/pyparser/`_ interpreter-level Python source parser + +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation + +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with + both application and interpreter level code. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. + +`pypy/objspace/`_ `object space`_ implementations + +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types + +`pypy/tool/`_ various utilities and hacks used + from various places + +`pypy/tool/algo/`_ general-purpose algorithmic and mathematic + tools + +`pypy/tool/pytest/`_ support code for our `testing methods`_ + + +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs + +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends + +`rpython/memory/`_ the `garbage collector`_ construction + framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an + RPython program (generally via the rtyper_) + +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) + +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here + +`rpython/translator/jvm/`_ the Java backend + +`rpython/translator/tool/`_ helper tools for translation + +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test + modules (see `Testing in PyPy`_) + +``_cache/`` holds cache files from various purposes +================================= ============================================ + +.. _`bytecode interpreter`: interpreter.html +.. _`Testing in PyPy`: coding-guide.html#testing-in-pypy +.. _`mixed modules`: coding-guide.html#mixed-modules +.. _`modules`: coding-guide.html#modules +.. _`basil`: http://people.cs.uchicago.edu/~jriehl/BasilTalk.pdf +.. _`object space`: objspace.html +.. _FlowObjSpace: objspace.html#the-flow-object-space +.. _`transparent proxies`: objspace-proxies.html#tproxy +.. _`Differences between PyPy and CPython`: cpython_differences.html +.. _`What PyPy can do for your objects`: objspace-proxies.html +.. _`Continulets and greenlets`: stackless.html +.. _StdObjSpace: objspace.html#the-standard-object-space +.. _`abstract interpretation`: http://en.wikipedia.org/wiki/Abstract_interpretation +.. _`rpython`: coding-guide.html#rpython +.. _`type inferencing code`: translation.html#the-annotation-pass +.. _`RPython Typer`: translation.html#rpython-typer +.. _`testing methods`: coding-guide.html#testing-in-pypy +.. _`translation`: translation.html +.. _`GenC backend`: translation.html#genc +.. _`CLI backend`: cli-backend.html +.. _`py.py`: getting-started-python.html#the-py.py-interpreter +.. _`translatorshell.py`: getting-started-dev.html#try-out-the-translator +.. _JIT: jit/index.html +.. _`JIT Generation in PyPy`: jit/index.html +.. _`just-in-time compiler generator`: jit/index.html +.. _rtyper: rtyper.html +.. _`low-level type system`: rtyper.html#low-level-type +.. _`object-oriented type system`: rtyper.html#oo-type +.. _`garbage collector`: garbage_collection.html +.. _`main PyPy-translation scripts`: getting-started-python.html#translating-the-pypy-python-interpreter +.. _`.NET`: http://www.microsoft.com/net/ +.. _Mono: http://www.mono-project.com/ +.. _`"standard library"`: rlib.html +.. _`graph viewer`: getting-started-dev.html#try-out-the-translator diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -6,6 +6,9 @@ This should really write a word of two about **WHAT** is RPython + +XXX ltratt blog post +XXX "how to write interpreters" links XXX XXX XXX diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/how-to-contribute.rst @@ -0,0 +1,78 @@ +How to contribute to PyPy +------------------------- + +This page describes how to contribute to the PyPy project. The first thing +to remember is that PyPy project is very different than most projects out there. +It's also different from a classic compiler project, so academic courses +about compilers often don't apply or lead in the wrong direction. + +Don't just hack +--------------- + +The first and most important rule how not to contribute to PyPy is +"just hacking". This won't work. There are two major reasons why not +-- build times are large and PyPy has very thick layer separation which +make it harder to "just hack a feature". + +Test driven development +----------------------- + +Instead, we practice a lot of test driven development. This is partly because +of very high quality requirements for compilers and partly because there is +simply no other way to get around such complex project, that will keep you sane. +There are probably people out there who are smart enough not to need it, we're +not one of those. Familiarity with `pytest`_ is a must-have before +doing anything else. +This leads to the next issue: + +Layers +------ + +PyPy has layers. Those layers help us keep the respective parts separated enough +to be worked on independently and make the complexity manageable. This is, +again, just a sanity requirement for such a complex project. For example writing +a new optimization for the JIT usually does **not** involve touching a Python +interpreter at all or the JIT assembler backend or the garbage collector. +Instead it requires writing small tests in +``rpython/jit/metainterp/optimizeopt/test/test_*`` and fixing files there. +After that, you can just compile PyPy and things should just work. + +The short list of layers for further reading. For each of those layers, a good +entry point is a test subdirectory in respective directories. It usually +describes (better or worse) the interfaces between the submodules. For the +``pypy`` subdirectory, most tests are small snippets of python programs that +check for correctness (calls ``AppTestXxx``) that will call the appropriate +part of the interpreter. For the ``rpython`` directory, most tests are small +RPython interpreters that perform certain tasks. To see how they translate +to low-level graphs, run them with ``--view``. To see small interpreters +with a JIT compiler, use ``--viewloops`` option. + +* **python interpreter** - it's the part implemented in the ``pypy/`` directory. + It's implemented in RPython, which is a high level static language with + classes, garbage collection, just-in-time compiler generation and the ability + to call C. A cool part about it is that it can be run untranslated, so all + the tests are runnable without translating PyPy. + + **interpreter** contains the interpreter core + + **objspace** contains implementations of various objects exported to + the Python layer + + **module** directory contains extension modules written in RPython + +* **rpython compiler** that resides in ``rpython/annotator`` and + ``rpython/rtyper`` directories. Consult `introduction to RPython`_ for + further reading + +* **JIT generator** lives in ``rpython/jit`` directory. optimizations live + in ``rpython/jit/metainterp/optimizeopt``, the main JIT in + ``rpython/jit/metainterp`` (runtime part) and + ``rpython/jit/codewriter`` (translation-time part). Backends live in + ``rpython/jit/backend``. + +* **garbage collection** lives in ``rpython/memory`` + +The rest of directories serve specific niche goal and are unlikely a good +entry point. + +.. _`introduction to RPython`: getting-started-dev.rst From noreply at buildbot.pypy.org Sat Mar 30 07:47:21 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Sat, 30 Mar 2013 07:47:21 +0100 (CET) Subject: [pypy-commit] pypy remove-string-smm: Merge Message-ID: <20130330064721.44CD01C0183@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: remove-string-smm Changeset: r62885:27654a7869f9 Date: 2013-03-27 06:57 +0200 http://bitbucket.org/pypy/pypy/changeset/27654a7869f9/ Log: Merge diff too long, truncating to 2000 out of 7430 lines diff --git a/.tddium.requirements.txt b/.tddium.requirements.txt new file mode 100644 --- /dev/null +++ b/.tddium.requirements.txt @@ -0,0 +1,1 @@ +pytest diff --git a/lib-python/2/pickle.py b/lib-python/2/pickle.py --- a/lib-python/2/pickle.py +++ b/lib-python/2/pickle.py @@ -1409,26 +1409,11 @@ except ImportError: from StringIO import StringIO -try: - from __pypy__.builders import StringBuilder -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO -else: - class StringBuilderFile(object): - ''' pickle uses only file.write - provide this method, - use StringBuilder for speed - ''' - def __init__(self): - self.builder = StringBuilder() - self.write = self.builder.append - self.getvalue = self.builder.build - def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -97,18 +97,12 @@ from pickle import StringIO -try: - from pickle import StringBuilderFile -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - StringBuilderFile = StringIO - PythonPickler = Pickler class Pickler(PythonPickler): def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): - self.__f = StringBuilderFile() + self.__f = StringIO() PythonPickler.__init__(self, self.__f, args[0], **kw) else: PythonPickler.__init__(self, *args, **kw) @@ -126,7 +120,7 @@ @builtinify def dumps(obj, protocol=None): - file = StringBuilderFile() + file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -189,11 +189,6 @@ BoolOption("withtproxy", "support transparent proxies", default=True), - BoolOption("withsmallint", "use tagged integers", - default=False, - requires=[("objspace.std.withprebuiltint", False), - ("translation.taggedpointers", True)]), - BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False), @@ -204,9 +199,7 @@ default=100, cmdline="--prebuiltintto"), BoolOption("withsmalllong", "use a version of 'long' in a C long long", - default=False, - requires=[("objspace.std.withsmallint", False)]), - # ^^^ because of missing delegate_xx2yy + default=False), BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", default=False), diff --git a/pypy/config/test/test_pypyoption.py b/pypy/config/test/test_pypyoption.py --- a/pypy/config/test/test_pypyoption.py +++ b/pypy/config/test/test_pypyoption.py @@ -11,11 +11,11 @@ assert conf.objspace.usemodules.gc - conf.objspace.std.withsmallint = True - assert not conf.objspace.std.withprebuiltint + conf.objspace.std.withmapdict = True + assert conf.objspace.std.withmethodcache conf = get_pypy_config() - conf.objspace.std.withprebuiltint = True - py.test.raises(ConfigError, "conf.objspace.std.withsmallint = True") + conf.objspace.std.withmethodcache = False + py.test.raises(ConfigError, "conf.objspace.std.withmapdict = True") def test_conflicting_gcrootfinder(): conf = get_pypy_config() diff --git a/pypy/doc/config/objspace.std.withsmallint.txt b/pypy/doc/config/objspace.std.withsmallint.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.std.withsmallint.txt +++ /dev/null @@ -1,6 +0,0 @@ -Use "tagged pointers" to represent small enough integer values: Integers that -fit into 31 bits (respective 63 bits on 64 bit machines) are not represented by -boxing them in an instance of ``W_IntObject``. Instead they are represented as a -pointer having the lowest bit set and the rest of the bits used to store the -value of the integer. This gives a small speedup for integer operations as well -as better memory behaviour. diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1144,7 +1144,7 @@ assert space.eq_w(get_num("-0"), space.wrap(0)) assert space.eq_w(get_num("-0xAAAAAAL"), space.wrap(-0xAAAAAAL)) n = get_num(str(-sys.maxint - 1)) - assert space.is_true(space.isinstance(n, space.w_int)) + assert space.isinstance_w(n, space.w_int) for num in ("0o53", "0O53", "0o0000053", "0O00053"): assert space.eq_w(get_num(num), space.wrap(053)) for num in ("0b00101", "0B00101", "0b101", "0B101"): diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -211,6 +211,10 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def float_w(self, space): + raise OperationError(space.w_TypeError, + typed_unwrap_error_msg(space, "float", self)) + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -219,6 +223,22 @@ raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) + def int(self, space): + w_impl = space.lookup(self, '__int__') + if w_impl is None: + typename = space.type(self).getname(space) + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for int(): '%s'", + typename) + w_result = space.get_and_call_function(w_impl, self) + + if (space.isinstance_w(w_result, space.w_int) or + space.isinstance_w(w_result, space.w_long)): + return w_result + typename = space.type(w_result).getname(space) + msg = "__int__ returned non-int (type '%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) + def __spacebind__(self, space): return self @@ -257,18 +277,13 @@ def __init__(self, space): Cache.__init__(self) self.space = space + def _build(self, key): - val = self.space.enter_cache_building_mode() - try: - return self.build(key) - finally: - self.space.leave_cache_building_mode(val) + return self.build(key) + def _ready(self, result): - val = self.space.enter_cache_building_mode() - try: - return self.ready(result) - finally: - self.space.leave_cache_building_mode(val) + return self.ready(result) + def ready(self, result): pass @@ -557,11 +572,6 @@ """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" - def enter_cache_building_mode(self): - "hook for the flow object space" - def leave_cache_building_mode(self, val): - "hook for the flow object space" - @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." @@ -903,7 +913,7 @@ if self.is_w(w_exc_type, w_check_class): return True # fast path (also here to handle string exceptions) try: - if self.is_true(self.isinstance(w_check_class, self.w_tuple)): + if self.isinstance_w(w_check_class, self.w_tuple): for w_t in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_t): return True @@ -1031,9 +1041,6 @@ def issequence_w(self, w_obj): return (self.findattr(w_obj, self.wrap("__getitem__")) is not None) - def isinstance_w(self, w_obj, w_type): - return self.is_true(self.isinstance(w_obj, w_type)) - # The code below only works # for the simple case (new-style instance). # These methods are patched with the full logic by the __builtin__ @@ -1045,11 +1052,11 @@ def abstract_isinstance_w(self, w_obj, w_cls): # Equivalent to 'isinstance(obj, cls)'. - return self.is_true(self.isinstance(w_obj, w_cls)) + return self.isinstance_w(w_obj, w_cls) def abstract_isclass_w(self, w_obj): # Equivalent to 'isinstance(obj, type)'. - return self.is_true(self.isinstance(w_obj, self.w_type)) + return self.isinstance_w(w_obj, self.w_type) def abstract_getclass(self, w_obj): # Equivalent to 'obj.__class__'. @@ -1087,7 +1094,7 @@ expression = compiler.compile(expression, '?', 'eval', 0, hidden_applevel=hidden_applevel) else: - raise TypeError, 'space.eval(): expected a string, code or PyCode object' + raise TypeError('space.eval(): expected a string, code or PyCode object') return expression.exec_code(self, w_globals, w_locals) def exec_(self, statement, w_globals, w_locals, hidden_applevel=False, @@ -1101,7 +1108,7 @@ statement = compiler.compile(statement, filename, 'exec', 0, hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): - raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') if not self.is_true(self.contains(w_globals, w_key)): self.setitem(w_globals, w_key, self.wrap(self.builtin)) @@ -1157,7 +1164,7 @@ -> (index, 0, 0) or (start, stop, step) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) @@ -1177,7 +1184,7 @@ -> (index, 0, 0, 1) or (start, stop, step, slice_length) """ - if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)): + if self.isinstance_w(w_index_or_slice, self.w_slice): from pypy.objspace.std.sliceobject import W_SliceObject assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step, length = w_index_or_slice.indices4(self, @@ -1310,15 +1317,21 @@ def int_w(self, w_obj): return w_obj.int_w(self) + def int(self, w_obj): + return w_obj.int(self) + def uint_w(self, w_obj): return w_obj.uint_w(self) def bigint_w(self, w_obj): return w_obj.bigint_w(self) + def float_w(self, w_obj): + return w_obj.float_w(self) + def realstr_w(self, w_obj): # Like str_w, but only works if w_obj is really of type 'str'. - if not self.is_true(self.isinstance(w_obj, self.w_str)): + if not self.isinstance_w(w_obj, self.w_str): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) return self.str_w(w_obj) @@ -1338,7 +1351,7 @@ def realunicode_w(self, w_obj): # Like unicode_w, but only works if w_obj is really of type # 'unicode'. - if not self.is_true(self.isinstance(w_obj, self.w_unicode)): + if not self.isinstance_w(w_obj, self.w_unicode): raise OperationError(self.w_TypeError, self.wrap('argument must be a unicode')) return self.unicode_w(w_obj) @@ -1350,7 +1363,7 @@ # This is all interface for gateway.py. def gateway_int_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.int_w(self.int(w_obj)) @@ -1359,19 +1372,19 @@ return self.float_w(self.float(w_obj)) def gateway_r_longlong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_longlong_w(self.int(w_obj)) def gateway_r_uint_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.uint_w(self.int(w_obj)) def gateway_r_ulonglong_w(self, w_obj): - if self.is_true(self.isinstance(w_obj, self.w_float)): + if self.isinstance_w(w_obj, self.w_float): raise OperationError(self.w_TypeError, self.wrap("integer argument expected, got float")) return self.r_ulonglong_w(self.int(w_obj)) @@ -1488,23 +1501,28 @@ space.exec_(str(source), w_glob, w_glob) return space.getitem(w_glob, space.wrap('anonymous')) + class DummyLock(object): def acquire(self, flag): return True + def release(self): pass + def _freeze_(self): return True + def __enter__(self): pass + def __exit__(self, *args): pass dummy_lock = DummyLock() -## Table describing the regular part of the interface of object spaces, -## namely all methods which only take w_ arguments and return a w_ result -## (if any). Note: keep in sync with rpython.flowspace.operation.Table. +# Table describing the regular part of the interface of object spaces, +# namely all methods which only take w_ arguments and return a w_ result +# (if any). ObjSpace.MethodTable = [ # method name # symbol # number of arguments # special method name(s) @@ -1531,7 +1549,7 @@ ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), - ('abs' , 'abs', 1, ['__abs__']), + ('abs', 'abs', 1, ['__abs__']), ('hex', 'hex', 1, ['__hex__']), ('oct', 'oct', 1, ['__oct__']), ('ord', 'ord', 1, []), @@ -1584,12 +1602,12 @@ ('delete', 'delete', 2, ['__delete__']), ('userdel', 'del', 1, ['__del__']), ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py - ] +] ObjSpace.BuiltinModuleTable = [ '__builtin__', 'sys', - ] +] ObjSpace.ConstantTable = [ 'None', @@ -1597,7 +1615,7 @@ 'True', 'Ellipsis', 'NotImplemented', - ] +] ObjSpace.ExceptionTable = [ 'ArithmeticError', @@ -1640,7 +1658,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', - ] +] if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] @@ -1678,4 +1696,4 @@ 'newslice', 'call_args', 'marshal_w', - ] +] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -183,7 +183,7 @@ # w_type = self.w_type w_value = self.get_w_value(space) - while space.is_true(space.isinstance(w_type, space.w_tuple)): + while space.isinstance_w(w_type, space.w_tuple): w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): @@ -198,7 +198,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.is_true(space.isinstance(w_value, space.w_tuple)): + if space.isinstance_w(w_value, space.w_tuple): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -22,7 +22,6 @@ assert not func.can_change_code return func.code - class Function(W_Root): """A function is a code object captured with some environment: an object space, a dictionary of globals, default arguments, @@ -208,7 +207,7 @@ def descr_function__new__(space, w_subtype, w_code, w_globals, w_name=None, w_argdefs=None, w_closure=None): code = space.interp_w(Code, w_code) - if not space.is_true(space.isinstance(w_globals, space.w_dict)): + if not space.isinstance_w(w_globals, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("expected dict")) if not space.is_none(w_name): name = space.str_w(w_name) @@ -356,7 +355,7 @@ if space.is_w(w_defaults, space.w_None): self.defs_w = [] return - if not space.is_true(space.isinstance(w_defaults, space.w_tuple)): + if not space.isinstance_w(w_defaults, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None")) self.defs_w = space.fixedview(w_defaults) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -818,6 +818,8 @@ d = {} exec func_code.compile() in d f = d['f'] + f.__module__ = func.__module__ + # necessary for unique identifiers for pickling f.func_name = func.func_name if unwrap_spec is None: unwrap_spec = {} diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -81,7 +81,7 @@ def descr__reduce__(self, space): w_name = space.finditem(self.w_dict, space.wrap('__name__')) if (w_name is None or - not space.is_true(space.isinstance(w_name, space.w_str))): + not space.isinstance_w(w_name, space.w_str)): # maybe raise exception here (XXX this path is untested) return space.w_None w_modules = space.sys.get('modules') diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -232,7 +232,7 @@ def getdocstring(self, space): if self.co_consts_w: # it is probably never empty w_first = self.co_consts_w[0] - if space.is_true(space.isinstance(w_first, space.w_basestring)): + if space.isinstance_w(w_first, space.w_basestring): return w_first return space.w_None @@ -246,20 +246,20 @@ else: consts[num] = self.space.unwrap(w) num += 1 - return new.code( self.co_argcount, - self.co_nlocals, - self.co_stacksize, - self.co_flags, - self.co_code, - tuple(consts), - tuple(self.co_names), - tuple(self.co_varnames), - self.co_filename, - self.co_name, - self.co_firstlineno, - self.co_lnotab, - tuple(self.co_freevars), - tuple(self.co_cellvars) ) + return new.code(self.co_argcount, + self.co_nlocals, + self.co_stacksize, + self.co_flags, + self.co_code, + tuple(consts), + tuple(self.co_names), + tuple(self.co_varnames), + self.co_filename, + self.co_name, + self.co_firstlineno, + self.co_lnotab, + tuple(self.co_freevars), + tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): from pypy.interpreter.pyframe import CPythonFrame @@ -349,12 +349,12 @@ if nlocals < 0: raise OperationError(space.w_ValueError, space.wrap("code: nlocals must not be negative")) - if not space.is_true(space.isinstance(w_constants, space.w_tuple)): + if not space.isinstance_w(w_constants, space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("Expected tuple for constants")) - consts_w = space.fixedview(w_constants) - names = unpack_str_tuple(space, w_names) - varnames = unpack_str_tuple(space, w_varnames) + consts_w = space.fixedview(w_constants) + names = unpack_str_tuple(space, w_names) + varnames = unpack_str_tuple(space, w_varnames) if w_freevars is not None: freevars = unpack_str_tuple(space, w_freevars) else: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -777,12 +777,12 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space - if space.is_true(space.isinstance(w_2, space.w_tuple)): + if space.isinstance_w(w_2, space.w_tuple): for w_t in space.fixedview(w_2): - if space.is_true(space.isinstance(w_t, space.w_str)): + if space.isinstance_w(w_t, space.w_str): msg = "catching of string exceptions is deprecated" space.warn(space.wrap(msg), space.w_DeprecationWarning) - elif space.is_true(space.isinstance(w_2, space.w_str)): + elif space.isinstance_w(w_2, space.w_str): msg = "catching of string exceptions is deprecated" space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.newbool(space.exception_match(w_1, w_2)) @@ -796,7 +796,7 @@ w_result = getattr(self, attr)(w_1, w_2) break else: - raise BytecodeCorruption, "bad COMPARE_OP oparg" + raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) def IMPORT_NAME(self, nameindex, next_instr): diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -61,7 +61,6 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - if w_tb is None or not space.is_true(space.isinstance(w_tb, - space.gettypeobject(PyTraceback.typedef))): + if w_tb is None or not space.isinstance_w(w_tb, space.gettypeobject(PyTraceback.typedef)): raise OperationError(space.w_TypeError, space.wrap(msg)) return w_tb 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 @@ -24,8 +24,12 @@ assert code.signature() == Signature(['x', 'y'], 'hello', None) def d(self, w_boo): pass + + class W_X(W_Root): + pass + code = gateway.BuiltinCode(d, unwrap_spec= ['self', - gateway.W_Root], self_type=gateway.W_Root) + gateway.W_Root], self_type=W_X) assert code.signature() == Signature(['self', 'boo'], None, None) def e(space, w_x, w_y, __args__): pass diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -342,7 +342,7 @@ # a couple of helpers for the Proto classes above, factored out to reduce # the translated code size def check_new_dictionary(space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("setting dictionary to a non-dict")) from pypy.objspace.std import dictmultiobject @@ -552,7 +552,7 @@ self.w_cls = w_cls def typecheck(self, space, w_obj): - if not space.is_true(space.isinstance(w_obj, self.w_cls)): + if not space.isinstance_w(w_obj, self.w_cls): raise operationerrfmt(space.w_TypeError, "descriptor '%s' for '%s'" " objects doesn't apply to '%s' object", diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -114,7 +114,7 @@ else: if w_builtin is space.builtin: # common case return space.builtin - if space.is_true(space.isinstance(w_builtin, space.w_dict)): + if space.isinstance_w(w_builtin, space.w_dict): return module.Module(space, None, w_builtin) if isinstance(w_builtin, module.Module): return w_builtin diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -8,10 +8,12 @@ """ from rpython.rlib import jit + +from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace from pypy.interpreter.error import OperationError from pypy.module.__builtin__.interp_classobj import W_ClassObject from pypy.module.__builtin__.interp_classobj import W_InstanceObject -from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace + def _get_bases(space, w_cls): """Returns 'cls.__bases__'. Returns None if there is @@ -23,7 +25,7 @@ if not e.match(space, space.w_AttributeError): raise # propagate other errors return None - if space.is_true(space.isinstance(w_bases, space.w_tuple)): + if space.isinstance_w(w_bases, space.w_tuple): return w_bases else: return None @@ -47,10 +49,9 @@ @jit.unroll_safe def abstract_isinstance_w(space, w_obj, w_klass_or_tuple, allow_override=False): """Implementation for the full 'isinstance(obj, klass_or_tuple)'.""" - # -- case (anything, tuple) # XXX it might be risky that the JIT sees this - if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)): + if space.isinstance_w(w_klass_or_tuple, space.w_tuple): for w_klass in space.fixedview(w_klass_or_tuple): if abstract_isinstance_w(space, w_obj, w_klass, allow_override): return True @@ -129,8 +130,7 @@ """Implementation for the full 'issubclass(derived, klass_or_tuple)'.""" # -- case (class-like-object, tuple-of-classes) - # XXX it might be risky that the JIT sees this - if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)): + if space.isinstance_w(w_klass_or_tuple, space.w_tuple): for w_klass in space.fixedview(w_klass_or_tuple): if abstract_issubclass_w(space, w_derived, w_klass, allow_override): return True diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -7,6 +7,7 @@ from pypy.interpreter.astcompiler import consts, ast from pypy.interpreter.gateway import unwrap_spec + @unwrap_spec(filename=str, mode=str, flags=int, dont_inherit=int) def compile(space, w_source, filename, mode, flags=0, dont_inherit=0): """Compile the source string (a Python module, statement or expression) @@ -25,10 +26,10 @@ ast_node = None w_ast_type = space.gettypeobject(ast.AST.typedef) str_ = None - if space.is_true(space.isinstance(w_source, w_ast_type)): + if space.isinstance_w(w_source, w_ast_type): ast_node = space.interp_w(ast.mod, w_source) ast_node.sync_app_attrs(space) - elif space.is_true(space.isinstance(w_source, space.w_unicode)): + elif space.isinstance_w(w_source, space.w_unicode): w_utf_8_source = space.call_method(w_source, "encode", space.wrap("utf-8")) str_ = space.str_w(w_utf_8_source) @@ -72,8 +73,8 @@ """ w = space.wrap - if (space.is_true(space.isinstance(w_code, space.w_str)) or - space.is_true(space.isinstance(w_code, space.w_unicode))): + if (space.isinstance_w(w_code, space.w_str) or + space.isinstance_w(w_code, space.w_unicode)): w_code = compile(space, space.call_method(w_code, 'lstrip', space.wrap(' \t')), diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -47,7 +47,8 @@ n = 0 return n - at unwrap_spec(w_step = WrappedDefault(1)) + + at unwrap_spec(w_step=WrappedDefault(1)) def range_int(space, w_x, w_y=None, w_step=None): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to @@ -60,24 +61,24 @@ w_start = w_x w_stop = w_y - if space.is_true(space.isinstance(w_stop, space.w_float)): + if space.isinstance_w(w_stop, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer end argument expected, got float.")) - if space.is_true(space.isinstance(w_start, space.w_float)): + if space.isinstance_w(w_start, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer start argument expected, got float.")) - if space.is_true(space.isinstance(w_step, space.w_float)): + if space.isinstance_w(w_step, space.w_float): raise OperationError(space.w_TypeError, space.wrap("range() integer step argument expected, got float.")) w_start = space.int(w_start) - w_stop = space.int(w_stop) - w_step = space.int(w_step) + w_stop = space.int(w_stop) + w_step = space.int(w_step) try: start = space.int_w(w_start) - stop = space.int_w(w_stop) - step = space.int_w(w_step) + stop = space.int_w(w_stop) + step = space.int_w(w_step) except OperationError, e: if not e.match(space, space.w_OverflowError): raise @@ -107,7 +108,7 @@ start = lo = space.bigint_w(w_start) hi = space.bigint_w(w_stop) - step = st = space.bigint_w(w_step) + step = st = space.bigint_w(w_step) if not step.tobool(): raise OperationError(space.w_ValueError, @@ -201,8 +202,8 @@ @specialize.arg(2) def min_max(space, args, implementation_of): - if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2): + if not jit.we_are_jitted() or len(args.arguments_w) != 1 and \ + jit.loop_unrolling_heuristic(args.arguments_w, len(args.arguments_w)): return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) @@ -329,6 +330,7 @@ next = interp2app(W_ReversedIterator.descr_next), __reduce__ = interp2app(W_ReversedIterator.descr___reduce__), ) +W_ReversedIterator.typedef.acceptable_as_base_class = False # exported through _pickle_support def _make_reversed(space, w_seq, w_remaining): @@ -427,7 +429,7 @@ __reversed__ = interp2app(W_XRange.descr_reversed), __reduce__ = interp2app(W_XRange.descr_reduce), ) - +W_XRange.typedef.acceptable_as_base_class = False class W_XRangeIterator(W_Root): def __init__(self, space, current, remaining, step): @@ -474,6 +476,7 @@ next = interp2app(W_XRangeIterator.descr_next), __reduce__ = interp2app(W_XRangeIterator.descr_reduce), ) +W_XRangeIterator.typedef.acceptable_as_base_class = False class W_XRangeStepOneIterator(W_XRangeIterator): def __init__(self, space, start, stop): diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -25,10 +25,10 @@ # XXX it's not clear that we have to catch the TypeError... def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict): - if not space.is_true(space.isinstance(w_bases, space.w_tuple)): + if not space.isinstance_w(w_bases, space.w_tuple): raise_type_err(space, 'bases', 'tuple', w_bases) - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise_type_err(space, 'bases', 'tuple', w_bases) if not space.is_true(space.contains(w_dict, space.wrap("__doc__"))): @@ -68,27 +68,24 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError( space.w_TypeError, space.wrap("__dict__ must be a dictionary object")) self.w_dict = w_dict def setname(self, space, w_newname): - if not space.is_true(space.isinstance(w_newname, space.w_str)): - raise OperationError( - space.w_TypeError, - space.wrap("__name__ must be a string object")) + if not space.isinstance_w(w_newname, space.w_str): + raise OperationError(space.w_TypeError, + space.wrap("__name__ must be a string object") + ) self.name = space.str_w(w_newname) def setbases(self, space, w_bases): - # XXX in theory, this misses a check against inheritance cycles - # although on pypy we don't get a segfault for infinite - # recursion anyway - if not space.is_true(space.isinstance(w_bases, space.w_tuple)): - raise OperationError( - space.w_TypeError, - space.wrap("__bases__ must be a tuple object")) + if not space.isinstance_w(w_bases, space.w_tuple): + raise OperationError(space.w_TypeError, + space.wrap("__bases__ must be a tuple object") + ) bases_w = space.fixedview(w_bases) for w_base in bases_w: if not isinstance(w_base, W_ClassObject): @@ -194,7 +191,7 @@ if not e.match(space, space.w_AttributeError): raise return "?" - if space.is_true(space.isinstance(w_mod, space.w_str)): + if space.isinstance_w(w_mod, space.w_str): return space.str_w(w_mod) return "?" @@ -464,7 +461,7 @@ def descr_len(self, space): w_meth = self.getattr(space, '__len__') w_result = space.call_function(w_meth) - if space.is_true(space.isinstance(w_result, space.w_int)): + if space.isinstance_w(w_result, space.w_int): if space.is_true(space.lt(w_result, space.wrap(0))): raise OperationError( space.w_ValueError, @@ -532,7 +529,7 @@ if w_func is None: return space.w_True w_result = space.call_function(w_func) - if space.is_true(space.isinstance(w_result, space.w_int)): + if space.isinstance_w(w_result, space.w_int): if space.is_true(space.lt(w_result, space.wrap(0))): raise OperationError( space.w_ValueError, @@ -594,16 +591,16 @@ def descr_hash(self, space): w_func = self.getattr(space, '__hash__', False) if w_func is None: - w_eq = self.getattr(space, '__eq__', False) - w_cmp = self.getattr(space, '__cmp__', False) + w_eq = self.getattr(space, '__eq__', False) + w_cmp = self.getattr(space, '__cmp__', False) if w_eq is not None or w_cmp is not None: raise OperationError(space.w_TypeError, space.wrap("unhashable instance")) else: return space.wrap(compute_identity_hash(self)) w_ret = space.call_function(w_func) - if (not space.is_true(space.isinstance(w_ret, space.w_int)) and - not space.is_true(space.isinstance(w_ret, space.w_long))): + if (not space.isinstance_w(w_ret, space.w_int) and + not space.isinstance_w(w_ret, space.w_long)): raise OperationError( space.w_TypeError, space.wrap("__hash__ must return int or long")) @@ -654,7 +651,6 @@ if space.eq_w(w_x, w_obj): return space.w_True - def descr_pow(self, space, w_other, w_modulo=None): if space.is_none(w_modulo): w_a, w_b = _coerce_helper(space, self, w_other) diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -56,13 +56,13 @@ def nonzero(self): return self.space.wrap(bool(self._cdata)) - def int(self): - w_result = self.ctype.int(self._cdata) + def int(self, space): + w_result = self.ctype.cast_to_int(self._cdata) keepalive_until_here(self) return w_result - def long(self): - w_result = self.int() + def long(self, space): + w_result = self.int(space) space = self.space if space.is_w(space.type(w_result), space.w_int): w_result = space.newlong(space.int_w(w_result)) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -54,7 +54,7 @@ raise operationerrfmt(space.w_TypeError, "cannot cast to '%s'", self.name) - def int(self, cdata): + def cast_to_int(self, cdata): space = self.space raise operationerrfmt(space.w_TypeError, "int() not supported on cdata '%s'", self.name) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -99,7 +99,7 @@ _attrs_ = [] cast_anything = True - def int(self, cdata): + def cast_to_int(self, cdata): return self.space.wrap(ord(cdata[0])) def convert_to_object(self, cdata): @@ -124,7 +124,7 @@ class W_CTypePrimitiveUniChar(W_CTypePrimitiveCharOrUniChar): _attrs_ = [] - def int(self, cdata): + def cast_to_int(self, cdata): unichardata = rffi.cast(rffi.CWCHARP, cdata) return self.space.wrap(ord(unichardata[0])) @@ -168,7 +168,7 @@ self.vmin = r_uint(-1) << (sh - 1) self.vrangemax = (r_uint(1) << sh) - 1 - def int(self, cdata): + def cast_to_int(self, cdata): return self.convert_to_object(cdata) def convert_to_object(self, cdata): @@ -213,7 +213,7 @@ sh = self.size * 8 return (r_uint(1) << sh) - 1 - def int(self, cdata): + def cast_to_int(self, cdata): return self.convert_to_object(cdata) def convert_from_object(self, cdata, w_ob): @@ -288,7 +288,7 @@ keepalive_until_here(w_cdata) return w_cdata - def int(self, cdata): + def cast_to_int(self, cdata): w_value = self.float(cdata) return self.space.int(w_value) diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -3,6 +3,7 @@ from rpython.rlib.rstring import UnicodeBuilder from rpython.rlib.objectmodel import we_are_translated + class CodecState(object): def __init__(self, space): self.codec_search_path = [] @@ -35,11 +36,11 @@ space.wrap(endpos), space.wrap(reason)) w_res = space.call_function(w_errorhandler, w_exc) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2 - or not space.is_true(space.isinstance( + or not space.isinstance_w( space.getitem(w_res, space.wrap(0)), - space.w_unicode))): + space.w_unicode)): if decode: msg = ("decoding error handler must return " "(unicode, int) tuple, not %s") @@ -135,8 +136,7 @@ w_result = space.call_function(w_search, space.wrap(normalized_encoding)) if not space.is_w(w_result, space.w_None): - if not (space.is_true(space.isinstance(w_result, - space.w_tuple)) and + if not (space.isinstance_w(w_result, space.w_tuple) and space.len_w(w_result) == 4): raise OperationError( space.w_TypeError, @@ -322,8 +322,7 @@ w_decoder = space.getitem(lookup_codec(space, encoding), space.wrap(1)) if space.is_true(w_decoder): w_res = space.call_function(w_decoder, w_obj, space.wrap(errors)) - if (not space.is_true(space.isinstance(w_res, space.w_tuple)) - or space.len_w(w_res) != 2): + if (not space.isinstance_w(w_res, space.w_tuple) or space.len_w(w_res) != 2): raise OperationError( space.w_TypeError, space.wrap("encoder must return a tuple (object, integer)")) @@ -493,7 +492,7 @@ self.w_mapping = w_mapping # fast path for all the stuff in the encodings module - if space.is_true(space.isinstance(w_mapping, space.w_tuple)): + if space.isinstance_w(w_mapping, space.w_tuple): self.mapping_w = space.fixedview(w_mapping) else: self.mapping_w = None diff --git a/pypy/module/_locale/interp_locale.py b/pypy/module/_locale/interp_locale.py --- a/pypy/module/_locale/interp_locale.py +++ b/pypy/module/_locale/interp_locale.py @@ -118,11 +118,12 @@ _strcoll = rlocale.external('strcoll', [rffi.CCHARP, rffi.CCHARP], rffi.INT) _wcscoll = rlocale.external('wcscoll', [rffi.CWCHARP, rffi.CWCHARP], rffi.INT) + def strcoll(space, w_s1, w_s2): "string,string -> int. Compares two strings according to the locale." - if space.is_true(space.isinstance(w_s1, space.w_str)) and \ - space.is_true(space.isinstance(w_s2, space.w_str)): + if (space.isinstance_w(w_s1, space.w_str) and + space.isinstance_w(w_s2, space.w_str)): s1, s2 = space.str_w(w_s1), space.str_w(w_s2) s1_c = rffi.str2charp(s1) @@ -133,11 +134,6 @@ rffi.free_charp(s1_c) rffi.free_charp(s2_c) - #if not space.is_true(space.isinstance(w_s1, space.w_unicode)) and \ - # not space.is_true(space.isinstance(w_s2, space.w_unicode)): - # raise OperationError(space.w_ValueError, - # space.wrap("strcoll arguments must be strings")) - s1, s2 = space.unicode_w(w_s1), space.unicode_w(w_s2) s1_c = rffi.unicode2wcharp(s1) diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -28,9 +28,9 @@ if w_n is None: w_n = space.newint(int(time.time())) else: - if space.is_true(space.isinstance(w_n, space.w_int)): + if space.isinstance_w(w_n, space.w_int): w_n = space.abs(w_n) - elif space.is_true(space.isinstance(w_n, space.w_long)): + elif space.isinstance_w(w_n, space.w_long): w_n = space.abs(w_n) else: # XXX not perfectly like CPython @@ -59,7 +59,7 @@ return space.newtuple(state) def setstate(self, space, w_state): - if not space.is_true(space.isinstance(w_state, space.w_tuple)): + if not space.isinstance_w(w_state, space.w_tuple): errstring = space.wrap("state vector must be tuple") raise OperationError(space.w_TypeError, errstring) if space.len_w(w_state) != rrandom.N + 1: @@ -78,7 +78,7 @@ self._rnd.index = space.int_w(w_item) def jumpahead(self, space, w_n): - if space.is_true(space.isinstance(w_n, space.w_long)): + if space.isinstance_w(w_n, space.w_long): num = space.bigint_w(w_n) n = intmask(num.uintmask()) else: diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py --- a/pypy/module/_rawffi/array.py +++ b/pypy/module/_rawffi/array.py @@ -163,7 +163,7 @@ return itemsize * self.length def decodeslice(self, space, w_slice): - if not space.is_true(space.isinstance(w_slice, space.w_slice)): + if not space.isinstance_w(w_slice, space.w_slice): raise OperationError(space.w_TypeError, space.wrap('index must be int or slice')) letter = self.shape.itemcode diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -91,7 +91,7 @@ def unpack_simple_shape(space, w_shape): # 'w_shape' must be either a letter or a tuple (struct, 1). - if space.is_true(space.isinstance(w_shape, space.w_str)): + if space.isinstance_w(w_shape, space.w_str): letter = space.str_w(w_shape) return letter2tp(space, letter) else: @@ -102,7 +102,7 @@ def unpack_shape_with_length(space, w_shape): # Allow 'w_shape' to be a letter or any (shape, number). # The result is always a W_Array. - if space.is_true(space.isinstance(w_shape, space.w_str)): + if space.isinstance_w(w_shape, space.w_str): letter = space.str_w(w_shape) return letter2tp(space, letter) else: @@ -171,7 +171,7 @@ else: ffi_restype = ffi_type_void - if space.is_true(space.isinstance(w_name, space.w_str)): + if space.isinstance_w(w_name, space.w_str): name = space.str_w(w_name) try: @@ -183,8 +183,7 @@ except LibFFIError: raise got_libffi_error(space) - elif (_MS_WINDOWS and - space.is_true(space.isinstance(w_name, space.w_int))): + elif (_MS_WINDOWS and space.isinstance_w(w_name, space.w_int)): ordinal = space.int_w(w_name) try: ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes, @@ -311,12 +310,13 @@ raise NotImplementedError("abstract base class") def unwrap_truncate_int(TP, space, w_arg): - if space.is_true(space.isinstance(w_arg, space.w_int)): + if space.isinstance_w(w_arg, space.w_int): return rffi.cast(TP, space.int_w(w_arg)) else: return rffi.cast(TP, space.bigint_w(w_arg).ulonglongmask()) unwrap_truncate_int._annspecialcase_ = 'specialize:arg(0)' + def unwrap_value(space, push_func, add_arg, argdesc, letter, w_arg): w = space.wrap if letter in TYPEMAP_PTR_LETTERS: diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py --- a/pypy/module/_rawffi/structure.py +++ b/pypy/module/_rawffi/structure.py @@ -32,7 +32,7 @@ name = space.str_w(l_w[0]) except OperationError: raise OperationError(space.w_TypeError, space.wrap( - "structure field name must be string not %s" % + "structure field name must be string not %s" % space.type(l_w[0]).getname(space))) tp = unpack_shape_with_length(space, l_w[1]) @@ -153,7 +153,7 @@ bitsizes = None self.fields = fields self.size = size - self.alignment = alignment + self.alignment = alignment self.ll_positions = pos self.ll_bitsizes = bitsizes self.name_to_index = name_to_index @@ -223,11 +223,10 @@ self.alignment, fieldtypes) return self.ffi_struct.ffistruct - + def __del__(self): if self.ffi_struct: lltype.free(self.ffi_struct, flavor='raw') - @unwrap_spec(union=bool, pack=int) @@ -236,7 +235,7 @@ raise OperationError(space.w_ValueError, space.wrap( "_pack_ must be a non-negative integer")) - if space.is_true(space.isinstance(w_shapeinfo, space.w_tuple)): + if space.isinstance_w(w_shapeinfo, space.w_tuple): w_size, w_alignment = space.fixedview(w_shapeinfo, expected_length=2) S = W_Structure(space, None, space.int_w(w_size), space.int_w(w_alignment), union) @@ -372,7 +371,7 @@ def __del__(self): if self.ll_buffer: self._free() - + W_StructureInstanceAutoFree.typedef = TypeDef( 'StructureInstanceAutoFree', __repr__ = interp2app(W_StructureInstance.descr_repr), diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -255,9 +255,9 @@ # host can be None, string or unicode if space.is_w(w_host, space.w_None): host = None - elif space.is_true(space.isinstance(w_host, space.w_str)): + elif space.isinstance_w(w_host, space.w_str): host = space.str_w(w_host) - elif space.is_true(space.isinstance(w_host, space.w_unicode)): + elif space.isinstance_w(w_host, space.w_unicode): w_shost = space.call_method(w_host, "encode", space.wrap("idna")) host = space.str_w(w_shost) else: @@ -268,9 +268,9 @@ # port can be None, int or string if space.is_w(w_port, space.w_None): port = None - elif space.is_true(space.isinstance(w_port, space.w_int)): + elif space.isinstance_w(w_port, space.w_int): port = str(space.int_w(w_port)) - elif space.is_true(space.isinstance(w_port, space.w_str)): + elif space.isinstance_w(w_port, space.w_str): port = space.str_w(w_port) else: raise OperationError(space.w_TypeError, diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -32,7 +32,19 @@ assert space.unwrap(ip) == socket.gethostbyname_ex(host) def test_gethostbyaddr(): + try: + socket.gethostbyaddr("::1") + except socket.herror: + ipv6 = False + else: + ipv6 = True for host in ["localhost", "127.0.0.1", "::1"]: + if host == "::1" and not ipv6: + from pypy.interpreter.error import OperationError + with py.test.raises(OperationError): + space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + continue ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") assert space.unwrap(ip) == socket.gethostbyaddr(host) @@ -219,7 +231,7 @@ "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info -def test_unknown_addr_as_object(): +def test_unknown_addr_as_object(): from pypy.module._socket.interp_socket import addr_as_object c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw') c_addr.c_sa_data[0] = 'c' @@ -228,7 +240,7 @@ # to be short enough so we have some data, 1 sounds good enough # + sizeof USHORT w_obj = addr_as_object(rsocket.Address(c_addr, 1 + 2), -1, space) - assert space.is_true(space.isinstance(w_obj, space.w_tuple)) + assert space.isinstance_w(w_obj, space.w_tuple) assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15 assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c' diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -101,18 +101,24 @@ """Make a StrMatchContext or a UnicodeMatchContext for searching in the given w_string object.""" space = self.space - if pos < 0: pos = 0 - if endpos < pos: endpos = pos - if space.is_true(space.isinstance(w_string, space.w_unicode)): + if pos < 0: + pos = 0 + if endpos < pos: + endpos = pos + if space.isinstance_w(w_string, space.w_unicode): unicodestr = space.unicode_w(w_string) - if pos > len(unicodestr): pos = len(unicodestr) - if endpos > len(unicodestr): endpos = len(unicodestr) + if pos > len(unicodestr): + pos = len(unicodestr) + if endpos > len(unicodestr): + endpos = len(unicodestr) return rsre_core.UnicodeMatchContext(self.code, unicodestr, pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) - if pos > len(str): pos = len(str) - if endpos > len(str): endpos = len(str) + if pos > len(str): + pos = len(str) + if endpos > len(str): + endpos = len(str) return rsre_core.StrMatchContext(self.code, str, pos, endpos, self.flags) @@ -212,7 +218,7 @@ w_filter = w_ptemplate filter_is_callable = True else: - if space.is_true(space.isinstance(w_ptemplate, space.w_unicode)): + if space.isinstance_w(w_ptemplate, space.w_unicode): filter_as_unicode = space.unicode_w(w_ptemplate) literal = u'\\' not in filter_as_unicode else: @@ -267,7 +273,7 @@ sublist_w.append(slice_w(space, ctx, last_pos, ctx.end, space.w_None)) - if space.is_true(space.isinstance(w_string, space.w_unicode)): + if space.isinstance_w(w_string, space.w_unicode): w_emptystr = space.wrap(u'') else: w_emptystr = space.wrap('') @@ -315,6 +321,7 @@ groups = interp_attrproperty('num_groups', W_SRE_Pattern), pattern = interp_attrproperty_w('w_pattern', W_SRE_Pattern), ) +W_SRE_Pattern.typedef.acceptable_as_base_class = False # ____________________________________________________________ # @@ -381,15 +388,15 @@ return space.call_method(w_re, '_expand', space.wrap(self.srepat), space.wrap(self), w_template) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def start_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[0]) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def end_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[1]) - @unwrap_spec(w_groupnum = WrappedDefault(0)) + @unwrap_spec(w_groupnum=WrappedDefault(0)) def span_w(self, w_groupnum): start, end = self.do_span(w_groupnum) return self.space.newtuple([self.space.wrap(start), @@ -492,7 +499,7 @@ lastindex = GetSetProperty(W_SRE_Match.fget_lastindex), regs = GetSetProperty(W_SRE_Match.fget_regs), ) - +W_SRE_Match.typedef.acceptable_as_base_class = False # ____________________________________________________________ # @@ -548,3 +555,4 @@ search = interp2app(W_SRE_Scanner.search_w), pattern = interp_attrproperty('srepat', W_SRE_Scanner), ) +W_SRE_Scanner.typedef.acceptable_as_base_class = False diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py --- a/pypy/module/_weakref/interp__weakref.py +++ b/pypy/module/_weakref/interp__weakref.py @@ -92,8 +92,7 @@ w_weakreftype = space.gettypeobject(W_Weakref.typedef) for wref in self.other_refs_weak.items(): w_ref = wref() - if (w_ref is not None and - space.is_true(space.isinstance(w_ref, w_weakreftype))): + if (w_ref is not None and space.isinstance_w(w_ref, w_weakreftype)): return w_ref return space.w_None @@ -103,8 +102,8 @@ def __init__(self, space, oldlifeline=None): self.space = space if oldlifeline is not None: - self.cached_weakref = oldlifeline.cached_weakref - self.cached_proxy = oldlifeline.cached_proxy + self.cached_weakref = oldlifeline.cached_weakref + self.cached_proxy = oldlifeline.cached_proxy self.other_refs_weak = oldlifeline.other_refs_weak def __del__(self): diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -108,9 +108,9 @@ raise OperationError(space.w_TypeError, errstring) elif isinstance(w_hkey, W_HKEY): return w_hkey.hkey - elif space.is_true(space.isinstance(w_hkey, space.w_int)): + elif space.isinstance_w(w_hkey, space.w_int): return rffi.cast(rwinreg.HKEY, space.int_w(w_hkey)) - elif space.is_true(space.isinstance(w_hkey, space.w_long)): + elif space.isinstance_w(w_hkey, space.w_long): return rffi.cast(rwinreg.HKEY, space.uint_w(w_hkey)) else: errstring = space.wrap("The object is not a PyHKEY object") @@ -266,7 +266,7 @@ buf = None if typ == rwinreg.REG_DWORD: - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): buflen = rffi.sizeof(rwin32.DWORD) buf1 = lltype.malloc(rffi.CArray(rwin32.DWORD), 1, flavor='raw') buf1[0] = space.uint_w(w_value) @@ -278,7 +278,7 @@ buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') buf[0] = '\0' else: - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): w_value = space.call_method(w_value, 'encode', space.wrap('mbcs')) buf = rffi.str2charp(space.str_w(w_value)) @@ -289,7 +289,7 @@ buflen = 1 buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') buf[0] = '\0' - elif space.is_true(space.isinstance(w_value, space.w_list)): + elif space.isinstance_w(w_value, space.w_list): strings = [] buflen = 0 @@ -298,7 +298,7 @@ while True: try: w_item = space.next(w_iter) - if space.is_true(space.isinstance(w_item, space.w_unicode)): + if space.isinstance_w(w_item, space.w_unicode): w_item = space.call_method(w_item, 'encode', space.wrap('mbcs')) item = space.str_w(w_item) diff --git a/pypy/module/cpyext/complexobject.py b/pypy/module/cpyext/complexobject.py --- a/pypy/module/cpyext/complexobject.py +++ b/pypy/module/cpyext/complexobject.py @@ -12,21 +12,24 @@ Py_complex_fields = (("real", rffi.DOUBLE), ("imag", rffi.DOUBLE)) cpython_struct("Py_complex", Py_complex_fields, Py_complex_t) + @cpython_api([lltype.Float, lltype.Float], PyObject) def PyComplex_FromDoubles(space, real, imag): return space.newcomplex(real, imag) + @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_RealAsDouble(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_complex)): + if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.realval else: return space.float_w(w_obj) + @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_ImagAsDouble(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_complex)): + if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.imagval else: diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -29,7 +29,7 @@ space.setitem(w_globals, space.wrap("__builtins__"), w_builtin) # Get the __import__ function from the builtins - if space.is_true(space.isinstance(w_builtin, space.w_dict)): + if space.isinstance_w(w_builtin, space.w_dict): w_import = space.getitem(w_builtin, space.wrap("__import__")) else: w_import = space.getattr(w_builtin, space.wrap("__import__")) diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py --- a/pypy/module/cpyext/intobject.py +++ b/pypy/module/cpyext/intobject.py @@ -69,6 +69,7 @@ space.wrap("an integer is required, got NULL")) return space.uint_w(space.int(w_obj)) + @cpython_api([PyObject], rffi.ULONG, error=-1) def PyInt_AsUnsignedLongMask(space, w_obj): """Will first attempt to cast the object to a PyIntObject or @@ -76,13 +77,14 @@ unsigned long. This function does not check for overflow. """ w_int = space.int(w_obj) - if space.is_true(space.isinstance(w_int, space.w_int)): + if space.isinstance_w(w_int, space.w_int): num = space.int_w(w_int) return r_uint(num) else: num = space.bigint_w(w_int) return num.uintmask() + @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyInt_AsUnsignedLongLongMask(space, w_obj): """Will first attempt to cast the object to a PyIntObject or @@ -90,7 +92,7 @@ unsigned long long, without checking for overflow. """ w_int = space.int(w_obj) - if space.is_true(space.isinstance(w_int, space.w_int)): + if space.isinstance_w(w_int, space.w_int): num = space.int_w(w_int) return r_ulonglong(num) else: diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -23,6 +23,13 @@ """ return space.newlong(val) + at cpython_api([rffi.SIZE_T], PyObject) +def PyLong_FromSize_t(space, val): + """Return a new PyLongObject object from a C size_t, or NULL on + failure. + """ + return space.wrap(val) + @cpython_api([rffi.LONGLONG], PyObject) def PyLong_FromLongLong(space, val): """Return a new PyLongObject object from a C long long, or NULL diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py --- a/pypy/module/cpyext/pyerrors.py +++ b/pypy/module/cpyext/pyerrors.py @@ -182,7 +182,7 @@ exc is a class object, this also returns true when given is an instance of a subclass. If exc is a tuple, all exceptions in the tuple (and recursively in subtuples) are searched for a match.""" - if (space.is_true(space.isinstance(w_given, space.w_BaseException)) or + if (space.isinstance_w(w_given, space.w_BaseException) or space.is_oldstyle_instance(w_given)): w_given_type = space.exception_getclass(w_given) else: diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1395,13 +1395,6 @@ """ raise NotImplementedError - at cpython_api([rffi.SIZE_T], PyObject) -def PyLong_FromSize_t(space, v): - """Return a new PyLongObject object from a C size_t, or - NULL on failure. - """ - raise NotImplementedError - @cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.INT_real], PyObject) def PyLong_FromUnicode(space, u, length, base): """Convert a sequence of Unicode digits to a Python long integer value. The first diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -146,6 +146,15 @@ assert module.from_longlong() == -1 assert module.from_unsignedlonglong() == (1<<64) - 1 + def test_from_size_t(self): + module = self.import_extension('foo', [ + ("from_unsignedlong", "METH_NOARGS", + """ + return PyLong_FromSize_t((size_t)-1); + """)]) + import sys + assert module.from_unsignedlong() == 2 * sys.maxint + 1 + def test_fromstring(self): module = self.import_extension('foo', [ ("from_string", "METH_NOARGS", diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -304,7 +304,7 @@ api.PyUnicode_Decode(b_text, 4, b_encoding, None)) == u'caf\xe9' w_text = api.PyUnicode_FromEncodedObject(space.wrap("test"), b_encoding, None) - assert space.is_true(space.isinstance(w_text, space.w_unicode)) + assert space.isinstance_w(w_text, space.w_unicode) assert space.unwrap(w_text) == "test" assert api.PyUnicode_FromEncodedObject(space.wrap(u"test"), b_encoding, None) is None diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -248,7 +248,7 @@ Py_DecRef(space, base_object_pyo) def check_descr(space, w_self, w_type): - if not space.is_true(space.isinstance(w_self, w_type)): + if not space.isinstance_w(w_self, w_type): raise DescrMismatch() class GettersAndSetters: @@ -489,7 +489,7 @@ pto.c_tp_as_sequence = heaptype.c_as_sequence pto.c_tp_as_mapping = heaptype.c_as_mapping pto.c_tp_as_buffer = heaptype.c_as_buffer - + return rffi.cast(PyObject, heaptype) def type_attach(space, py_obj, w_type): @@ -734,4 +734,4 @@ return if w_obj.is_cpytype(): w_obj.mutated(None) - + diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -1,6 +1,5 @@ from pypy.interpreter.error import OperationError from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rtyper.lltypesystem import llmemory from pypy.module.unicodedata import unicodedb from pypy.module.cpyext.api import ( CANNOT_FAIL, Py_ssize_t, build_type_checkers, cpython_api, @@ -388,7 +387,7 @@ # - unicode is disallowed # - raise TypeError for non-string types - if space.is_true(space.isinstance(w_obj, space.w_unicode)): + if space.isinstance_w(w_obj, space.w_unicode): w_meth = None else: try: diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -156,7 +156,7 @@ return self.w_dict def setdict(self, space, w_dict): - if not space.is_true(space.isinstance(w_dict, space.w_dict)): + if not space.isinstance_w(w_dict, space.w_dict): raise OperationError(space.w_TypeError, space.wrap("setting exceptions's dictionary to a non-dict")) self.w_dict = w_dict diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -182,7 +182,7 @@ def _log_any(space, w_x, base): # base is supposed to be positive or 0.0, which means we use e try: - if space.is_true(space.isinstance(w_x, space.w_long)): + if space.isinstance_w(w_x, space.w_long): # special case to support log(extremely-large-long) num = space.bigint_w(w_x) result = num.log(base) diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py --- a/pypy/module/operator/interp_operator.py +++ b/pypy/module/operator/interp_operator.py @@ -233,8 +233,8 @@ raise OperationError(space.w_TypeError, space.wrap("non-sequence object can't be repeated")) - if not (space.is_true(space.isinstance(w_obj2, space.w_int)) or \ - space.is_true(space.isinstance(w_obj2, space.w_long))): + if not (space.isinstance_w(w_obj2, space.w_int) or + space.isinstance_w(w_obj2, space.w_long)): # second arg has to be int/long raise OperationError(space.w_TypeError, space.wrap('an integer is required')) diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -82,7 +82,7 @@ # perform binds if w_vars is None: pass - elif space.is_true(space.isinstance(w_vars, space.w_dict)): + elif space.isinstance_w(w_vars, space.w_dict): self._setBindVariablesByName(space, w_vars, 1, 0, 0) else: self._setBindVariablesByPos(space, w_vars, 1, 0, 0) @@ -114,7 +114,7 @@ def executemany(self, space, w_stmt, w_list_of_args): if space.is_w(w_stmt, space.w_None): w_stmt = None - if not space.is_true(space.isinstance(w_list_of_args, space.w_list)): + if not space.isinstance_w(w_list_of_args, space.w_list): raise OperationError( space.w_TypeError, space.wrap("list expected")) @@ -137,7 +137,7 @@ for i in range(numrows): w_arguments = args_w[i] deferred = i < numrows - 1 - if space.is_true(space.isinstance(w_arguments, space.w_dict)): + if space.isinstance_w(w_arguments, space.w_dict): self._setBindVariablesByName( space, w_arguments, numrows, i, deferred) else: @@ -317,7 +317,7 @@ if e.match(space, get(space).w_DatabaseError): attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') try: - status = roci.OCIAttrGet( + roci.OCIAttrGet( self.handle, roci.OCI_HTYPE_STMT, rffi.cast(roci.dvoidp, attrptr), lltype.nullptr(roci.Ptr(roci.ub4).TO), @@ -603,7 +603,7 @@ def _setBindVariableHelper(self, space, w_value, origVar, numElements, arrayPos, defer): - valueIsVariable = space.is_true(space.isinstance(w_value, get(space).w_Variable)) + valueIsVariable = space.isinstance_w(w_value, get(space).w_Variable) newVar = None # handle case where variable is already bound @@ -859,8 +859,6 @@ def _createRow(self, space): items_w = [] - numItems = len(self.fetchVariables) - # acquire the value for each item for var in self.fetchVariables: assert isinstance(var, interp_variable.W_Variable) @@ -981,9 +979,9 @@ size = varType.size # determine the number of elements to create - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): numElements = space.len_w(w_value) - elif space.is_true(space.isinstance(w_value, space.w_int)): + elif space.isinstance_w(w_value, space.w_int): numElements = space.int_w(w_value) else: raise OperationError( @@ -995,7 +993,7 @@ var.makeArray(space) # set the value, if applicable - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): var.setArrayValue(space, w_value) return var diff --git a/pypy/module/oracle/interp_variable.py b/pypy/module/oracle/interp_variable.py --- a/pypy/module/oracle/interp_variable.py +++ b/pypy/module/oracle/interp_variable.py @@ -425,7 +425,7 @@ def setArrayValue(self, space, w_value): # ensure we have an array to set - if not space.is_true(space.isinstance(w_value, space.w_list)): + if not space.isinstance_w(w_value, space.w_list): raise OperationError( space.w_TypeError, space.wrap("expecting array data")) @@ -514,7 +514,7 @@ wantBytes = self.charsetForm == roci.SQLCS_IMPLICIT if wantBytes: - if space.is_true(space.isinstance(w_value, space.w_str)): + if space.isinstance_w(w_value, space.w_str): buf = config.StringBuffer() buf.fill(space, w_value) size = buf.size @@ -523,7 +523,7 @@ space.w_TypeError, space.wrap("expecting string or buffer data")) else: - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): buf = config.StringBuffer() buf.fill_with_unicode(space, w_value) size = buf.size @@ -760,7 +760,7 @@ rffi.cast(roci.Ptr(roci.OCINumber), self.data), pos) - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): integerValuePtr = lltype.malloc(roci.Ptr(lltype.Signed).TO, 1, flavor='raw') try: @@ -776,7 +776,7 @@ finally: lltype.free(integerValuePtr, flavor='raw') return - elif space.is_true(space.isinstance(w_value, space.w_long)): + elif space.isinstance_w(w_value, space.w_long): text_buf = config.StringBuffer() text_buf.fill(space, space.str(w_value)) format_buf = config.StringBuffer() @@ -793,7 +793,7 @@ status, "NumberVar_SetValue(): from long") return # XXX The bool case was already processed above - elif space.is_true(space.isinstance(w_value, space.w_float)): + elif space.isinstance_w(w_value, space.w_float): doubleValuePtr = lltype.malloc(roci.Ptr(lltype.Float).TO, 1, flavor='raw') try: @@ -808,7 +808,7 @@ finally: lltype.free(doubleValuePtr, flavor='raw') return - elif space.is_true(space.isinstance(w_value, get(space).w_DecimalType)): + elif space.isinstance_w(w_value, get(space).w_DecimalType): w_text, w_format = transform.DecimalToFormatAndText(self.environment, w_value) text_buf = config.StringBuffer() text_buf.fill(space, w_text) @@ -856,14 +856,14 @@ dataptr = rffi.ptradd( rffi.cast(roci.Ptr(roci.OCIDate), self.data), pos) - if space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if space.isinstance_w(w_value, get(space).w_DateTimeType): year = space.int_w(space.getattr(w_value, space.wrap('year'))) month = space.int_w(space.getattr(w_value, space.wrap('month'))) day = space.int_w(space.getattr(w_value, space.wrap('day'))) hour = space.int_w(space.getattr(w_value, space.wrap('hour'))) minute = space.int_w(space.getattr(w_value, space.wrap('minute'))) second = space.int_w(space.getattr(w_value, space.wrap('second'))) - elif space.is_true(space.isinstance(w_value, get(space).w_DateType)): + elif space.isinstance_w(w_value, get(space).w_DateType): year = space.int_w(space.getattr(w_value, space.wrap('year'))) month = space.int_w(space.getattr(w_value, space.wrap('month'))) day = space.int_w(space.getattr(w_value, space.wrap('day'))) @@ -933,7 +933,7 @@ def setValueProc(self, space, pos, w_value): # make sure a timestamp is being bound - if not space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if not space.isinstance_w(w_value, get(space).w_DateTimeType): raise OperationError( space.w_TypeError, space.wrap("expecting timestamp data")) @@ -985,8 +985,7 @@ self.environment, self.getDataptr(pos)) def setValueProc(self, space, pos, w_value): - if not space.is_true(space.isinstance(w_value, - get(space).w_TimedeltaType)): + if not space.isinstance_w(w_value, get(space).w_TimedeltaType): raise OperationError( space.w_TypeError, space.wrap("expecting timedelta data")) @@ -1208,7 +1207,7 @@ def setValueProc(self, space, pos, w_value): from pypy.module.oracle import interp_cursor w_CursorType = space.gettypeobject(interp_cursor.W_Cursor.typedef) - if not space.is_true(space.isinstance(w_value, w_CursorType)): + if not space.isinstance_w(w_value, w_CursorType): raise OperationError( space.w_TypeError, space.wrap("expecting cursor")) @@ -1414,7 +1413,7 @@ from pypy.objspace.std.typeobject import W_TypeObject moduledict = get(space) - if not space.is_true(space.isinstance(w_type, space.w_type)): + if not space.isinstance_w(w_type, space.w_type): raise OperationError( space.w_TypeError, space.wrap("Variable_TypeByPythonType(): type expected")) @@ -1435,49 +1434,49 @@ if space.is_w(w_value, space.w_None): return VT_String, 1, numElements - if space.is_true(space.isinstance(w_value, space.w_str)): + if space.isinstance_w(w_value, space.w_str): size = space.len_w(w_value) if size > config.MAX_STRING_CHARS: return VT_LongString, size, numElements else: return VT_String, size, numElements - if space.is_true(space.isinstance(w_value, space.w_unicode)): + if space.isinstance_w(w_value, space.w_unicode): size = space.len_w(w_value) return VT_NationalCharString, size, numElements - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.isinstance_w(w_value, space.w_int): return VT_Integer, 0, numElements - if space.is_true(space.isinstance(w_value, space.w_long)): + if space.isinstance_w(w_value, space.w_long): return VT_LongInteger, 0, numElements - if space.is_true(space.isinstance(w_value, space.w_float)): + if space.isinstance_w(w_value, space.w_float): return VT_Float, 0, numElements # XXX cxBinary # XXX bool - if space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)): + if space.isinstance_w(w_value, get(space).w_DateTimeType): return VT_DateTime, 0, numElements - if space.is_true(space.isinstance(w_value, get(space).w_DateType)): + if space.isinstance_w(w_value, get(space).w_DateType): return VT_Date, 0, numElements # XXX Delta from pypy.module.oracle import interp_cursor - if space.is_true(space.isinstance( # XXX is there an easier way? + if space.isinstance_w( # XXX is there an easier way? w_value, - space.gettypeobject(interp_cursor.W_Cursor.typedef))): + space.gettypeobject(interp_cursor.W_Cursor.typedef)): return VT_Cursor, 0, numElements - if space.is_true(space.isinstance(w_value, get(space).w_DecimalType)): + if space.isinstance_w(w_value, get(space).w_DecimalType): return VT_NumberAsString, 0, numElements # handle arrays - if space.is_true(space.isinstance(w_value, space.w_list)): + if space.isinstance_w(w_value, space.w_list): elements_w = space.listview(w_value) for w_element in elements_w: if not space.is_w(w_element, space.w_None): @@ -1497,8 +1496,7 @@ space.wrap(cursor), w_value, space.wrap(numElements)) - if not space.is_true(space.isinstance(w_var, - get(space).w_Variable)): + if not space.isinstance_w(w_var, get(space).w_Variable): raise OperationError( space.w_TypeError, space.wrap("expecting variable from input type handler")) @@ -1519,7 +1517,7 @@ if space.is_w(var, space.w_None): varType, size, numElements = typeByValue(space, w_value, numElements) var = varType(cursor, numElements, size) From noreply at buildbot.pypy.org Sat Mar 30 07:47:22 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Sat, 30 Mar 2013 07:47:22 +0100 (CET) Subject: [pypy-commit] pypy improve-docs-2: Fix typo and inaccuracy in bpnn example's comments. Message-ID: <20130330064722.920BD1C0183@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: improve-docs-2 Changeset: r62886:6e161d4684b2 Date: 2013-03-30 08:38 +0200 http://bitbucket.org/pypy/pypy/changeset/6e161d4684b2/ Log: Fix typo and inaccuracy in bpnn example's comments. diff --git a/rpython/translator/goal/bpnn.py b/rpython/translator/goal/bpnn.py --- a/rpython/translator/goal/bpnn.py +++ b/rpython/translator/goal/bpnn.py @@ -60,7 +60,7 @@ # create weights self.wi = makeMatrix(self.ni, self.nh) self.wo = makeMatrix(self.nh, self.no) - # set them to random vaules + # set them to random values for i in range(self.ni): for j in range(self.nh): self.wi[i][j] = rand(-2.0, 2.0) @@ -177,7 +177,7 @@ [[1,1], [0]] ] - # create a network with two input, two hidden, and two output nodes + # create a network with two input, three hidden, and one output nodes n = NN(2, 3, 1) # train it with some patterns n.train(pat, 2000) From noreply at buildbot.pypy.org Sat Mar 30 07:47:23 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Sat, 30 Mar 2013 07:47:23 +0100 (CET) Subject: [pypy-commit] pypy improve-docs-2: Remove EOL whitespace in getting started dev docs. Message-ID: <20130330064723.D60BB1C0183@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: improve-docs-2 Changeset: r62887:e3b7af11981b Date: 2013-03-30 08:39 +0200 http://bitbucket.org/pypy/pypy/changeset/e3b7af11981b/ Log: Remove EOL whitespace in getting started dev docs. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -16,7 +16,7 @@ .. _`try out the translator`: Trying out the translator -------------------------- +------------------------- The translator is a tool based on the PyPy interpreter which can translate sufficiently static RPython programs into low-level code (in particular it can @@ -37,7 +37,7 @@ >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() - + After that, the graph viewer pops up, that lets you interactively inspect the flow graph. To move around, click on something that you want to inspect. To get help about how to use it, press 'H'. To close it again, press 'Q'. @@ -92,10 +92,10 @@ The object returned by ``compile_cli`` or ``compile_jvm`` is a wrapper around the real executable: the parameters are passed as command line arguments, and -the returned value is read from the standard output. +the returned value is read from the standard output. Once you have compiled the snippet, you can also try to launch the -executable directly from the shell. You will find the +executable directly from the shell. You will find the executable in one of the ``/tmp/usession-*`` directories:: # For CLI: From noreply at buildbot.pypy.org Sat Mar 30 07:47:25 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Sat, 30 Mar 2013 07:47:25 +0100 (CET) Subject: [pypy-commit] pypy improve-docs-2: Clean up first paragraphs. Message-ID: <20130330064725.4107C1C0183@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: improve-docs-2 Changeset: r62888:3f9b479df9fa Date: 2013-03-27 10:41 +0200 http://bitbucket.org/pypy/pypy/changeset/3f9b479df9fa/ Log: Clean up first paragraphs. diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -2,22 +2,25 @@ Welcome to PyPy =============== -The PyPy project aims at producing a flexible and fast Python_ -implementation. For the general idea what is pypy, consult the `pypy website`_. -This page documents entry points into the development of the PyPy project. -If you just want to use it, consult the `download`_ page on the PyPy website -and `getting started with pypy`_ document. +The PyPy project aims to produce a flexible and fast Python_ +implementation. This page documents the development of the PyPy +project itself. If you don't know what PyPy is, consult the `PyPy +website`_. If you just want to use PyPy, consult the `download`_ page +and the `getting started with pypy`_ documents. If you want to help +develop PyPy -- keep reading! PyPy is written in a language called `RPython`_, which is suitable for -writing dynamic language interpreters (and not much else). -`Starting with RPython`_ should provide a reasonable overview if you want -to learn the language. +writing dynamic language interpreters (and not much else). RPython is +a subset of Python and is itself written in Python. If you'd like to +learn more about RPython, `Starting with RPython`_ should provide a +reasonable overview. -**If you want to contribute to PyPy**, please read `how to contribute`_ first. -PyPy development style is vastly different than most other software projects -and it usually comes as surprise to most people. What is **not** necessary is -having academic knowledge from university about writing compilers. Most of -it does not apply to PyPy at all. +**If you would like to contribute to PyPy**, please read `how to +contribute`_ first. PyPy's development style is somewhat different to +that of many other software projects and it often surprises +newcomers. What is **not** necessary is an academic background from +university in writing compilers -- much of it does not apply to PyPy +any way. All of the documentation and source code is available under the MIT license, unless otherwise specified. Consult `LICENSE`_ @@ -27,7 +30,7 @@ .. _`RPython`: coding-guide.html#RPython .. _`Starting with RPython`: getting-started-dev.html .. _`how to contribute`: how-to-contribute.html -.. _`pypy website`: http://pypy.org +.. _`PyPy website`: http://pypy.org Index of various topics: ======================== From noreply at buildbot.pypy.org Sat Mar 30 13:30:15 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sat, 30 Mar 2013 13:30:15 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_compile_asmlen for armv6 too Message-ID: <20130330123015.4B9A81C06C3@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62890:c9fdb143f15e Date: 2013-03-30 13:26 +0100 http://bitbucket.org/pypy/pypy/changeset/c9fdb143f15e/ Log: fix test_compile_asmlen for armv6 too diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -27,6 +27,19 @@ bridge_loop_instructions = ['ldr', 'mov', 'nop', 'cmp', 'bge', 'push', 'mov', 'mov', 'push', 'mov', 'mov', 'blx', 'mov', 'mov', 'bx'] + if CPU.backend_name.startswith('armv7'): + bridge_loop_instructions = ['ldr', 'mov', 'nop', 'cmp', 'bge', + 'push', 'mov', 'mov', 'push', 'mov', 'mov', + 'blx', 'mov', 'mov', 'bx'] + else: + bridge_loop_instructions = ['ldr', 'mov', 'nop', 'nop', 'nop', 'cmp', 'bge', + 'push', 'ldr', 'mov', + '', # inline constant + 'push', 'ldr', 'mov', + 'ldrsblt', #inline constant (decodes as instruction) + 'blx', 'ldr', 'mov', + '', # inline constant + 'bx'] def get_cpu(self): cpu = CPU(rtyper=None, stats=FakeStats()) From noreply at buildbot.pypy.org Sat Mar 30 13:30:13 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sat, 30 Mar 2013 13:30:13 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_compile_asmlen on armv7 Message-ID: <20130330123013.EA0AE1C0619@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62889:91509100b64e Date: 2013-03-30 13:15 +0100 http://bitbucket.org/pypy/pypy/changeset/91509100b64e/ Log: fix test_compile_asmlen on armv7 diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -250,7 +250,7 @@ def currpos(self): raise NotImplementedError - max_size_of_gen_load_int = 2 * WORD + max_size_of_gen_load_int = 2 def gen_load_int(self, r, value, cond=cond.AL): """r is the register number, value is the value to be loaded to the register""" @@ -275,7 +275,7 @@ self.MOV_rr(reg.pc.value, reg.pc.value) self.write32(value) - max_size_of_gen_load_int = 4 * WORD + max_size_of_gen_load_int = 4 ofs_shift = zip(range(8, 25, 8), range(12, 0, -4)) def _load_by_shifting(self, r, value, c=cond.AL): # to be sure it is only called for the correct cases diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -53,8 +53,8 @@ 'x86_32': 'i386', 'x86_64': 'x86-64', 'i386': 'i386', - 'arm': 'arm', - 'arm_32': 'arm', + 'armv6_32': 'arm', + 'armv7_32': 'arm', } cmd = find_objdump() objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' From noreply at buildbot.pypy.org Sat Mar 30 16:29:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 16:29:06 +0100 (CET) Subject: [pypy-commit] pypy default: Don't import the stacklet C code if we're not translating with Message-ID: <20130330152906.94EAB1C0014@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62891:5b34c642de6f Date: 2013-03-30 16:28 +0100 http://bitbucket.org/pypy/pypy/changeset/5b34c642de6f/ Log: Don't import the stacklet C code if we're not translating with "continuation". diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -468,6 +468,7 @@ # thread support if translator.config.translation.continuation: + root_walker.stacklet_support = True root_walker.need_stacklet_support(self, getfn) if translator.config.translation.thread: root_walker.need_thread_support(self, getfn) @@ -1275,6 +1276,7 @@ def __init__(self, gctransformer): self.gcdata = gctransformer.gcdata self.gc = self.gcdata.gc + self.stacklet_support = False def _freeze_(self): return True diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -113,7 +113,7 @@ # gc_thread_run and gc_thread_die. See docstrings below. shadow_stack_pool = self.shadow_stack_pool - SHADOWSTACKREF = get_shadowstackref(gctransformer) + SHADOWSTACKREF = get_shadowstackref(self, gctransformer) # this is a dict {tid: SHADOWSTACKREF}, where the tid for the # current thread may be missing so far @@ -217,7 +217,7 @@ def need_stacklet_support(self, gctransformer, getfn): shadow_stack_pool = self.shadow_stack_pool - SHADOWSTACKREF = get_shadowstackref(gctransformer) + SHADOWSTACKREF = get_shadowstackref(self, gctransformer) def gc_shadowstackref_new(): ssref = shadow_stack_pool.allocate(SHADOWSTACKREF) @@ -366,7 +366,7 @@ return result -def get_shadowstackref(gctransformer): +def get_shadowstackref(root_walker, gctransformer): if hasattr(gctransformer, '_SHADOWSTACKREF'): return gctransformer._SHADOWSTACKREF @@ -394,16 +394,20 @@ customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) def shadowstack_destructor(shadowstackref): - from rpython.rlib import _rffi_stacklet as _c - h = shadowstackref.context - h = llmemory.cast_adr_to_ptr(h, _c.handle) + if root_walker.stacklet_support: + from rpython.rlib import _rffi_stacklet as _c + h = shadowstackref.context + h = llmemory.cast_adr_to_ptr(h, _c.handle) + shadowstackref.context = llmemory.NULL + # base = shadowstackref.base shadowstackref.base = llmemory.NULL shadowstackref.top = llmemory.NULL - shadowstackref.context = llmemory.NULL llmemory.raw_free(base) - if h: - _c.destroy(h) + # + if root_walker.stacklet_support: + if h: + _c.destroy(h) destrptr = gctransformer.annotate_helper(shadowstack_destructor, [SHADOWSTACKREFPTR], lltype.Void) From noreply at buildbot.pypy.org Sat Mar 30 16:59:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 16:59:19 +0100 (CET) Subject: [pypy-commit] cffi default: Fix for PPC: check that "long double" has more precision than "double" Message-ID: <20130330155919.B18791C0014@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1207:e67cd88ae64b Date: 2013-03-30 16:59 +0100 http://bitbucket.org/cffi/cffi/changeset/e67cd88ae64b/ Log: Fix for PPC: check that "long double" has more precision than "double" if the type is larger, without assuming that it can hold bigger values. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4785,11 +4785,12 @@ return ptr->a1 + (int)ptr->a2; } -static long double _testfunc19(long double x) +static long double _testfunc19(long double x, int count) { int i; - for (i=0; i<28; i++) - x += x; + for (i=0; i sizeof(new_primitive_type("double")): - if not py_py: - assert repr(start).startswith("") - # - c = newp(BLongDoubleArray, [start]) - x = c[0] - if not py_py: - assert repr(x).endswith("E+902>") - assert float(x) == float("inf") + assert float(lstart) != start + assert repr(lstart).startswith(" Author: Armin Rigo Branch: Changeset: r1208:c5e85201f3ce Date: 2013-03-30 09:48 -0700 http://bitbucket.org/cffi/cffi/changeset/c5e85201f3ce/ Log: Fix(?) an issue that only showed up on PPC64 so far, about char- returning C functions. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4932,11 +4932,6 @@ _cffi_to_c_UNSIGNED_FN(unsigned int, 32) _cffi_to_c_UNSIGNED_FN(unsigned PY_LONG_LONG, 64) -static char _cffi_to_c_char(PyObject *obj) -{ - return (char)_convert_to_char(obj); -} - static PyObject *_cffi_from_c_pointer(char *ptr, CTypeDescrObject *ct) { return convert_to_object((char *)&ptr, ct); @@ -5024,7 +5019,7 @@ _cffi_to_c_u32, _cffi_to_c_i64, _cffi_to_c_u64, - _cffi_to_c_char, + _convert_to_char, _cffi_from_c_pointer, _cffi_to_c_pointer, _cffi_get_struct_layout, diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py --- a/cffi/vengine_cpy.py +++ b/cffi/vengine_cpy.py @@ -778,7 +778,7 @@ #define _cffi_to_c_u64 \ ((unsigned long long(*)(PyObject *))_cffi_exports[8]) #define _cffi_to_c_char \ - ((char(*)(PyObject *))_cffi_exports[9]) + ((int(*)(PyObject *))_cffi_exports[9]) #define _cffi_from_c_pointer \ ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[10]) #define _cffi_to_c_pointer \ From noreply at buildbot.pypy.org Sat Mar 30 17:55:02 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 17:55:02 +0100 (CET) Subject: [pypy-commit] cffi default: Be more lenient and skip this test in non-x86 cases Message-ID: <20130330165502.91D4C1C0183@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1209:be070b8687d3 Date: 2013-03-30 17:53 +0100 http://bitbucket.org/cffi/cffi/changeset/be070b8687d3/ Log: Be more lenient and skip this test in non-x86 cases diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1235,7 +1235,8 @@ f0 = lib.square(0.0) f2 = lib.square(f) f3 = lib.square(f * 2.0) - assert repr(f2) != repr(f3) # two non-null 'long doubles' + if repr(f2) == repr(f3): + py.test.skip("long double doesn't have enough precision") assert float(f0) == float(f2) == float(f3) == 0.0 # too tiny for 'double' assert int(ffi.cast("_Bool", f2)) == 1 assert int(ffi.cast("_Bool", f3)) == 1 From noreply at buildbot.pypy.org Sat Mar 30 18:09:42 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 18:09:42 +0100 (CET) Subject: [pypy-commit] cffi default: Ignore mismatches between two different primitive types of the same size, Message-ID: <20130330170942.A92BC1C0014@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1210:3c66c29d2e80 Date: 2013-03-30 19:08 +0200 http://bitbucket.org/cffi/cffi/changeset/3c66c29d2e80/ Log: Ignore mismatches between two different primitive types of the same size, like on some platforms "double" and "long double". diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -425,13 +425,18 @@ def _check_field_match(typename, real, expect_mismatch): ffi = FFI() - if expect_mismatch == 'by_size': + testing_by_size = (expect_mismatch == 'by_size') + if testing_by_size: expect_mismatch = ffi.sizeof(typename) != ffi.sizeof(real) ffi.cdef("struct foo_s { %s x; ...; };" % typename) try: ffi.verify("struct foo_s { %s x; };" % real) except VerificationError: if not expect_mismatch: + if testing_by_size: + print("ignoring mismatch between %s* and %s* even though " + "they have the same size" % (typename, real)) + return raise AssertionError("unexpected mismatch: %s should be accepted " "as equal to %s" % (typename, real)) else: From noreply at buildbot.pypy.org Sat Mar 30 18:29:09 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 18:29:09 +0100 (CET) Subject: [pypy-commit] cffi default: Only ignore mismatches between *different* types; using twice the same type must be tested to work. Message-ID: <20130330172909.E9C881C0619@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1211:1f49770a97b2 Date: 2013-03-30 18:28 +0100 http://bitbucket.org/cffi/cffi/changeset/1f49770a97b2/ Log: Only ignore mismatches between *different* types; using twice the same type must be tested to work. diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -433,7 +433,7 @@ ffi.verify("struct foo_s { %s x; };" % real) except VerificationError: if not expect_mismatch: - if testing_by_size: + if testing_by_size and typename != real: print("ignoring mismatch between %s* and %s* even though " "they have the same size" % (typename, real)) return From noreply at buildbot.pypy.org Sat Mar 30 18:36:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 18:36:39 +0100 (CET) Subject: [pypy-commit] cffi default: PyPy compatibility Message-ID: <20130330173639.7B6E01C0619@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1212:231fd7f12dbb Date: 2013-03-30 18:36 +0100 http://bitbucket.org/cffi/cffi/changeset/231fd7f12dbb/ Log: PyPy compatibility diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2313,15 +2313,16 @@ start = 4 * start - start * start lstart = f(lstart, 1) lother = f(1.5, 107) - assert float(lstart) == float(lother) - assert repr(lstart) == repr(lother) - if sizeof(BLongDouble) > sizeof(new_primitive_type("double")): - assert float(lstart) != start - assert repr(lstart).startswith(" sizeof(new_primitive_type("double")): + assert float(lstart) != start + assert repr(lstart).startswith(" Author: Armin Rigo Branch: Changeset: r62892:1dee64abca8b Date: 2013-03-30 18:37 +0100 http://bitbucket.org/pypy/pypy/changeset/1dee64abca8b/ Log: Update to cffi/231fd7f12dbb. 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 @@ -2277,6 +2277,7 @@ def test_longdouble(): py_py = 'PY_DOT_PY' in globals() + BInt = new_primitive_type("int") BLongDouble = new_primitive_type("long double") BLongDoublePtr = new_pointer_type(BLongDouble) BLongDoubleArray = new_array_type(BLongDoublePtr, None) @@ -2294,21 +2295,23 @@ assert float(x) == 1.23 assert int(x) == 1 # - BFunc19 = new_function_type((BLongDouble,), BLongDouble) + BFunc19 = new_function_type((BLongDouble, BInt), BLongDouble) f = cast(BFunc19, _testfunc(19)) - start = 8 + start = lstart = 1.5 for i in range(107): - start = f(start) - if sizeof(BLongDouble) > sizeof(new_primitive_type("double")): - if not py_py: - assert repr(start).startswith("") - # - c = newp(BLongDoubleArray, [start]) - x = c[0] - if not py_py: - assert repr(x).endswith("E+902>") - assert float(x) == float("inf") + start = 4 * start - start * start + lstart = f(lstart, 1) + lother = f(1.5, 107) + if not py_py: + assert float(lstart) == float(lother) + assert repr(lstart) == repr(lother) + if sizeof(BLongDouble) > sizeof(new_primitive_type("double")): + assert float(lstart) != start + assert repr(lstart).startswith("a1 + (int)ptr->a2; } -static long double _testfunc19(long double x) +static long double _testfunc19(long double x, int count) { int i; - for (i=0; i<28; i++) - x += x; + for (i=0; i Author: Armin Rigo Branch: Changeset: r1213:70f108bb6786 Date: 2013-03-30 19:04 +0100 http://bitbucket.org/cffi/cffi/changeset/70f108bb6786/ Log: Always test the mention of cffi-$VERSION.tar.gz in the docs, even if it does not exist so far, because readthedocs displays the doc of the latest release now by default. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -90,13 +90,13 @@ Download and Installation: -* http://pypi.python.org/packages/source/c/cffi/cffi-0.5.tar.gz +* http://pypi.python.org/packages/source/c/cffi/cffi-0.6.tar.gz - Or grab the most current version by following the instructions below. - - MD5: b163c11f68cad4371e8caeb91d81743f + - MD5: ... - - SHA: d201e114d701eafbf458ebde569acbcc5225eeff + - SHA: ... * Or get it from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` diff --git a/testing/test_version.py b/testing/test_version.py --- a/testing/test_version.py +++ b/testing/test_version.py @@ -25,8 +25,7 @@ v = cffi.__version__ p = os.path.join(parent, 'doc', 'source', 'index.rst') content = open(p).read() - if ("cffi/cffi-%s.tar.gz" % v) not in content: - py.test.skip("XXX fix the file referenced by the doc!") + assert ("cffi/cffi-%s.tar.gz" % v) in content def test_setup_version(): parent = os.path.dirname(os.path.dirname(__file__)) From noreply at buildbot.pypy.org Sat Mar 30 19:09:19 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sat, 30 Mar 2013 19:09:19 +0100 (CET) Subject: [pypy-commit] pypy default: Check if base directory exists while collecting tests Message-ID: <20130330180919.50ACD1C0183@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62893:bc465cb0b6a7 Date: 2013-03-30 19:08 +0100 http://bitbucket.org/pypy/pypy/changeset/bc465cb0b6a7/ Log: Check if base directory exists while collecting tests diff --git a/testrunner/runner.py b/testrunner/runner.py --- a/testrunner/runner.py +++ b/testrunner/runner.py @@ -315,9 +315,12 @@ def collect_testdirs(self, testdirs, p=None): if p is None: p = self.root - + reldir = self.reltoroot(p) - entries = [p1 for p1 in p.listdir() if p1.check(dotfile=0)] + if p.check(): + entries = [p1 for p1 in p.listdir() if p1.check(dotfile=0)] + else: + entries = [] entries.sort() if p != self.root: From noreply at buildbot.pypy.org Sat Mar 30 19:24:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 30 Mar 2013 19:24:26 +0100 (CET) Subject: [pypy-commit] cffi default: Skip testing for large unsigned values on Windows, where the C compiler Message-ID: <20130330182426.84E601C0014@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1214:758d60d39a87 Date: 2013-03-30 19:24 +0100 http://bitbucket.org/cffi/cffi/changeset/758d60d39a87/ Log: Skip testing for large unsigned values on Windows, where the C compiler silently truncates them to negative values, apparently. diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1469,6 +1469,8 @@ ('-2147483649L', 8, -1), ('%dL-1L' % (1-2**63), 8, -1)] for hidden_value, expected_size, expected_minus1 in cases: + if sys.platform == 'win32' and 'U' in hidden_value: + continue # skipped on Windows ffi = FFI() ffi.cdef("enum foo_e { AA, BB, ... };") lib = ffi.verify("enum foo_e { AA, BB=%s };" % hidden_value) From noreply at buildbot.pypy.org Sat Mar 30 19:48:45 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 30 Mar 2013 19:48:45 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: start extracting low-level type metadata into pypy.module.micronumpy.typespec Message-ID: <20130330184845.0A04F1C0183@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62894:fd8c3f3499aa Date: 2013-03-30 18:48 +0000 http://bitbucket.org/pypy/pypy/changeset/fd8c3f3499aa/ Log: start extracting low-level type metadata into pypy.module.micronumpy.typespec diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -18,9 +18,12 @@ INT_SIZE = rffi.sizeof(lltype.Signed) def make_sort_function(space, itemtype, comp_type, count=1): - TP = itemtype.T + if comp_type == 'complex': + TP = itemtype.FloatType.spec.T + else: + TP = itemtype.spec.T step = rffi.sizeof(TP) - + class Repr(object): def __init__(self, index_stride_size, stride_size, size, values, indexes, index_start, start): @@ -72,9 +75,9 @@ start = 0 dtype = interp_dtype.get_dtype_cache(space).w_longdtype self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) - self.values = alloc_raw_storage(size * stride_size, + self.values = alloc_raw_storage(size * stride_size, track_allocation=False) - Repr.__init__(self, index_stride_size, stride_size, + Repr.__init__(self, index_stride_size, stride_size, size, self.values, self.indexes, start, start) def __del__(self): @@ -96,7 +99,7 @@ for i in range(stop-start): retval.setitem(i, lst.getitem(i+start)) return retval - + if count < 2: def arg_lt(a, b): # Does numpy do <= ? @@ -108,7 +111,7 @@ return True elif a[0][i] > b[0][i]: return False - # Does numpy do True? + # Does numpy do True? return False ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, @@ -180,7 +183,7 @@ class SortCache(object): built = False - + def __init__(self, space): if self.built: return 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 @@ -19,6 +19,10 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder +from pypy.module.micronumpy.typespec import (bool_spec, int8_spec, uint8_spec, + int16_spec, uint16_spec, int32_spec, uint32_spec, long_spec, + ulong_spec, int64_spec, uint64_spec, float32_spec, float64_spec, + float16_spec) degToRad = math.pi / 180.0 log2 = math.log(2) @@ -132,11 +136,11 @@ _mixin_ = True def get_element_size(self): - return rffi.sizeof(self.T) + return rffi.sizeof(self.spec.T) @specialize.argtype(1) def box(self, value): - return self.BoxType(rffi.cast(self.T, value)) + return self.BoxType(rffi.cast(self.spec.T, value)) @specialize.argtype(1, 2) def box_complex(self, real, imag): @@ -170,7 +174,7 @@ raise NotImplementedError def _read(self, storage, i, offset): - return raw_storage_getitem(self.T, storage, i + offset) + return raw_storage_getitem(self.spec.T, storage, i + offset) def read(self, arr, i, offset, dtype=None): return self.box(self._read(arr.storage, i, offset)) @@ -304,7 +308,7 @@ _mixin_ = True def _read(self, storage, i, offset): - res = raw_storage_getitem(self.T, storage, i + offset) + res = raw_storage_getitem(self.spec.T, storage, i + offset) return byteswap(res) def _write(self, storage, i, offset, value): @@ -314,7 +318,7 @@ class Bool(BaseType, Primitive): _attrs_ = () - T = lltype.Bool + spec = bool_spec BoxType = interp_boxes.W_BoolBox format_code = "?" @@ -323,8 +327,8 @@ @specialize.argtype(1) def box(self, value): - box = Primitive.box(self, value) - if box.value: + value = rffi.cast(self.spec.T, value) + if value: return self.True else: return self.False @@ -507,8 +511,8 @@ # XXX good place to warn # XXX can't do the following, func is specialized only on argtype(v) # (which is the same for all int classes) - #if self.T in (rffi.INT, rffi.LONG): - # return most_neg_value_of(self.T) + #if self.spec.T in (rffi.INT, rffi.LONG): + # return most_neg_value_of(self.spec.T) return 0 if abs(v) == 1: return v @@ -523,101 +527,87 @@ class Int8(BaseType, Integer): _attrs_ = () - - T = rffi.SIGNEDCHAR + spec = int8_spec BoxType = interp_boxes.W_Int8Box format_code = "b" NonNativeInt8 = Int8 class UInt8(BaseType, Integer): _attrs_ = () - - T = rffi.UCHAR + spec = uint8_spec BoxType = interp_boxes.W_UInt8Box format_code = "B" NonNativeUInt8 = UInt8 class Int16(BaseType, Integer): _attrs_ = () - - T = rffi.SHORT + spec = int16_spec BoxType = interp_boxes.W_Int16Box format_code = "h" class NonNativeInt16(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.SHORT + spec = int16_spec BoxType = interp_boxes.W_Int16Box format_code = "h" class UInt16(BaseType, Integer): _attrs_ = () - - T = rffi.USHORT + spec = uint16_spec BoxType = interp_boxes.W_UInt16Box format_code = "H" class NonNativeUInt16(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.USHORT + spec = uint16_spec BoxType = interp_boxes.W_UInt16Box format_code = "H" class Int32(BaseType, Integer): _attrs_ = () - - T = rffi.INT + spec = int32_spec BoxType = interp_boxes.W_Int32Box format_code = "i" class NonNativeInt32(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.INT + spec = int32_spec BoxType = interp_boxes.W_Int32Box format_code = "i" class UInt32(BaseType, Integer): _attrs_ = () - - T = rffi.UINT + spec = uint32_spec BoxType = interp_boxes.W_UInt32Box format_code = "I" class NonNativeUInt32(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.UINT + spec = uint32_spec BoxType = interp_boxes.W_UInt32Box format_code = "I" class Long(BaseType, Integer): _attrs_ = () - - T = rffi.LONG + spec = long_spec BoxType = interp_boxes.W_LongBox format_code = "l" class NonNativeLong(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.LONG + spec = long_spec BoxType = interp_boxes.W_LongBox format_code = "l" class ULong(BaseType, Integer): _attrs_ = () - - T = rffi.ULONG + spec = ulong_spec BoxType = interp_boxes.W_ULongBox format_code = "L" class NonNativeULong(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.ULONG + spec = ulong_spec BoxType = interp_boxes.W_ULongBox format_code = "L" @@ -636,8 +626,7 @@ class Int64(BaseType, Integer): _attrs_ = () - - T = rffi.LONGLONG + spec = int64_spec BoxType = interp_boxes.W_Int64Box format_code = "q" @@ -645,8 +634,7 @@ class NonNativeInt64(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.LONGLONG + spec = int64_spec BoxType = interp_boxes.W_Int64Box format_code = "q" @@ -667,8 +655,7 @@ class UInt64(BaseType, Integer): _attrs_ = () - - T = rffi.ULONGLONG + spec = uint64_spec BoxType = interp_boxes.W_UInt64Box format_code = "Q" @@ -676,8 +663,7 @@ class NonNativeUInt64(BaseType, NonNativeInteger): _attrs_ = () - - T = rffi.ULONGLONG + spec = uint64_spec BoxType = interp_boxes.W_UInt64Box format_code = "Q" @@ -990,17 +976,16 @@ _mixin_ = True def _read(self, storage, i, offset): - res = raw_storage_getitem(self.T, storage, i + offset) + res = raw_storage_getitem(self.spec.T, storage, i + offset) return rffi.cast(lltype.Float, byteswap(res)) def _write(self, storage, i, offset, value): - swapped_value = byteswap(rffi.cast(self.T, value)) + swapped_value = byteswap(rffi.cast(self.spec.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) class Float32(BaseType, Float): _attrs_ = () - - T = rffi.FLOAT + spec = float32_spec BoxType = interp_boxes.W_Float32Box format_code = "f" Float32_instance = Float32() @@ -1009,6 +994,7 @@ _attrs_ = () T = rffi.FLOAT + spec = float32_spec BoxType = interp_boxes.W_Float32Box format_code = "f" @@ -1022,16 +1008,14 @@ class Float64(BaseType, Float): _attrs_ = () - - T = rffi.DOUBLE + spec = float64_spec BoxType = interp_boxes.W_Float64Box format_code = "d" Float64_instance = Float64() class NonNativeFloat64(BaseType, NonNativeFloat): _attrs_ = () - - T = rffi.DOUBLE + spec = float64_spec BoxType = interp_boxes.W_Float64Box format_code = "d" @@ -1085,7 +1069,7 @@ return bool(v[0]) or bool(v[1]) def get_element_size(self): - return 2 * rffi.sizeof(self.T) + return 2 * self.FloatType.get_element_size() def byteswap(self, w_v): real, imag = self.unbox(w_v) @@ -1093,9 +1077,7 @@ @specialize.argtype(1) def box(self, value): - return self.BoxType( - rffi.cast(self.T, value), - rffi.cast(self.T, 0.0)) + return self.box_complex(value, 0.) @specialize.argtype(1) def box_component(self, value): @@ -1104,8 +1086,8 @@ @specialize.argtype(1, 2) def box_complex(self, real, imag): return self.BoxType( - rffi.cast(self.T, real), - rffi.cast(self.T, imag)) + rffi.cast(self.FloatType.spec.T, real), + rffi.cast(self.FloatType.spec.T, imag)) def unbox(self, box): assert isinstance(box, self.BoxType) @@ -1117,12 +1099,12 @@ real, imag = self.unbox(box) raw_storage_setitem(arr.storage, i+offset, real) raw_storage_setitem(arr.storage, - i+offset+rffi.sizeof(self.T), imag) + i + offset + self.FloatType.get_element_size(), imag) def _read(self, storage, i, offset): - real = raw_storage_getitem(self.T, storage, i + offset) - imag = raw_storage_getitem(self.T, storage, - i + offset + rffi.sizeof(self.T)) + real = raw_storage_getitem(self.FloatType.spec.T, storage, i + offset) + imag = raw_storage_getitem(self.FloatType.spec.T, storage, + i + offset + self.FloatType.get_element_size()) return real, imag def read(self, arr, i, offset, dtype=None): @@ -1539,8 +1521,6 @@ class Complex64(ComplexFloating, BaseType): _attrs_ = () - - T = rffi.FLOAT BoxType = interp_boxes.W_Complex64Box FloatType = Float32_instance @@ -1548,8 +1528,6 @@ class Complex128(ComplexFloating, BaseType): _attrs_ = () - - T = rffi.DOUBLE BoxType = interp_boxes.W_Complex128Box FloatType = Float64_instance @@ -1558,8 +1536,7 @@ if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size > 8: class Float80(BaseType, Float): _attrs_ = () - - T = rffi.LONGDOUBLE + spec = longdouble_spec BoxType = interp_boxes.W_LongDoubleBox format_code = "q" @@ -1579,8 +1556,6 @@ class Complex160(ComplexFloating, BaseType): _attrs_ = () - - T = rffi.LONGDOUBLE BoxType = interp_boxes.W_CLongDoubleBox FloatType = Float80_instance NonNativeComplex160 = Complex160 @@ -1736,11 +1711,11 @@ return "".join(pieces) for tp in [Int32, Int64]: - if tp.T == lltype.Signed: + if tp.spec.T == lltype.Signed: IntP = tp break for tp in [UInt32, UInt64]: - if tp.T == lltype.Unsigned: + if tp.spec.T == lltype.Unsigned: UIntP = tp break del tp @@ -1752,8 +1727,11 @@ def _setup(): # compute alignment for tp in globals().values(): - if isinstance(tp, type) and hasattr(tp, 'T'): - tp.alignment = clibffi.cast_type_to_ffitype(tp.T).c_alignment + if isinstance(tp, type) and hasattr(tp, 'BoxType'): + if issubclass(tp, ComplexFloating): + tp.alignment = clibffi.cast_type_to_ffitype(tp.FloatType.spec.T).c_alignment + else: + tp.alignment = clibffi.cast_type_to_ffitype(tp.spec.T).c_alignment if issubclass(tp, Float): all_float_types.append((tp, 'float')) if issubclass(tp, Integer): @@ -1768,8 +1746,8 @@ _attrs_ = () _STORAGE_T = rffi.USHORT - T = rffi.SHORT + spec = float16_spec BoxType = interp_boxes.W_Float16Box @specialize.argtype(1) diff --git a/pypy/module/micronumpy/typespec.py b/pypy/module/micronumpy/typespec.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/typespec.py @@ -0,0 +1,28 @@ +""" Meta-data for the low-level types """ + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.objectmodel import specialize + +class TypeSpec(object): + def __init__(self, name, T): + self.name = name + self.T = T + + def _freeze_(self): + return True + +bool_spec = TypeSpec("bool", lltype.Bool) +int8_spec = TypeSpec("int8", rffi.SIGNEDCHAR) +uint8_spec = TypeSpec("uint8", rffi.UCHAR) +int16_spec = TypeSpec("int16", rffi.SHORT) +uint16_spec = TypeSpec("uint16", rffi.USHORT) +int32_spec = TypeSpec("int32", rffi.INT) +uint32_spec = TypeSpec("uint32", rffi.UINT) +long_spec = TypeSpec("long", rffi.LONG) +ulong_spec = TypeSpec("ulong", rffi.ULONG) +int64_spec = TypeSpec("int64", rffi.LONGLONG) +uint64_spec = TypeSpec("uint64", rffi.ULONGLONG) + +float32_spec = TypeSpec("float32", rffi.FLOAT) +float64_spec = TypeSpec("float64", rffi.DOUBLE) +float16_spec = TypeSpec("float16", rffi.SHORT) From noreply at buildbot.pypy.org Sat Mar 30 20:30:48 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 30 Mar 2013 20:30:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: kill the keep_zero cornercase Message-ID: <20130330193048.2B1081C0705@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62895:6b3a588d8647 Date: 2013-03-30 12:28 -0700 http://bitbucket.org/pypy/pypy/changeset/6b3a588d8647/ Log: kill the keep_zero cornercase diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -43,7 +43,7 @@ space.wrap('not all arguments converted ' 'during string formatting')) - def std_wp_int(self, r, prefix='', keep_zero=False): + def std_wp_int(self, r, prefix=''): # use self.prec to add some '0' on the left of the number if self.prec >= 0: if self.prec > 1000: @@ -57,8 +57,6 @@ r = '-' + '0'*padding + r[1:] else: r = '0'*padding + r - elif self.prec == 0 and r == '0' and not keep_zero: - r = '' self.std_wp_number(r, prefix) def fmt_d(self, w_value): @@ -91,7 +89,7 @@ prefix = '0o' else: prefix = '' - self.std_wp_int(r, prefix, keep_zero=True) + self.std_wp_int(r, prefix) fmt_i = fmt_d fmt_u = fmt_d diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py --- a/pypy/objspace/std/test/test_stringformat.py +++ b/pypy/objspace/std/test/test_stringformat.py @@ -182,14 +182,15 @@ assert "%3s" % a == ' a' assert "%-3s"% a == 'a ' - def test_prec_cornercase(self): + def test_prec_zero(self): z = 0 - assert "%.0x" % z == '' - assert "%.x" % z == '' - assert "%.0d" % z == '' - assert "%.i" % z == '' - assert "%.0o" % z == '' - assert "%.o" % z == '' + assert "%.0x" % z == '0' + assert "%.0X" % z == '0' + assert "%.x" % z == '0' + assert "%.0d" % z == '0' + assert "%.i" % z == '0' + assert "%.0o" % z == '0' + assert "%.o" % z == '0' def test_prec_string(self): a = 'a' From noreply at buildbot.pypy.org Sat Mar 30 20:30:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 30 Mar 2013 20:30:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: avoid threading here to prevent a circular import when importing re Message-ID: <20130330193049.90E5B1C242D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62896:2d69edccb7f6 Date: 2013-03-30 12:29 -0700 http://bitbucket.org/pypy/pypy/changeset/2d69edccb7f6/ Log: avoid threading here to prevent a circular import when importing re diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -10,7 +10,7 @@ import operator try: - from threading import _get_ident as _thread_ident + from _thread import _get_ident as _thread_ident except ImportError: def _thread_ident(): return -1 From noreply at buildbot.pypy.org Sat Mar 30 20:30:51 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 30 Mar 2013 20:30:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: move these into baseobjspace to avoid obscure test_ztranslation failures Message-ID: <20130330193051.010F61C0705@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62897:b6cdff153a38 Date: 2013-03-30 12:29 -0700 http://bitbucket.org/pypy/pypy/changeset/b6cdff153a38/ Log: move these into baseobjspace to avoid obscure test_ztranslation failures diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1377,6 +1377,14 @@ """ return w_obj.identifier_w(self) + def fsencode(space, w_obj): + from pypy.interpreter.unicodehelper import PyUnicode_EncodeFSDefault + return PyUnicode_EncodeFSDefault(space, w_obj) + + def fsdecode(space, w_obj): + from pypy.interpreter.unicodehelper import PyUnicode_DecodeFSDefault + return PyUnicode_DecodeFSDefault(space, w_obj) + def fsencode_w(self, w_obj): if self.isinstance_w(w_obj, self.w_unicode): w_obj = self.fsencode(w_obj) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -514,14 +514,6 @@ "'%s' does not support the buffer interface", typename) return space.get_and_call_function(w_impl, w_obj) - def fsencode(space, w_obj): - from pypy.interpreter.unicodehelper import PyUnicode_EncodeFSDefault - return PyUnicode_EncodeFSDefault(space, w_obj) - - def fsdecode(space, w_obj): - from pypy.interpreter.unicodehelper import PyUnicode_DecodeFSDefault - return PyUnicode_DecodeFSDefault(space, w_obj) - # helpers From noreply at buildbot.pypy.org Sat Mar 30 20:30:52 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 30 Mar 2013 20:30:52 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130330193052.580B51C0705@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62898:978d0f19e56e Date: 2013-03-30 12:29 -0700 http://bitbucket.org/pypy/pypy/changeset/978d0f19e56e/ Log: 2to3 diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1172,10 +1172,10 @@ # strategies, to avoid surprizes depending on the strategy. class X: pass for base, arg in [ - (list, []), (list, [5]), (list, ['x']), (list, [X]), (list, [u'x']), - (set, []), (set, [5]), (set, ['x']), (set, [X]), (set, [u'x']), + (list, []), (list, [5]), (list, ['x']), (list, [X]), (list, ['x']), + (set, []), (set, [5]), (set, ['x']), (set, [X]), (set, ['x']), (dict, []), (dict, [(5,6)]), (dict, [('x',7)]), (dict, [(X,8)]), - (dict, [(u'x', 7)]), + (dict, [('x', 7)]), ]: print(base, arg) class SubClass(base): @@ -1258,17 +1258,17 @@ assert len(l1) == 0 def test_use_method_for_wrong_object(self): - raises(TypeError, list.append.im_func, 1, 2) + raises(TypeError, list.append, 1, 2) def test_issue1266(self): - l = range(1) + l = list(range(1)) l.pop() # would previously crash l.append(1) assert l == [1] - l = range(1) + l = list(range(1)) l.pop() # would previously crash l.reverse() @@ -1277,17 +1277,17 @@ def test_issue1266_ovf(self): import sys - l = range(0, sys.maxint, sys.maxint) - l.append(sys.maxint) + l = list(range(0, sys.maxsize, sys.maxsize)) + l.append(sys.maxsize) # -2 would be next in the range sequence if overflow were # allowed l.append(-2) - assert l == [0, sys.maxint, -2] + assert l == [0, sys.maxsize, -2] assert -2 in l - l = range(-sys.maxint, sys.maxint, sys.maxint // 10) + l = list(range(-sys.maxsize, sys.maxsize, sys.maxsize // 10)) item11 = l[11] - assert l[::11] == [-sys.maxint, item11] + assert l[::11] == [-sys.maxsize, item11] assert item11 in l[::11] From noreply at buildbot.pypy.org Sat Mar 30 20:48:45 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 30 Mar 2013 20:48:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix Message-ID: <20130330194845.357611C0014@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r62899:8f4d8d845253 Date: 2013-03-30 12:48 -0700 http://bitbucket.org/pypy/pypy/changeset/8f4d8d845253/ Log: fix diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -885,8 +885,8 @@ bytes_dir = self.bytes_dir if bytes_dir is None: skip("encoding not good enough") - dest = bytes_dir + b"%s/file.txt" - posix.symlink(bytes_dir + b"%s/somefile", dest) + dest = bytes_dir + b"/file.txt" + posix.symlink(bytes_dir + b"/somefile", dest) with open(dest) as f: data = f.read() assert data == "who cares?" From noreply at buildbot.pypy.org Sat Mar 30 22:40:32 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Sat, 30 Mar 2013 22:40:32 +0100 (CET) Subject: [pypy-commit] cffi default: Add missing b prefix to a byte-tring in the big-endian code path Message-ID: <20130330214032.3A42B1C0705@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r1216:7889afdcddc7 Date: 2013-03-30 23:07 +0200 http://bitbucket.org/cffi/cffi/changeset/7889afdcddc7/ Log: Add missing b prefix to a byte-tring in the big-endian code path diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -1094,7 +1094,7 @@ assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00') b[4] = b'\x45' else: - assert content.startswith('\x00\x00\x00\x64\x00\x00\x00\x65') + assert content.startswith(b'\x00\x00\x00\x64\x00\x00\x00\x65') b[7] = b'\x45' assert len(content) == 4 * 10 assert a[1] == 0x45 From noreply at buildbot.pypy.org Sat Mar 30 22:40:30 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Sat, 30 Mar 2013 22:40:30 +0100 (CET) Subject: [pypy-commit] cffi default: Linux isn't the only platform using glibc. Debian gnukfreebsd and hurd ports do too Message-ID: <20130330214030.ED6541C0619@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r1215:4fa8a99e93e8 Date: 2013-03-30 21:38 +0200 http://bitbucket.org/cffi/cffi/changeset/4fa8a99e93e8/ Log: Linux isn't the only platform using glibc. Debian gnukfreebsd and hurd ports do too diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -173,7 +173,7 @@ res = fd.getvalue() if sys.platform == 'win32': NIL = b"00000000" - elif sys.platform.startswith('linux'): + elif sys.platform.startswith(('linux', 'gnu')): NIL = b"(nil)" else: NIL = b"0x0" # OS/X at least From noreply at buildbot.pypy.org Sun Mar 31 01:39:32 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 31 Mar 2013 01:39:32 +0100 (CET) Subject: [pypy-commit] pypy longdouble2: fix translation oddity with .read_bool() Message-ID: <20130331003932.5ABE71C0619@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62900:86a3422134f7 Date: 2013-03-31 00:38 +0000 http://bitbucket.org/pypy/pypy/changeset/86a3422134f7/ Log: fix translation oddity with .read_bool() 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 @@ -682,6 +682,7 @@ rfloat.DTSF_STR_PRECISION) @staticmethod + @specialize.argtype(0) def for_computation(v): return float(v) @@ -992,20 +993,10 @@ class NonNativeFloat32(BaseType, NonNativeFloat): _attrs_ = () - - T = rffi.FLOAT spec = float32_spec BoxType = interp_boxes.W_Float32Box format_code = "f" - def read_bool(self, arr, i, offset): - # it's not clear to me why this is needed - # but a hint might be that calling for_computation(v) - # causes translation to fail, and the assert is necessary - v = self._read(arr.storage, i, offset) - assert isinstance(v, float) - return bool(v) - class Float64(BaseType, Float): _attrs_ = () spec = float64_spec From noreply at buildbot.pypy.org Sun Mar 31 15:29:32 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 31 Mar 2013 15:29:32 +0200 (CEST) Subject: [pypy-commit] pypy default: fix translation instructions Message-ID: <20130331132932.C4B5B1C01A0@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62901:ad0365848ec6 Date: 2013-03-31 16:11 +0300 http://bitbucket.org/pypy/pypy/changeset/ad0365848ec6/ Log: fix translation instructions diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/bin/rpython -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. @@ -153,7 +153,7 @@ :: - pypy /rpython/translator/goal/translate.py -Ojit --platform=arm --gcrootfinder=shadowstack --jit-backend=arm targetpypystandalone.py + pypy /rpython/bin/rpython -Ojit --platform=arm --gcrootfinder=shadowstack --jit-backend=arm targetpypystandalone.py The gcrootfinder option is needed to work around `issue 1377`_ and the jit-backend works around `issue 1376`_ From noreply at buildbot.pypy.org Sun Mar 31 15:29:34 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 31 Mar 2013 15:29:34 +0200 (CEST) Subject: [pypy-commit] pypy default: fix --jit-backend argument Message-ID: <20130331132934.8B5481C01A0@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62902:3293157cf5cc Date: 2013-03-31 16:28 +0300 http://bitbucket.org/pypy/pypy/changeset/3293157cf5cc/ Log: fix --jit-backend argument diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -153,7 +153,7 @@ :: - pypy /rpython/bin/rpython -Ojit --platform=arm --gcrootfinder=shadowstack --jit-backend=arm targetpypystandalone.py + pypy /rpython/bin/rpython -Ojit --platform=arm --gcrootfinder=shadowstack --jit-backend=armv7 targetpypystandalone.py The gcrootfinder option is needed to work around `issue 1377`_ and the jit-backend works around `issue 1376`_ From noreply at buildbot.pypy.org Sun Mar 31 17:06:04 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 31 Mar 2013 17:06:04 +0200 (CEST) Subject: [pypy-commit] pypy default: fix documentation for smallint -> smalllong Message-ID: <20130331150604.1C8671C1465@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r62903:09ce885fa359 Date: 2013-03-31 18:05 +0300 http://bitbucket.org/pypy/pypy/changeset/09ce885fa359/ Log: fix documentation for smallint -> smalllong diff --git a/pypy/doc/config/translation.taggedpointers.txt b/pypy/doc/config/translation.taggedpointers.txt --- a/pypy/doc/config/translation.taggedpointers.txt +++ b/pypy/doc/config/translation.taggedpointers.txt @@ -1,3 +1,3 @@ Enable tagged pointers. This option is mostly useful for the Smalltalk and Prolog interpreters. For the Python interpreter the option -:config:`objspace.std.withsmallint` should be used. +:config:`objspace.std.withsmalllong` should be used. diff --git a/pypy/doc/interpreter-optimizations.rst b/pypy/doc/interpreter-optimizations.rst --- a/pypy/doc/interpreter-optimizations.rst +++ b/pypy/doc/interpreter-optimizations.rst @@ -55,7 +55,7 @@ them from normal pointers. This completely avoids the boxing step, saving time and memory. -You can enable this feature with the :config:`objspace.std.withsmallint` option. +You can enable this feature with the :config:`objspace.std.withsmalllong` option. Dictionary Optimizations ------------------------ From noreply at buildbot.pypy.org Sun Mar 31 18:04:57 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 31 Mar 2013 18:04:57 +0200 (CEST) Subject: [pypy-commit] pypy longdouble2: Factor out other-endian dtype creation Message-ID: <20130331160457.192321C01E1@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62904:e2a5bea67fff Date: 2013-03-31 02:33 +0100 http://bitbucket.org/pypy/pypy/changeset/e2a5bea67fff/ Log: Factor out other-endian dtype creation 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 @@ -66,6 +66,16 @@ self.native = native self.float_type = None + def _nonnative(self, name): + """NOT RPYTHON + Return the non-native version of this dtype + """ + itemtypename = self.itemtype.__class__.__name__ + itemtype = getattr(types, 'NonNative' + itemtypename)() + return W_Dtype(itemtype, self.num, self.kind, name, self.char, + self.BoxType, native=False) + + @specialize.argtype(1) def box(self, value): return self.itemtype.box(value) @@ -636,21 +646,13 @@ self.dtypes_by_name[byteorder_prefix + can_name] = dtype self.dtypes_by_name['=' + can_name] = dtype new_name = nonnative_byteorder_prefix + can_name - itemtypename = dtype.itemtype.__class__.__name__ - itemtype = getattr(types, 'NonNative' + itemtypename)() - self.dtypes_by_name[new_name] = W_Dtype( - itemtype, - dtype.num, dtype.kind, new_name, dtype.char, dtype.BoxType, - native=False) + self.dtypes_by_name[new_name] = dtype._nonnative(new_name) if dtype.kind != dtype.char: can_name = dtype.char self.dtypes_by_name[byteorder_prefix + can_name] = dtype self.dtypes_by_name['=' + can_name] = dtype new_name = nonnative_byteorder_prefix + can_name - self.dtypes_by_name[new_name] = W_Dtype( - itemtype, - dtype.num, dtype.kind, new_name, dtype.char, dtype.BoxType, - native=False) + self.dtypes_by_name[new_name] = dtype._nonnative(new_name) for alias in dtype.aliases: self.dtypes_by_name[alias] = dtype From noreply at buildbot.pypy.org Sun Mar 31 18:04:58 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 31 Mar 2013 18:04:58 +0200 (CEST) Subject: [pypy-commit] pypy longdouble2: get rid of the NonNativeFoo item types (a few translation failures) Message-ID: <20130331160458.76A5B1C01E1@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: longdouble2 Changeset: r62905:bfcadb0b748c Date: 2013-03-31 17:04 +0100 http://bitbucket.org/pypy/pypy/changeset/bfcadb0b748c/ Log: get rid of the NonNativeFoo item types (a few translation failures) 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 @@ -284,8 +284,8 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) - if isinstance (read_val, W_StringBox): + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype.native, dtype) + if isinstance(read_val, W_StringBox): # StringType returns a str return space.wrap(dtype.itemtype.to_str(read_val)) return read_val @@ -298,7 +298,7 @@ raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) dtype.itemtype.store(self.arr, self.ofs, ofs, - dtype.coerce(space, w_value)) + dtype.coerce(space, w_value), dtype.native) def convert_to(self, dtype): # if we reach here, the record fields are guarenteed to match. 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 @@ -70,9 +70,7 @@ """NOT RPYTHON Return the non-native version of this dtype """ - itemtypename = self.itemtype.__class__.__name__ - itemtype = getattr(types, 'NonNative' + itemtypename)() - return W_Dtype(itemtype, self.num, self.kind, name, self.char, + return W_Dtype(self.itemtype, self.num, self.kind, name, self.char, self.BoxType, native=False) @@ -90,16 +88,30 @@ return self.itemtype.coerce(space, self, w_item) def getitem(self, arr, i): - return self.itemtype.read(arr, i, 0) + if self.native: + return self.itemtype.read(arr, i, 0, True) + else: + return self.itemtype.read(arr, i, 0, False) def getitem_bool(self, arr, i): - return self.itemtype.read_bool(arr, i, 0) + if self.native: + return self.itemtype.read_bool(arr, i, 0, True) + else: + return self.itemtype.read_bool(arr, i, 0, False) def setitem(self, arr, i, box): - self.itemtype.store(arr, i, 0, box) + if self.native: + self.itemtype.store(arr, i, 0, box, True) + else: + self.itemtype.store(arr, i, 0, box, False) def fill(self, storage, box, start, stop): - self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + if self.native: + self.itemtype.fill(storage, self.get_size(), box, start, stop, 0, + True) + else: + self.itemtype.fill(storage, self.get_size(), box, start, stop, 0, + False) def get_name(self): if self.char == 'S': 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 @@ -176,22 +176,47 @@ def _read(self, storage, i, offset): return raw_storage_getitem(self.spec.T, storage, i + offset) - def read(self, arr, i, offset, dtype=None): - return self.box(self._read(arr.storage, i, offset)) + def _read_nn(self, storage, i, offset): + res = raw_storage_getitem(self.spec.T, storage, i + offset) + return byteswap(res) - def read_bool(self, arr, i, offset): - return bool(self.for_computation(self._read(arr.storage, i, offset))) + @specialize.arg(4) + def read(self, arr, i, offset, native, dtype=None): + if native: + value = self._read(arr.storage, i, offset) + else: + value = self._read_nn(arr.storage, i, offset) + return self.box(value) + + def read_bool(self, arr, i, offset, native): + if native: + value = self.for_computation(self._read(arr.storage, i, offset)) + else: + value = self.for_computation(self._read_nn(arr.storage, i, offset)) + return bool(value) def _write(self, storage, i, offset, value): raw_storage_setitem(storage, i + offset, value) - def store(self, arr, i, offset, box): - self._write(arr.storage, i, offset, self.unbox(box)) + def _write_nn(self, storage, i, offset, value): + value = byteswap(value) + raw_storage_setitem(storage, i + offset, value) - def fill(self, storage, width, box, start, stop, offset): + @specialize.arg(5) + def store(self, arr, i, offset, box, native): + if native: + self._write(arr.storage, i, offset, self.unbox(box)) + else: + self._write_nn(arr.storage, i, offset, self.unbox(box)) + + @specialize.arg(7) + def fill(self, storage, width, box, start, stop, offset, native): value = self.unbox(box) for i in xrange(start, stop, width): - self._write(storage, i, offset, value) + if native: + self._write(storage, i, offset, value) + else: + self._write_nn(storage, i, offset, value) def runpack_str(self, s): v = runpack(self.format_code, s) @@ -307,13 +332,6 @@ class NonNativePrimitive(Primitive): _mixin_ = True - def _read(self, storage, i, offset): - res = raw_storage_getitem(self.spec.T, storage, i + offset) - return byteswap(res) - - def _write(self, storage, i, offset, value): - value = byteswap(value) - raw_storage_setitem(storage, i + offset, value) class Bool(BaseType, Primitive): _attrs_ = () @@ -973,14 +991,11 @@ else: return v1 + v2 -class NonNativeFloat(NonNativePrimitive, Float): - _mixin_ = True - - def _read(self, storage, i, offset): + def _read_nn(self, storage, i, offset): res = raw_storage_getitem(self.spec.T, storage, i + offset) return rffi.cast(lltype.Float, byteswap(res)) - def _write(self, storage, i, offset, value): + def _write_nn(self, storage, i, offset, value): swapped_value = byteswap(rffi.cast(self.spec.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) @@ -991,12 +1006,6 @@ format_code = "f" Float32_instance = Float32() -class NonNativeFloat32(BaseType, NonNativeFloat): - _attrs_ = () - spec = float32_spec - BoxType = interp_boxes.W_Float32Box - format_code = "f" - class Float64(BaseType, Float): _attrs_ = () spec = float64_spec @@ -1004,11 +1013,6 @@ format_code = "d" Float64_instance = Float64() -class NonNativeFloat64(BaseType, NonNativeFloat): - _attrs_ = () - spec = float64_spec - BoxType = interp_boxes.W_Float64Box - format_code = "d" class ComplexFloating(object): _mixin_ = True @@ -1055,7 +1059,7 @@ real,imag = self.for_computation(self.unbox(box)) return space.newcomplex(real, imag) - def read_bool(self, arr, i, offset): + def read_bool(self, arr, i, offset, native): v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) @@ -1086,7 +1090,7 @@ real, imag = box.real, box.imag return real, imag - def store(self, arr, i, offset, box): + def store(self, arr, i, offset, box, native): real, imag = self.unbox(box) raw_storage_setitem(arr.storage, i+offset, real) raw_storage_setitem(arr.storage, @@ -1098,7 +1102,7 @@ i + offset + self.FloatType.get_element_size()) return real, imag - def read(self, arr, i, offset, dtype=None): + def read(self, arr, i, offset, native, dtype=None): real, imag = self._read(arr.storage, i, offset) return self.box_complex(real, imag) @@ -1583,12 +1587,12 @@ return interp_boxes.W_StringBox(arr, 0, arr.dtype) @jit.unroll_safe - def store(self, arr, i, offset, box): + def store(self, arr, i, offset, box, native): assert isinstance(box, interp_boxes.W_StringBox) for k in range(min(self.size, box.arr.size-offset)): arr.storage[k + i] = box.arr.storage[k + offset] - def read(self, arr, i, offset, dtype=None): + def read(self, arr, i, offset, native, dtype=None): if dtype is None: dtype = arr.dtype return interp_boxes.W_StringBox(arr, i + offset, dtype) @@ -1654,7 +1658,7 @@ def get_element_size(self): return self.size - def read(self, arr, i, offset, dtype=None): + def read(self, arr, i, offset, native, dtype=None): if dtype is None: dtype = arr.dtype return interp_boxes.W_VoidBox(arr, i + offset, dtype) @@ -1678,11 +1682,11 @@ ofs, itemtype = self.offsets_and_fields[i] w_item = items_w[i] w_box = itemtype.coerce(space, subdtype, w_item) - itemtype.store(arr, 0, ofs, w_box) + itemtype.store(arr, 0, ofs, w_box, subdtype.native) return interp_boxes.W_VoidBox(arr, 0, dtype) @jit.unroll_safe - def store(self, arr, i, ofs, box): + def store(self, arr, i, ofs, box, native): assert isinstance(box, interp_boxes.W_VoidBox) for k in range(self.get_element_size()): arr.storage[k + i] = box.arr.storage[k + box.ofs] @@ -1697,7 +1701,12 @@ first = False else: pieces.append(", ") - pieces.append(tp.str_format(tp.read(box.arr, box.ofs, ofs))) + dtype = box.arr.dtype + if dtype.native: + p_box = tp.read(box.arr, box.ofs, ofs, True) + else: + p_box = tp.read(box.arr, box.ofs, ofs, False) + pieces.append(tp.str_format(p_box)) pieces.append(")") return "".join(pieces) @@ -1732,10 +1741,7 @@ _setup() del _setup -class BaseFloat16(Float): - _mixin_ = True - - _attrs_ = () +class Float16(BaseType, Float): _STORAGE_T = rffi.USHORT spec = float16_spec @@ -1759,7 +1765,6 @@ swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) return self.box(float_unpack(r_ulonglong(swapped), 2)) -class Float16(BaseType, BaseFloat16): def _read(self, storage, i, offset): hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) return float_unpack(r_ulonglong(hbits), 2) @@ -1769,12 +1774,11 @@ raw_storage_setitem(storage, i + offset, rffi.cast(self._STORAGE_T, hbits)) -class NonNativeFloat16(BaseType, BaseFloat16): - def _read(self, storage, i, offset): + def _read_nn(self, storage, i, offset): hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) return float_unpack(r_ulonglong(byteswap(hbits)), 2) - def _write(self, storage, i, offset, value): + def _write_nn(self, storage, i, offset, value): hbits = float_pack(value,2) raw_storage_setitem(storage, i + offset, byteswap(rffi.cast(self._STORAGE_T, hbits))) From noreply at buildbot.pypy.org Sun Mar 31 19:15:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 31 Mar 2013 19:15:49 +0200 (CEST) Subject: [pypy-commit] cffi default: merge heads Message-ID: <20130331171549.544A91C1465@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1218:c15983a2607b Date: 2013-03-31 19:15 +0200 http://bitbucket.org/cffi/cffi/changeset/c15983a2607b/ Log: merge heads diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -1094,7 +1094,7 @@ assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00') b[4] = b'\x45' else: - assert content.startswith('\x00\x00\x00\x64\x00\x00\x00\x65') + assert content.startswith(b'\x00\x00\x00\x64\x00\x00\x00\x65') b[7] = b'\x45' assert len(content) == 4 * 10 assert a[1] == 0x45 diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -173,7 +173,7 @@ res = fd.getvalue() if sys.platform == 'win32': NIL = b"00000000" - elif sys.platform.startswith('linux'): + elif sys.platform.startswith(('linux', 'gnu')): NIL = b"(nil)" else: NIL = b"0x0" # OS/X at least From noreply at buildbot.pypy.org Sun Mar 31 19:15:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 31 Mar 2013 19:15:48 +0200 (CEST) Subject: [pypy-commit] cffi default: Merge d0f6755466f7 into default: Message-ID: <20130331171548.1E1291C1008@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1217:27c82dcc020c Date: 2013-03-31 19:10 +0200 http://bitbucket.org/cffi/cffi/changeset/27c82dcc020c/ Log: Merge d0f6755466f7 into default: Cancel again these changes: we can't pass 0 or None to mean NULL. Just use NULL explicitly. (After discussion on IRC, notably with Amaury -- thanks) Removed some unrelated doc changes that describe something that was planned but never implemented. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1120,11 +1120,6 @@ CTypeDescrObject *ctinit; if (!CData_Check(init)) { - if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) { - /* convert 0 to NULL */ - *(char **)data = NULL; - return 0; - } expected = "cdata pointer"; goto cannot_convert; } @@ -1609,15 +1604,7 @@ char *v_cdata, *w_cdata; assert(CData_Check(v)); - v_cdata = ((CDataObject *)v)->c_data; - if (!CData_Check(w)) { - if (PyIntOrLong_Check(w) && !PyObject_IsTrue(w) && - !(((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY)) { - /* comparing a non-primitive with 0 */ - w_cdata = NULL; - goto compare; - } pyres = Py_NotImplemented; goto done; } @@ -1627,8 +1614,9 @@ (((CDataObject *)w)->c_type->ct_flags & CT_PRIMITIVE_ANY))) goto Error; + v_cdata = ((CDataObject *)v)->c_data; w_cdata = ((CDataObject *)w)->c_data; - compare: + switch (op) { case Py_EQ: res = (v_cdata == w_cdata); break; case Py_NE: res = (v_cdata != w_cdata); break; @@ -2078,16 +2066,7 @@ ctitem = ctptr->ct_itemdescr; /* XXX some code duplication, how to avoid it? */ - if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) { - /* Convert 0 to NULL. Note that passing 0 is not ambigous, - despite the potential confusion: as a 'T*' argument, 0 means - NULL, but as a 'T[]' argument it would mean "array of size 0" - --- except that we specifically refuse to interpret numbers - as the array size when passing arguments. */ - *output_data = NULL; - return 0; - } - else if (PyBytes_Check(init)) { + if (PyBytes_Check(init)) { /* from a string: just returning the string here is fine. We assume that the C code won't modify the 'char *' data. */ if ((ctptr->ct_flags & CT_CAST_ANYTHING) || diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -398,19 +398,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -790,7 +779,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -803,14 +792,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1028,11 +1014,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1192,8 +1192,9 @@ (It would be difficult because only structs and unions are internally stored as an indirect pointer to the data.) If ``field`` is given, returns the address of that field in the structure. The returned -pointer is only valid as long as the original object is. *New in -version 0.4.* +pointer is only valid as long as the original ``cdata`` object is; be +sure to keep it alive if it was obtained directly from ``ffi.new()``. +*New in version 0.4.* .. "versionadded:: 0.4" --- inlined in the previous paragraph @@ -1314,12 +1315,11 @@ | | a compatible type (i.e.| |``+``, ``-``, | | | same type or ``char*`` | |bool() | | | or ``void*``, or as an | | | -| | array instead) `(*)`; | | | -| | or ``0`` `(******)` | | | +| | array instead) `(*)` | | | +---------------+------------------------+ | | | ``void *``, | another with | | | | ``char *`` | any pointer or array | | | -| | type; or ``0`` | | | +| | type | | | +---------------+------------------------+ +----------------+ | pointers to | same as pointers | | ``[]``, ``+``, | | structure or | | | ``-``, bool(), | @@ -1399,11 +1399,6 @@ If you really want to get their value as a string, use ``ffi.string(ffi.cast("the_enum_type", x.field))``. -.. versionadded:: 0.6 - `(******)` ``0`` is interpreted like ``ffi.NULL`` in most places. - It is the way both gcc and MSVC work. (Of course non-null integers - are not transparently interpreted as pointers; only ``0`` is.) - Reference: verifier ------------------- diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1569,7 +1569,7 @@ p = ffi.new("char[]", b'\x10\x20\x30') assert lib.sum3chars(p) == b'\x60' -def test_passing_0_for_NULL(): +def test_passing_string_or_NULL(): ffi = FFI() ffi.cdef("int seeme1(char *); int seeme2(int *);") lib = ffi.verify(""" @@ -1581,15 +1581,16 @@ } """) assert lib.seeme1(b"foo") == 0 - assert lib.seeme1(0) == 1 - assert lib.seeme1(long(0)) == 1 + assert lib.seeme1(ffi.NULL) == 1 assert lib.seeme2([42, 43]) == 0 - assert lib.seeme2(0) == 1 - assert lib.seeme2(long(0)) == 1 + assert lib.seeme2(ffi.NULL) == 1 py.test.raises(TypeError, lib.seeme1, None) py.test.raises(TypeError, lib.seeme2, None) py.test.raises(TypeError, lib.seeme1, 0.0) py.test.raises(TypeError, lib.seeme2, 0.0) + py.test.raises(TypeError, lib.seeme1, 0) + py.test.raises(TypeError, lib.seeme2, 0) + py.test.raises(TypeError, lib.seeme2, 0L) def test_typeof_function(): ffi = FFI() From noreply at buildbot.pypy.org Sun Mar 31 19:17:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 31 Mar 2013 19:17:40 +0200 (CEST) Subject: [pypy-commit] pypy default: Update to cffi/27c82dcc020c. Message-ID: <20130331171740.9A0D01C1008@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r62906:38851cb8e021 Date: 2013-03-31 19:17 +0200 http://bitbucket.org/pypy/pypy/changeset/38851cb8e021/ Log: Update to cffi/27c82dcc020c. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -91,20 +91,15 @@ space = self.space cdata1 = self._cdata if isinstance(w_other, W_CData): - if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(w_other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a " - "primitive cdata")) cdata2 = w_other._cdata - elif (misc.is_zero(space, w_other) and - not isinstance(self.ctype, W_CTypePrimitive)): - cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(w_other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -152,10 +152,6 @@ def convert_from_object(self, cdata, w_ob): space = self.space if not isinstance(w_ob, cdataobj.W_CData): - if misc.is_zero(space, w_ob): - NULL = lltype.nullptr(rffi.CCHARP.TO) - rffi.cast(rffi.CCHARPP, cdata)[0] = NULL - return raise self._convert_error("cdata pointer", w_ob) other = w_ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -257,15 +253,7 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if misc.is_zero(space, w_init): - # Convert 0 to NULL. Note that passing 0 is not ambigous, - # despite the potential confusion: as a 'T*' argument, 0 means - # NULL, but as a 'T[]' argument it would mean "array of size 0" - # --- except that we specifically refuse to interpret numbers - # as the array size when passing arguments. - rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) - return 3 - elif (space.isinstance_w(w_init, space.w_list) or + if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -202,11 +202,6 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" -def is_zero(space, w_ob): - return ((space.isinstance_w(w_ob, space.w_int) or - space.isinstance_w(w_ob, space.w_long)) - and not space.is_true(w_ob)) - # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,19 +387,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -779,7 +768,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -792,14 +781,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1017,11 +1003,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): From noreply at buildbot.pypy.org Sun Mar 31 20:01:59 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 31 Mar 2013 20:01:59 +0200 (CEST) Subject: [pypy-commit] pypy default: fix import Message-ID: <20130331180159.49C811C01E1@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62907:42e88ee86a00 Date: 2013-03-31 20:00 +0200 http://bitbucket.org/pypy/pypy/changeset/42e88ee86a00/ Log: fix import diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -267,7 +267,7 @@ AbstractARMv7Builder.__init__(self) def gen_load_int(self, r, value, cond=cond.AL): - from pypy.jit.backend.arm.conditions import AL + from rpython.jit.backend.arm.conditions import AL if cond != AL or 0 <= value <= 0xFFFF: self._load_by_shifting(r, value, cond) else: From noreply at buildbot.pypy.org Sun Mar 31 20:02:00 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 31 Mar 2013 20:02:00 +0200 (CEST) Subject: [pypy-commit] pypy default: some work on fixing translation on arm Message-ID: <20130331180200.908131C01E1@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62908:d5fba32b813a Date: 2013-03-31 20:01 +0200 http://bitbucket.org/pypy/pypy/changeset/d5fba32b813a/ Log: some work on fixing translation on arm diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -299,19 +299,10 @@ is_guard_not_invalidated=True) def emit_op_jump(self, op, arglocs, regalloc, fcond): - # The backend's logic assumes that the target code is in a piece of - # assembler that was also called with the same number of arguments, - # so that the locations [ebp+8..] of the input arguments are valid - # stack locations both before and after the jump. - # target_token = op.getdescr() + assert isinstance(target_token, TargetToken) target = target_token._ll_loop_code - assert isinstance(target_token, TargetToken) assert fcond == c.AL - my_nbargs = self.current_clt._debug_nbargs - target_nbargs = target_token._arm_clt._debug_nbargs - assert my_nbargs == target_nbargs - if target_token in self.target_tokens_currently_compiling: self.mc.B_offs(target, fcond) else: @@ -576,10 +567,12 @@ def emit_op_cond_call_gc_wb(self, op, arglocs, regalloc, fcond): self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, fcond) + return fcond def emit_op_cond_call_gc_wb_array(self, op, arglocs, regalloc, fcond): self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, fcond, array=True) + return fcond def _write_barrier_fastpath(self, mc, descr, arglocs, fcond=c.AL, array=False, is_frame=False): diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -752,6 +752,7 @@ # self.frame_manager.hint_frame_locations[box] = loc def prepare_op_jump(self, op, fcond): + assert self.jump_target_descr is None descr = op.getdescr() assert isinstance(descr, TargetToken) self.jump_target_descr = descr From noreply at buildbot.pypy.org Sun Mar 31 20:02:01 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 31 Mar 2013 20:02:01 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130331180201.CB0F61C01E1@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r62909:e3ebae528d55 Date: 2013-03-31 20:01 +0200 http://bitbucket.org/pypy/pypy/changeset/e3ebae528d55/ Log: merge heads diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -91,20 +91,15 @@ space = self.space cdata1 = self._cdata if isinstance(w_other, W_CData): - if requires_ordering: - if (isinstance(self.ctype, W_CTypePrimitive) or - isinstance(w_other.ctype, W_CTypePrimitive)): - raise OperationError(space.w_TypeError, - space.wrap("cannot do comparison on a " - "primitive cdata")) cdata2 = w_other._cdata - elif (misc.is_zero(space, w_other) and - not isinstance(self.ctype, W_CTypePrimitive)): - cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: + if (isinstance(self.ctype, W_CTypePrimitive) or + isinstance(w_other.ctype, W_CTypePrimitive)): + raise OperationError(space.w_TypeError, + space.wrap("cannot do comparison on a primitive cdata")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -152,10 +152,6 @@ def convert_from_object(self, cdata, w_ob): space = self.space if not isinstance(w_ob, cdataobj.W_CData): - if misc.is_zero(space, w_ob): - NULL = lltype.nullptr(rffi.CCHARP.TO) - rffi.cast(rffi.CCHARPP, cdata)[0] = NULL - return raise self._convert_error("cdata pointer", w_ob) other = w_ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -257,15 +253,7 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if misc.is_zero(space, w_init): - # Convert 0 to NULL. Note that passing 0 is not ambigous, - # despite the potential confusion: as a 'T*' argument, 0 means - # NULL, but as a 'T[]' argument it would mean "array of size 0" - # --- except that we specifically refuse to interpret numbers - # as the array size when passing arguments. - rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) - return 3 - elif (space.isinstance_w(w_init, space.w_list) or + if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -202,11 +202,6 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" -def is_zero(space, w_ob): - return ((space.isinstance_w(w_ob, space.w_int) or - space.isinstance_w(w_ob, space.w_long)) - and not space.is_true(w_ob)) - # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,19 +387,8 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - -def test_cmp_pointer_with_0(): - p = new_pointer_type(new_primitive_type("int")) - x = cast(p, 0) - assert (x == 0) is True - assert (x != 0) is False - assert (0 == x) is True - assert (0 != x) is False - y = cast(p, 42) - assert (y == 0) is False - assert (y != 0) is True - assert (0 == y) is False - assert (0 != y) is True + y = cast(p, 0) + assert (y == None) is False def test_invalid_indexing(): p = new_primitive_type("int") @@ -779,7 +768,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 == 0 + assert s.p4 != 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -792,14 +781,11 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - s.p4 = 0 - assert s.p4 == 0 + assert s.p4 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) - assert s.p4 == 0 - # - s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) + assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1017,11 +1003,10 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(0) # NULL - assert res == -42 - res = f(long(0)) # NULL + res = f(cast(BVoidP, 0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis():